|
@@ -1,7 +1,7 @@
|
|
|
import { defineComponent, ref } from 'vue'
|
|
|
import * as RTC from '@rongcloud/plugin-rtc'
|
|
|
import Header from './header'
|
|
|
-import ActionBar, { state as ActionBarRuntime} from './action-bar'
|
|
|
+import ActionBar, { state as ActionBarRuntime } from './action-bar'
|
|
|
import VideoStatus from './video-status'
|
|
|
import { state } from '/src/state'
|
|
|
import event, { LIVE_EVENT_MESSAGE } from './event'
|
|
@@ -10,6 +10,7 @@ import Chronography from './chronography'
|
|
|
import runtimeModel, * as RuntimeModelUtils from '/src/components/live-message/model/runtime'
|
|
|
import { requireMedia } from './helpers'
|
|
|
import styles from './index.module.less'
|
|
|
+import request from '/src/helpers/request'
|
|
|
|
|
|
const videoRef = ref<HTMLVideoElement | null>(null)
|
|
|
|
|
@@ -20,21 +21,22 @@ export default defineComponent({
|
|
|
name: 'LiveBroadcast',
|
|
|
data() {
|
|
|
return {
|
|
|
- headerStatus: false
|
|
|
+ headerStatus: false,
|
|
|
+ initAudioUsers: [],
|
|
|
}
|
|
|
},
|
|
|
computed: {
|
|
|
isLive() {
|
|
|
console.log(runtime.videoStatus)
|
|
|
- if(runtime.videoStatus === 'liveing') {
|
|
|
+ if (runtime.videoStatus === 'liveing') {
|
|
|
setTimeout(() => {
|
|
|
this.headerStatus = true
|
|
|
- }, 3000);
|
|
|
+ }, 3000)
|
|
|
} else {
|
|
|
this.headerStatus = false
|
|
|
}
|
|
|
return runtime.videoStatus === 'liveing'
|
|
|
- }
|
|
|
+ },
|
|
|
},
|
|
|
async mounted() {
|
|
|
this.initializeRoom()
|
|
@@ -75,24 +77,51 @@ export default defineComponent({
|
|
|
const audioDeviceId2 = localStorage.getItem(RuntimeUtils.AUDIO_DEVICE_ID2)
|
|
|
if (type === 'camera') {
|
|
|
if (videoDeviceId) {
|
|
|
- return runtime.cameras.find(camera => camera.deviceId === videoDeviceId) || runtime.cameras[0]
|
|
|
+ return (
|
|
|
+ runtime.cameras.find(
|
|
|
+ (camera) => camera.deviceId === videoDeviceId
|
|
|
+ ) || runtime.cameras[0]
|
|
|
+ )
|
|
|
}
|
|
|
return runtime.cameras[0]
|
|
|
}
|
|
|
if (audioDeviceId) {
|
|
|
- return runtime.microphones.find(microphone => microphone.deviceId === audioDeviceId) || runtime.microphones[0]
|
|
|
+ return (
|
|
|
+ runtime.microphones.find(
|
|
|
+ (microphone) => microphone.deviceId === audioDeviceId
|
|
|
+ ) || runtime.microphones[0]
|
|
|
+ )
|
|
|
}
|
|
|
if (audioDeviceId2) {
|
|
|
- return runtime.microphones.find(microphone => microphone.deviceId === audioDeviceId2) || runtime.microphones[0]
|
|
|
+ return (
|
|
|
+ runtime.microphones.find(
|
|
|
+ (microphone) => microphone.deviceId === audioDeviceId2
|
|
|
+ ) || runtime.microphones[0]
|
|
|
+ )
|
|
|
}
|
|
|
return runtime.microphones[0]
|
|
|
},
|
|
|
- async initializeRoom () {
|
|
|
+ async FetchUserDetails(userIds: string[]) {
|
|
|
+ try {
|
|
|
+ const res = await request.post(
|
|
|
+ '/api-web/imLiveBroadcastRoom/queryBaseUserInfo',
|
|
|
+ {
|
|
|
+ requestType: 'json',
|
|
|
+ data: userIds,
|
|
|
+ }
|
|
|
+ )
|
|
|
+ return res.data
|
|
|
+ } catch (error) {}
|
|
|
+ return []
|
|
|
+ },
|
|
|
+ async initializeRoom() {
|
|
|
if (!state.user) throw Error('请先登录')
|
|
|
+ let initAudioUsers: any[] = []
|
|
|
try {
|
|
|
runtime.likeCount = state.user?.likeNum || 0
|
|
|
runtime.lookCount = state.user?.lookNum || 0
|
|
|
- const isLiveing = sessionStorage.getItem(RuntimeUtils.START_LIVE_STATUS) === 'liveing'
|
|
|
+ const isLiveing =
|
|
|
+ sessionStorage.getItem(RuntimeUtils.START_LIVE_STATUS) === 'liveing'
|
|
|
// IM连接
|
|
|
await RuntimeUtils.connectIM(state.user?.imToken)
|
|
|
runtime.videoRef = videoRef.value
|
|
@@ -101,7 +130,9 @@ export default defineComponent({
|
|
|
await RuntimeUtils.getCameras()
|
|
|
// 设置播放设备
|
|
|
RuntimeUtils.setSelectCamera(this.getDeviceByDeviceType('camera'))
|
|
|
- RuntimeUtils.setSelectMicrophone(this.getDeviceByDeviceType('microphone'))
|
|
|
+ RuntimeUtils.setSelectMicrophone(
|
|
|
+ this.getDeviceByDeviceType('microphone')
|
|
|
+ )
|
|
|
// RuntimeUtils.setSelectMicrophone2(this.getDeviceByDeviceType('microphone2'))
|
|
|
cameraVideoTrack = await RuntimeUtils.getTrack('camera')
|
|
|
runtime.videoRef && cameraVideoTrack.play(runtime.videoRef)
|
|
@@ -112,51 +143,73 @@ export default defineComponent({
|
|
|
// console.log(microphoneAudioTrack)
|
|
|
// console.log(runtime.deviceStatus)
|
|
|
runtime.videoStatus = 'stream'
|
|
|
- const join = await RuntimeUtils.joinRoom(state.user?.roomUid, RTC.RCLivingType.VIDEO, {
|
|
|
- onMessageReceive(name, content) {
|
|
|
- console.log(name, content)
|
|
|
- },
|
|
|
- onKickOff(byServer: boolean) {
|
|
|
- console.log(byServer)
|
|
|
- },
|
|
|
- async onTrackPublish (tracks: RTC.RCRemoteTrack[]) {
|
|
|
- const subscribeRes = await join?.room?.subscribe(tracks)
|
|
|
- console.log(subscribeRes)
|
|
|
- if (subscribeRes?.code && subscribeRes.code !== RTC.RCRTCCode.SUCCESS) {
|
|
|
- console.log('资源订阅失败 ->', subscribeRes.code)
|
|
|
- }
|
|
|
- },
|
|
|
- onTrackUnpublish(tracks: RTC.RCRemoteTrack[]) {
|
|
|
- console.log(tracks)
|
|
|
- event.emit(LIVE_EVENT_MESSAGE['RM:RTC:TrackUnpublish'], tracks)
|
|
|
- },
|
|
|
- onSwitchRole(userId: string, role: RTC.RCRTCLiveRole) {
|
|
|
- event.emit(LIVE_EVENT_MESSAGE['RM:RTC:SwitchRole'], {
|
|
|
- userId,
|
|
|
- role,
|
|
|
- })
|
|
|
- },
|
|
|
- onTrackReady (track: RTC.RCRemoteTrack) {
|
|
|
- if (track.isAudioTrack()) {
|
|
|
- // 音轨不需要传递播放控件
|
|
|
- track.play()
|
|
|
- const trackUser = runtimeModel.lookList[track.getUserId()]
|
|
|
- runtimeModel.joinList[track.getUserId()] = {
|
|
|
- ...trackUser,
|
|
|
- userRoomType: 4,
|
|
|
+ const join = await RuntimeUtils.joinRoom(
|
|
|
+ state.user?.roomUid,
|
|
|
+ RTC.RCLivingType.VIDEO,
|
|
|
+ {
|
|
|
+ onMessageReceive(name, content) {
|
|
|
+ console.log(name, content)
|
|
|
+ },
|
|
|
+ onKickOff(byServer: boolean) {
|
|
|
+ console.log(byServer)
|
|
|
+ },
|
|
|
+ async onTrackPublish(tracks: RTC.RCRemoteTrack[]) {
|
|
|
+ const subscribeRes = await join?.room?.subscribe(tracks)
|
|
|
+ console.log(subscribeRes)
|
|
|
+ if (
|
|
|
+ subscribeRes?.code &&
|
|
|
+ subscribeRes.code !== RTC.RCRTCCode.SUCCESS
|
|
|
+ ) {
|
|
|
+ console.log('资源订阅失败 ->', subscribeRes.code)
|
|
|
}
|
|
|
- }
|
|
|
- },
|
|
|
- onUserJoin (userIds: string[]) {
|
|
|
- console.log('onUserJoin', userIds)
|
|
|
- },
|
|
|
- onUserLeave (userIds: string[]) {
|
|
|
- event.emit(LIVE_EVENT_MESSAGE['RM:RTC:UserLeave'], userIds)
|
|
|
- console.log('onUserLeave', userIds)
|
|
|
- },
|
|
|
- })
|
|
|
+ },
|
|
|
+ onTrackUnpublish(tracks: RTC.RCRemoteTrack[]) {
|
|
|
+ console.log(tracks)
|
|
|
+ event.emit(LIVE_EVENT_MESSAGE['RM:RTC:TrackUnpublish'], tracks)
|
|
|
+ },
|
|
|
+ onSwitchRole(userId: string, role: RTC.RCRTCLiveRole) {
|
|
|
+ event.emit(LIVE_EVENT_MESSAGE['RM:RTC:SwitchRole'], {
|
|
|
+ userId,
|
|
|
+ role,
|
|
|
+ })
|
|
|
+ },
|
|
|
+ onTrackReady(track: RTC.RCRemoteTrack) {
|
|
|
+ if (track.isAudioTrack()) {
|
|
|
+ // 音轨不需要传递播放控件
|
|
|
+ track.play()
|
|
|
+ const userId = track.getUserId()
|
|
|
+ const trackUser = initAudioUsers.find(
|
|
|
+ (user: any) => user.userId == Number(userId)
|
|
|
+ )
|
|
|
+ // console.log(trackUser, initAudioUsers, userId)
|
|
|
+ if (trackUser) {
|
|
|
+ runtimeModel.joinList[userId] = {
|
|
|
+ ...trackUser,
|
|
|
+ id: userId,
|
|
|
+ name: trackUser.userName,
|
|
|
+ userRoomType: 4,
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ },
|
|
|
+ onUserJoin(userIds: string[]) {
|
|
|
+ console.log('onUserJoin', userIds)
|
|
|
+ },
|
|
|
+ onUserLeave(userIds: string[]) {
|
|
|
+ event.emit(LIVE_EVENT_MESSAGE['RM:RTC:UserLeave'], userIds)
|
|
|
+ console.log('onUserLeave', userIds)
|
|
|
+ },
|
|
|
+ }
|
|
|
+ )
|
|
|
// RuntimeUtils.sendMessage({}, 'Welcome')
|
|
|
- const remoteTracks: RTC.RCRemoteTrack[] | undefined = join?.room?.getRemoteTracks()
|
|
|
+ const userIds: string[] | undefined = join?.room?.getRemoteUserIds()
|
|
|
+ // console.log('userIds', userIds)
|
|
|
+ if (userIds && userIds.length) {
|
|
|
+ const list = await this.FetchUserDetails(userIds)
|
|
|
+ initAudioUsers.push(...list)
|
|
|
+ }
|
|
|
+ const remoteTracks: RTC.RCRemoteTrack[] | undefined =
|
|
|
+ join?.room?.getRemoteTracks()
|
|
|
if (remoteTracks) {
|
|
|
await join?.room?.subscribe(remoteTracks)
|
|
|
}
|
|
@@ -166,7 +219,7 @@ export default defineComponent({
|
|
|
onStateReport(report) {
|
|
|
event.emit('onStateReport', report)
|
|
|
// console.log('onStateReport', report)
|
|
|
- }
|
|
|
+ },
|
|
|
})
|
|
|
}
|
|
|
if (isLiveing) {
|
|
@@ -174,9 +227,13 @@ export default defineComponent({
|
|
|
runtime.videoStatus = 'liveing'
|
|
|
} else {
|
|
|
await RuntimeUtils.setTrack([cameraVideoTrack], 'camera', false)
|
|
|
- await RuntimeUtils.setTrack([microphoneAudioTrack], 'microphone', false)
|
|
|
+ await RuntimeUtils.setTrack(
|
|
|
+ [microphoneAudioTrack],
|
|
|
+ 'microphone',
|
|
|
+ false
|
|
|
+ )
|
|
|
}
|
|
|
- const volume =localStorage.getItem(RuntimeUtils.AUDIO_DEVICE_VOLUME)
|
|
|
+ const volume = localStorage.getItem(RuntimeUtils.AUDIO_DEVICE_VOLUME)
|
|
|
if (volume) {
|
|
|
ActionBarRuntime.volume = parseInt(volume)
|
|
|
RuntimeUtils.setVolume(parseInt(volume))
|
|
@@ -189,23 +246,28 @@ export default defineComponent({
|
|
|
closeLive() {
|
|
|
// removeMedia(runtime.mediaStreams, runtime.mediaStreamTrack)
|
|
|
runtime.videoStatus = 'stream'
|
|
|
- }
|
|
|
+ },
|
|
|
},
|
|
|
render() {
|
|
|
return (
|
|
|
<div class={styles.main}>
|
|
|
{this.isLive ? null : null}
|
|
|
<div class={[styles.headerSection]}>
|
|
|
- <Header class={[styles.headerContent, this.headerStatus ? styles["header-top"] : null]} />
|
|
|
+ <Header
|
|
|
+ class={[
|
|
|
+ styles.headerContent,
|
|
|
+ this.headerStatus ? styles['header-top'] : null,
|
|
|
+ ]}
|
|
|
+ />
|
|
|
</div>
|
|
|
<div class={styles.video}>
|
|
|
<video ref={videoRef}></video>
|
|
|
- {!runtime.screenShareStatus ? <VideoStatus/> : null}
|
|
|
- {runtime.videoStatus === 'liveing' ? <Chronography/> : null}
|
|
|
+ {!runtime.screenShareStatus ? <VideoStatus /> : null}
|
|
|
+ {runtime.videoStatus === 'liveing' ? <Chronography /> : null}
|
|
|
</div>
|
|
|
- <ActionBar/>
|
|
|
+ <ActionBar />
|
|
|
{/* <div>video: {runtime.videoStatus}, imStatus: {runtime.imConnectStatus}</div> */}
|
|
|
</div>
|
|
|
)
|
|
|
- }
|
|
|
+ },
|
|
|
})
|