瀏覽代碼

Merge branch 'master' of http://git.dayaedu.com/lex/dy-admin-live

lex-xin 3 年之前
父節點
當前提交
d7cdf98c25

+ 59 - 56
src/components/live-broadcast/action-bar.tsx

@@ -14,19 +14,17 @@ export default defineComponent({
         microphone: false, // 麦克风
         microphone: false, // 麦克风
         screen: false, // 共享屏幕
         screen: false, // 共享屏幕
         share: false, // 分享
         share: false, // 分享
-      } as { [key: string]: boolean },
-      volume: 20,
+      },
       shareVisiable: false
       shareVisiable: false
     }
     }
   },
   },
   computed: {
   computed: {
     isCameraDisabled() {
     isCameraDisabled() {
-      // @ts-ignore
       return this.barStatus.camera && runtime.deviceStatus.camera !== 'denied'
       return this.barStatus.camera && runtime.deviceStatus.camera !== 'denied'
     },
     },
     isMicrophoneDisabled() {
     isMicrophoneDisabled() {
-      console.log(this)
-      return this.barStatus.microphone && runtime.deviceStatus.microphone !== 'denied'
+      const isDisabled = this.barStatus.microphone && runtime.deviceStatus.microphone !== 'denied'
+      return isDisabled
     },
     },
     isVolumeDisabled() {
     isVolumeDisabled() {
       return this.barStatus.volume && this.volume === 0
       return this.barStatus.volume && this.volume === 0
@@ -148,63 +146,68 @@ export default defineComponent({
           </div> */}
           </div> */}
           <div class={styles['bar-btn']}>
           <div class={styles['bar-btn']}>
             <div class={styles.btnInner}>
             <div class={styles.btnInner}>
-            <SvgIcon
-              onClick={() => {
-                this.barStatus.microphone = !this.barStatus.microphone
-                RuntimeUtils.toggleDevice('microphone')
-              }}
-              name={this.isMicrophoneDisabled ? 'bar-mike-disabled' : 'bar-mike'}
-              style={{
-                width: '22px',
-                cursor: 'pointer'
-              }}
-            />
-            <ElDropdown
-              placement="top-start"
-              popper-options={{ boundariesElement: '#action-bar', gpuAcceleration: false }}
-              onCommand={RuntimeUtils.setSelectMicrophone}
-              // @ts-ignore
-              vSlots={{
-                dropdown: () => (
-                  <ElDropdownMenu>
-                    {runtime.microphones.map(item => (<ElDropdownItem command={item}>{item.label}</ElDropdownItem>))}
-                  </ElDropdownMenu>
-                )
-              }}
-            >
-              <div class={styles['bar-btn']} style={{ height: '32px' }}>
-                <SvgIcon
-                  name="bar-arrow-down"
-                  style={{
-                    width: '18px'
-                  }}
-                />
-              </div>
-            </ElDropdown>
-        </div>
-        <span class={styles['bar-btn-text']}>麦克风</span>
-      </div>
-
-    </div>
-      <div style={{ display: 'flex' }}>
-        <div class={styles['bar-btn']} >
-          <div class={styles.btnInner}>
+              <SvgIcon
+                onClick={() => {
+                  const needPublish = runtime.videoStatus === 'liveing'
+                  this.barStatus.microphone = !this.barStatus.microphone
+                  if (!this.barStatus.microphone) {
+                    RuntimeUtils.openDevice('microphone', needPublish)
+                  } else {
+                    RuntimeUtils.closeDevice('microphone', needPublish)
+                  }
+                }}
+                name={this.isMicrophoneDisabled ? 'bar-mike-disabled' : 'bar-mike'}
+                style={{
+                  width: '22px',
+                  cursor: 'pointer'
+                }}
+              />
+              <ElDropdown
+                placement="top-start"
+                popper-options={{ boundariesElement: '#action-bar', gpuAcceleration: false }}
+                onCommand={RuntimeUtils.setSelectMicrophone}
+                // @ts-ignore
+                vSlots={{
+                  dropdown: () => (
+                    <ElDropdownMenu>
+                      {runtime.microphones.map(item => (<ElDropdownItem command={item}>{item.label}</ElDropdownItem>))}
+                    </ElDropdownMenu>
+                  )
+                }}
+              >
+                <div class={styles['bar-btn']} style={{ height: '32px' }}>
                   <SvgIcon
                   <SvgIcon
-                    name="bar-share"
+                    name="bar-arrow-down"
                     style={{
                     style={{
-                      width: '22px',
-                      cursor: 'pointer'
+                      width: '18px'
                     }}
                     }}
                   />
                   />
-              </div>
-              <span class={styles['bar-btn-text']}>分享</span>
+                </div>
+              </ElDropdown>
+            </div>
+            <span class={styles['bar-btn-text']}>麦克风</span>
+          </div>
+
+        </div>
+        <div style={{ display: 'flex' }}>
+          <div class={styles['bar-btn']} >
+            <div class={styles.btnInner}>
+              <SvgIcon
+                name="bar-share"
+                style={{
+                  width: '22px',
+                  cursor: 'pointer'
+                }}
+              />
             </div>
             </div>
+            <span class={styles['bar-btn-text']}>分享</span>
           </div>
           </div>
-          {/* <ElButton onClick={RuntimeUtils.shareScreenVideo}>屏幕共享</ElButton> */}
-          <ElDialog modelValue={this.shareVisiable} title="分享" before-close={() => { this.shareVisiable = false }}>
-            11111
-          </ElDialog>
         </div>
         </div>
-        )
+        {/* <ElButton onClick={RuntimeUtils.shareScreenVideo}>屏幕共享</ElButton> */}
+        <ElDialog modelValue={this.shareVisiable} title="分享" before-close={() => { this.shareVisiable = false }}>
+          11111
+        </ElDialog>
+      </div>
+    )
   }
   }
 })
 })

+ 8 - 9
src/components/live-broadcast/index.tsx

@@ -11,9 +11,6 @@ import styles from './index.module.less'
 
 
 const videoRef = ref<HTMLVideoElement | null>(null)
 const videoRef = ref<HTMLVideoElement | null>(null)
 
 
-const mediaStreams = new MediaStream()
-
-
 let microphoneAudioTrack: RTC.RCLocalTrack
 let microphoneAudioTrack: RTC.RCLocalTrack
 let cameraVideoTrack: RTC.RCLocalTrack
 let cameraVideoTrack: RTC.RCLocalTrack
 
 
@@ -21,8 +18,16 @@ export default defineComponent({
   name: 'LiveBroadcast',
   name: 'LiveBroadcast',
   async mounted() {
   async mounted() {
     this.initializeRoom()
     this.initializeRoom()
+    RuntimeUtils.loopSyncLike()
+    event.on(LIVE_EVENT_MESSAGE['RC:Chatroom:Like'], this.onLikeMessage)
+  },
+  beforeUnmount() {
+    event.off(LIVE_EVENT_MESSAGE['RC:Chatroom:Like'], this.onLikeMessage)
   },
   },
   methods: {
   methods: {
+    onLikeMessage(msg: any) {
+      runtime.likeCount += msg.counts
+    },
     async initializeRoom () {
     async initializeRoom () {
       if (!state.user) throw Error('请先登录')
       if (!state.user) throw Error('请先登录')
       try {
       try {
@@ -30,21 +35,15 @@ export default defineComponent({
         runtime.videoRef = videoRef.value
         runtime.videoRef = videoRef.value
         await RuntimeUtils.getMicrophones()
         await RuntimeUtils.getMicrophones()
         await RuntimeUtils.getCameras()
         await RuntimeUtils.getCameras()
-        // runtime.mediaStreams = mediaStreams
         RuntimeUtils.setSelectCamera(runtime.cameras[0])
         RuntimeUtils.setSelectCamera(runtime.cameras[0])
         RuntimeUtils.setSelectMicrophone(runtime.microphones[0])
         RuntimeUtils.setSelectMicrophone(runtime.microphones[0])
         cameraVideoTrack = await RuntimeUtils.getTrack('camera')
         cameraVideoTrack = await RuntimeUtils.getTrack('camera')
-        // console.log(cameraVideoTrack)
         runtime.videoRef && cameraVideoTrack.play(runtime.videoRef)
         runtime.videoRef && cameraVideoTrack.play(runtime.videoRef)
-        // RuntimeUtils.setVideoSrcObject(runtime.videoRef, mediaStreams)
         await RuntimeUtils.setTrack([cameraVideoTrack], 'camera')
         await RuntimeUtils.setTrack([cameraVideoTrack], 'camera')
         microphoneAudioTrack = await RuntimeUtils.getTrack('microphone')
         microphoneAudioTrack = await RuntimeUtils.getTrack('microphone')
         runtime.videoRef && microphoneAudioTrack.play(runtime.videoRef)
         runtime.videoRef && microphoneAudioTrack.play(runtime.videoRef)
         console.log(runtime.deviceStatus)
         console.log(runtime.deviceStatus)
         runtime.videoStatus = 'stream'
         runtime.videoStatus = 'stream'
-        // runtime.mediaStreamTrack = mediaStreams.getTracks()
-        // await RuntimeUtils.setTrack([microphoneAudioTrack], 'microphone')
-        // w_3fi4PXQcooe5_VUseReE
         const join = await RuntimeUtils.joinRoom(state.user?.roomUid, RTC.RCLivingType.VIDEO, {
         const join = await RuntimeUtils.joinRoom(state.user?.roomUid, RTC.RCLivingType.VIDEO, {
           onMessageReceive(name, content) {
           onMessageReceive(name, content) {
             console.log(name, content)
             console.log(name, content)

+ 42 - 13
src/components/live-broadcast/runtime.ts

@@ -22,6 +22,8 @@ type DeviceStatus = {
 }
 }
 
 
 const runtime = reactive({
 const runtime = reactive({
+  /** 房间id */
+  roomUid: 'LIVE-2112263-12345',
   /** IM连接状态 */
   /** IM连接状态 */
   imConnectStatus: 'connecting' as imConnectStatus,
   imConnectStatus: 'connecting' as imConnectStatus,
   // 屏幕分享状态
   // 屏幕分享状态
@@ -181,12 +183,20 @@ export const shareScreenVideo = async () => {
   if (runtime.rtcClient) {
   if (runtime.rtcClient) {
     const screenTrack = await getTrack('screen')
     const screenTrack = await getTrack('screen')
     const oldTrack = runtime.activeTracks.camera as RTC.RCLocalTrack
     const oldTrack = runtime.activeTracks.camera as RTC.RCLocalTrack
-    removeTrack([oldTrack], 'camera')
+    // removeTrack([oldTrack], 'camera')
+    runtime.joinedRoom?.unpublish([oldTrack])
     setTrack([screenTrack as RTC.RCLocalTrack], 'screen')
     setTrack([screenTrack as RTC.RCLocalTrack], 'screen')
+    if (runtime.videoRef) {
+      screenTrack.play(runtime.videoRef)
+    }
     screenTrack?.on(RTC.RCLocalTrack.EVENT_LOCAL_TRACK_END, (track: RTC.RCLocalTrack) => {
     screenTrack?.on(RTC.RCLocalTrack.EVENT_LOCAL_TRACK_END, (track: RTC.RCLocalTrack) => {
       runtime.screenShareStatus = false
       runtime.screenShareStatus = false
-      removeTrack([track], 'screen')
+      track.destroy()
+      // removeTrack([track], 'screen')
       setTrack([oldTrack as RTC.RCLocalTrack], 'camera')
       setTrack([oldTrack as RTC.RCLocalTrack], 'camera')
+      if (runtime.videoRef) {
+        oldTrack.play(runtime.videoRef)
+      }
       // setVideoSrcObject(runtime.videoRef, this.mediaStreams)
       // setVideoSrcObject(runtime.videoRef, this.mediaStreams)
     })
     })
 
 
@@ -292,7 +302,7 @@ export const removeTrack = async (tracks: RTC.RCLocalTrack[], trackType: TrackTy
     // await runtime.mediaStreams?.removeTrack(track._msTrack)
     // await runtime.mediaStreams?.removeTrack(track._msTrack)
     // runtime.activeTracks[trackType].destroy()
     // runtime.activeTracks[trackType].destroy()
     // console.log(runtime.activeTracks[trackType])
     // console.log(runtime.activeTracks[trackType])
-    // track.destroy()
+    track.destroy()
     runtime.activeTracks[trackType] = null
     runtime.activeTracks[trackType] = null
   }
   }
   if (needPublish) {
   if (needPublish) {
@@ -335,7 +345,13 @@ export const startLive = async () => {
  */
  */
 export const closeLive = async () => {
 export const closeLive = async () => {
   // removeMedia(runtime.mediaStreams, runtime.mediaStreamTrack)
   // removeMedia(runtime.mediaStreams, runtime.mediaStreamTrack)
-  // request.post('')
+  await request.post('/api-im/user/statusImUser', {
+    data: {
+      os: 'PC',
+      status: 2,
+      userId: state.user?.id,
+    }
+  })
   runtime.videoStatus = 'stopped'
   runtime.videoStatus = 'stopped'
   for (const key in runtime.activeTracks) {
   for (const key in runtime.activeTracks) {
     if (Object.prototype.hasOwnProperty.call(runtime.activeTracks, key)) {
     if (Object.prototype.hasOwnProperty.call(runtime.activeTracks, key)) {
@@ -351,9 +367,14 @@ export const closeLive = async () => {
  * 同步点赞数量
  * 同步点赞数量
  */
  */
 export const loopSyncLike = async () => {
 export const loopSyncLike = async () => {
-  if (runtime.likeCount !== runtime.lastLikeCount) {
+  if (runtime.likeCount !== runtime.lastLikeCount || runtime.likeCount === 0) {
     try {
     try {
-      await request.post('/api-web/imLiveBroadcastRoom/syncLike', {})
+      await request.get('/api-web/imLiveBroadcastRoom/syncLike', {
+        params: {
+          likeNum: runtime.likeCount,
+          roomUid: runtime.roomUid,
+        }
+      })
       runtime.lastLikeCount = runtime.likeCount
       runtime.lastLikeCount = runtime.likeCount
     } catch (error) {}
     } catch (error) {}
   }
   }
@@ -401,22 +422,30 @@ export const sendMessage = async (msg: any, type: SendMessageType = 'text') => {
     message = new MessageSeatResponse(msg)
     message = new MessageSeatResponse(msg)
   }
   }
   if (!message) return
   if (!message) return
-  console.log(msg)
+  console.log(message)
   await RongIMLib.sendMessage(conversation, message)
   await RongIMLib.sendMessage(conversation, message)
 }
 }
 
 
 export const openDevice = async (trackType: TrackType, needPublish = true) => {
 export const openDevice = async (trackType: TrackType, needPublish = true) => {
-  const track = await getTrack(trackType)
-  await setTrack([track], trackType, needPublish)
-  if (runtime.videoRef) {
-    track.play(runtime.videoRef)
+  if (trackType === 'microphone' && runtime.activeTracks[trackType]) {
+    runtime.activeTracks[trackType]?.unmute()
+  } else {
+    const track = await getTrack(trackType)
+    await setTrack([track], trackType, needPublish)
+    if (runtime.videoRef) {
+      track.play(runtime.videoRef)
+    }
   }
   }
 }
 }
 
 
 export const closeDevice = async (trackType: TrackType, needPublish = true) => {
 export const closeDevice = async (trackType: TrackType, needPublish = true) => {
   const track = runtime.activeTracks[trackType]
   const track = runtime.activeTracks[trackType]
-  await removeTrack([track] as RTC.RCLocalTrack[], trackType, needPublish)
-  track?.destroy()
+  if (trackType !== 'microphone') {
+    await removeTrack([track] as RTC.RCLocalTrack[], trackType, needPublish)
+    track?.destroy()
+  } else {
+    track?.mute()
+  }
 }
 }
 
 
 export const toggleDevice = async (trackType: TrackType) => {
 export const toggleDevice = async (trackType: TrackType) => {

+ 3 - 2
src/components/live-message/index.tsx

@@ -2,6 +2,7 @@ import { defineComponent } from "vue"
 import { ElTabs, ElTabPane } from "element-plus"
 import { ElTabs, ElTabPane } from "element-plus"
 import styles from './index.module.less'
 import styles from './index.module.less'
 import Message from './message'
 import Message from './message'
+import runtime from '../live-broadcast/runtime'
 import SendMessage from './send-message';
 import SendMessage from './send-message';
 import ItemList from './item-list'
 import ItemList from './item-list'
 import JoinModel from './model/join-model';
 import JoinModel from './model/join-model';
@@ -34,7 +35,7 @@ export default defineComponent({
             <p class={styles.text}><SvgIcon name="message-look" color="#fff" class={styles.dataIcon} />当前观看</p>
             <p class={styles.text}><SvgIcon name="message-look" color="#fff" class={styles.dataIcon} />当前观看</p>
           </div>
           </div>
           <div>
           <div>
-            <p class={styles.num}>1361</p>
+            <p class={styles.num}>{runtime.likeCount}</p>
             <p class={styles.text}><SvgIcon name="message-giveUp" color="#fff" class={styles.dataIcon} />累计点赞</p>
             <p class={styles.text}><SvgIcon name="message-giveUp" color="#fff" class={styles.dataIcon} />累计点赞</p>
           </div>
           </div>
         </div>
         </div>
@@ -68,4 +69,4 @@ export default defineComponent({
       </div>
       </div>
     )
     )
   }
   }
-})
+})