index.tsx 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154
  1. import { defineComponent, ref } from 'vue'
  2. import * as RTC from '@rongcloud/plugin-rtc'
  3. import Header from './header'
  4. import ActionBar, { state as ActionBarRuntime} from './action-bar'
  5. import VideoStatus from './video-status'
  6. import { state } from '/src/state'
  7. import event, { LIVE_EVENT_MESSAGE } from './event'
  8. import runtime, * as RuntimeUtils from './runtime'
  9. import Chronography from './chronography'
  10. // import { removeMedia } from './helpers'
  11. import styles from './index.module.less'
  12. const videoRef = ref<HTMLVideoElement | null>(null)
  13. let microphoneAudioTrack: RTC.RCLocalTrack
  14. let cameraVideoTrack: RTC.RCLocalTrack
  15. export default defineComponent({
  16. name: 'LiveBroadcast',
  17. async mounted() {
  18. this.initializeRoom()
  19. RuntimeUtils.loopSyncLike()
  20. event.on(LIVE_EVENT_MESSAGE['RC:Chatroom:Like'], this.onLikeMessage)
  21. window.onbeforeunload = this.beforeunload
  22. },
  23. beforeUnmount() {
  24. event.off(LIVE_EVENT_MESSAGE['RC:Chatroom:Like'], this.onLikeMessage)
  25. window.onbeforeunload = null
  26. },
  27. methods: {
  28. beforeunload() {
  29. if (runtime.videoStatus === 'liveing') {
  30. return '当前正在直播中是否确认关闭页面?'
  31. }
  32. },
  33. onLikeMessage(msg: any) {
  34. runtime.likeCount += msg.counts
  35. },
  36. getDeviceByDeviceType(type: RuntimeUtils.TrackType) {
  37. const videoDeviceId = localStorage.getItem(RuntimeUtils.VIDEO_DEVICE_ID)
  38. const audioDeviceId = localStorage.getItem(RuntimeUtils.AUDIO_DEVICE_ID)
  39. if (type === 'camera') {
  40. if (videoDeviceId) {
  41. return runtime.cameras.find(camera => camera.deviceId === videoDeviceId) || runtime.cameras[0]
  42. }
  43. return runtime.cameras[0]
  44. }
  45. if (audioDeviceId) {
  46. return runtime.microphones.find(microphone => microphone.deviceId === audioDeviceId) || runtime.microphones[0]
  47. }
  48. return runtime.microphones[0]
  49. },
  50. async initializeRoom () {
  51. if (!state.user) throw Error('请先登录')
  52. try {
  53. runtime.likeCount = state.user?.likeNum || 0
  54. runtime.lookCount = state.user?.lookNum || 0
  55. const isLiveing = sessionStorage.getItem(RuntimeUtils.START_LIVE_STATUS) === 'liveing'
  56. // IM连接
  57. await RuntimeUtils.connectIM(state.user?.imToken)
  58. runtime.videoRef = videoRef.value
  59. // 获取设备
  60. await RuntimeUtils.getMicrophones()
  61. await RuntimeUtils.getCameras()
  62. // 设置播放设备
  63. RuntimeUtils.setSelectCamera(this.getDeviceByDeviceType('camera'))
  64. RuntimeUtils.setSelectMicrophone(this.getDeviceByDeviceType('microphone'))
  65. cameraVideoTrack = await RuntimeUtils.getTrack('camera')
  66. runtime.videoRef && cameraVideoTrack.play(runtime.videoRef)
  67. // await RuntimeUtils.setTrack([cameraVideoTrack], 'camera', isLiveing)
  68. // await RuntimeUtils.getTrack('microphone')
  69. microphoneAudioTrack = await RuntimeUtils.getTrack('microphone')
  70. // microphoneAudioTrack.play()
  71. // console.log(microphoneAudioTrack)
  72. // console.log(runtime.deviceStatus)
  73. runtime.videoStatus = 'stream'
  74. const join = await RuntimeUtils.joinRoom(state.user?.roomUid, RTC.RCLivingType.VIDEO, {
  75. onMessageReceive(name, content) {
  76. console.log(name, content)
  77. },
  78. onKickOff(byServer: boolean) {
  79. console.log(byServer)
  80. },
  81. async onTrackPublish (tracks: RTC.RCRemoteTrack[]) {
  82. const subscribeRes = await join?.room?.subscribe(tracks)
  83. console.log(subscribeRes)
  84. if (subscribeRes?.code && subscribeRes.code !== RTC.RCRTCCode.SUCCESS) {
  85. console.log('资源订阅失败 ->', subscribeRes.code)
  86. }
  87. },
  88. onTrackUnpublish(tracks: RTC.RCRemoteTrack[]) {
  89. console.log(tracks)
  90. event.emit(LIVE_EVENT_MESSAGE['RM:RTC:TrackUnpublish'], tracks)
  91. },
  92. onSwitchRole(userId: string, role: RTC.RCRTCLiveRole) {
  93. event.emit(LIVE_EVENT_MESSAGE['RM:RTC:SwitchRole'], {
  94. userId,
  95. role,
  96. })
  97. },
  98. onTrackReady (track: RTC.RCRemoteTrack) {
  99. if (track.isAudioTrack()) {
  100. // 音轨不需要传递播放控件
  101. track.play()
  102. }
  103. },
  104. onUserJoin (userIds: string[]) {
  105. console.log('onUserJoin', userIds)
  106. },
  107. onUserLeave (userIds: string[]) {
  108. event.emit(LIVE_EVENT_MESSAGE['RM:RTC:UserLeave'], userIds)
  109. console.log('onUserLeave', userIds)
  110. },
  111. })
  112. if (join.room && join.code === RTC.RCRTCCode.SUCCESS) {
  113. runtime.joinedRoom = join.room
  114. }
  115. if (isLiveing) {
  116. await RuntimeUtils.startLive(false)
  117. runtime.videoStatus = 'liveing'
  118. } else {
  119. await RuntimeUtils.setTrack([cameraVideoTrack], 'camera', false)
  120. await RuntimeUtils.setTrack([microphoneAudioTrack], 'microphone', false)
  121. }
  122. const volume =localStorage.getItem(RuntimeUtils.AUDIO_DEVICE_VOLUME)
  123. if (volume) {
  124. ActionBarRuntime.volume = parseInt(volume)
  125. RuntimeUtils.setVolume(parseInt(volume))
  126. }
  127. } catch (error) {
  128. runtime.videoStatus = 'error'
  129. console.log(error)
  130. }
  131. },
  132. closeLive() {
  133. // removeMedia(runtime.mediaStreams, runtime.mediaStreamTrack)
  134. runtime.videoStatus = 'stream'
  135. },
  136. },
  137. render() {
  138. return (
  139. <div class={styles.main}>
  140. <Header/>
  141. <div class={styles.video}>
  142. <video ref={videoRef}></video>
  143. {!runtime.screenShareStatus ? <VideoStatus/> : null}
  144. {runtime.videoStatus === 'liveing' ? <Chronography/> : null}
  145. </div>
  146. <ActionBar/>
  147. {/* <div>video: {runtime.videoStatus}, imStatus: {runtime.imConnectStatus}</div> */}
  148. </div>
  149. )
  150. }
  151. })