ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

今日看

2020-11-30 23:04:07  阅读:193  来源: 互联网

标签:publisher let userId aliWebrtc video 今日 any


import React, { FC, useState, useEffect } from 'react'
import $dp from 'dataProvider'
import auth from 'utils/auth'
import i18n from 'i18n'
import audioicon from 'theme/images/audio.png'
import audiocloseicon from 'theme/images/audio_close.png'
import cameraicon from 'theme/images/camera.png'
import cameracloseicon from 'theme/images/camera_close.png'
import { Modal, message } from 'components/ui-components'
import { getUCNickName } from 'utils/ucUser'
import {
  showAlert, initialization, getSubscribeInfo, setConfigRemote, receivePublishManual
} from './utils'

import styles from './style.module.scss'

interface IWebRTCBodyProps {
  channelId: string
  ownerId: string
  onOwnerLeave: ()=>void
}

const WebRTC: FC<IWebRTCBodyProps> = (props) => {
  const {
    channelId, ownerId, onOwnerLeave
  } = props

  const [openAudia, setOpenAudia] = useState(true)
  const [openCamera, setOpenCamera] = useState(true)

  let publisherList: any[]
  let aliToken: any
  let isCameraEnable: boolean = true
  let currentUser: any = auth.getAuth()
  let nickName = getUCNickName(currentUser)
  let t = i18n.getFixedT(null, 'message')
  const aliWebrtc = window.aliWebrtc

  function removeDom(userid: any) {
  }

  function compareIsOwner(compareOwnerId: string) {
    let newOwnerId
    if (compareOwnerId.length > 1) {
      newOwnerId = compareOwnerId.substr(0, compareOwnerId.length - 1)
    }
    return ownerId === newOwnerId
  }

  function detelePublisher(userId: any) {
    let index = (publisherList as any).getIndexByProprety(userId, 'userId')
    if (index !== -1) {
      publisherList.splice(index, 1)
      detelePublisher(userId)
    } else {
      console.log('未找到之前的推流数据')// 删除推流用户
    }
  }

  function updateUserList() {
    let videoList = document.getElementById('remote-user-list-video')
    let userList = aliWebrtc.getUserList()

    if (videoList && videoList.hasChildNodes()) {
      let childList = videoList.childNodes
      for (let i = childList.length - 1; i >= 1; i--) {
        let childDiv = childList[i]
        let currentId = (childDiv as HTMLElement).id.substr(9)
        let isFind = false
        for (let j = 0; j < userList.length; j++) {
          let currentUser = userList[j]
          if (currentId === currentUser.userId) {
            isFind = true
            break
          }
        }
        if (!isFind) {
          videoList.removeChild(childList[i])
        }
      }
    }
    // let frg = document.createDocumentFragment()
    userList.forEach((user: any) => {
      let isFind = false
      let videoList = document.getElementById('remote-user-list-video')

      if (videoList && videoList.hasChildNodes()) {
        let childList = videoList.childNodes
        for (let i = childList.length - 1; i >= 1; i--) {
          let childDiv = childList[i]
          let currentId = (childDiv as HTMLElement).id.substr(9)
          if (currentId === user.userId) {
            isFind = true
            break
          }
        }
      }
      if (!isFind && videoList) {
        if (user.userId !== aliToken.userid) {
          if (!compareIsOwner(user.userId)) {
            let videoDiv = document.createElement('div')
            videoDiv.className = styles['video-box']
            videoDiv.id = `video-box${user.userId}`
            let videoText = document.createElement('div')
            videoText = document.createElement('div')
            videoText.className = styles['video-box-text']
            videoDiv.appendChild(videoText)
            let videoName = document.createElement('p')
            videoName.align = 'center'
            videoName.className = styles['video-text-p']
            videoName.innerHTML = `${user.displayName}`
            videoName.id = `videoName${user.userId}`
            videoText.appendChild(videoName)
            let videoParent = document.createElement('div')
            videoParent.className = styles['video-box-parent']
            videoDiv.appendChild(videoParent)
            let videoEle = document.createElement('video')
            videoEle.autoplay = true
            // videoEle.playsinline = true
            videoEle.controls = false
            videoEle.width = 146
            videoEle.height = 110
            videoEle.style.marginTop = '5'
            videoEle.id = `video${user.userId}`
            videoParent.appendChild(videoEle)

            let leftNameDiv = document.createElement('div')
            leftNameDiv.className = styles['video-box-text-2']
            videoDiv.appendChild(leftNameDiv)
            leftNameDiv.id = `videoBoxText2${user.userId}`
            let leftNamePara = document.createElement('p')
            leftNamePara.className = styles['video-text-p-2']
            leftNamePara.id = `videoName2${user.userId}`
            leftNameDiv.appendChild(leftNamePara)
            leftNameDiv.style.display = 'none'
            videoList.appendChild(videoDiv)
          }
        }
      }
    })
  }

  function unSubn(streamConfigWithPublisherInfo: any) {
    if (streamConfigWithPublisherInfo.subscribed) {
      console.log('已经订阅')
      return
    }
    console.log(`----onPublisher${streamConfigWithPublisherInfo.userId} ${streamConfigWithPublisherInfo.displayName}`)
    receivePublishManual(streamConfigWithPublisherInfo)
      .then((re: any) => {
        if (compareIsOwner(streamConfigWithPublisherInfo.userId)) {
          let videoEleID = 'local-video-window'
          let video = document.getElementById(videoEleID)
          // let videoNameEleID = 'videoName' + publisher.userId
          // let p = document.getElementById(videoNameEleID)
          // p.innerHTML = publisher.displayName
          if (streamConfigWithPublisherInfo.label !== 'sophon_video_screen_share') {
            aliWebrtc.setDisplayRemoteVideo(streamConfigWithPublisherInfo.userId, video, 1)
          } else {
            aliWebrtc.setDisplayRemoteVideo(streamConfigWithPublisherInfo.userId, video, 2)
          }

          // aliWebrtc.setDisplayRemoteVideo(streamConfigWithPublisherInfo.userId, video, 1)
        } else {
          let videoEleID = `video${streamConfigWithPublisherInfo.userId}`
          let video = document.getElementById(videoEleID)
          let videoNameEleID = `videoName${streamConfigWithPublisherInfo.userId}`
          let p = document.getElementById(videoNameEleID)

          let videoNameEleID2 = `videoName2${streamConfigWithPublisherInfo.userId}`
          let p2 = document.getElementById(videoNameEleID2)

          if (p) {
            p.innerHTML = streamConfigWithPublisherInfo.displayName
          }
          if (p2) {
            p2.innerHTML = streamConfigWithPublisherInfo.displayName
          }

          let videoBoxText2 = `videoBoxText2${streamConfigWithPublisherInfo.userId}`
          let videoBoxText2Ele = document.getElementById(videoBoxText2)
          let newpublisher = aliWebrtc.getUserInfo(re)

          if (videoBoxText2Ele) {
            for (let stream of newpublisher.streamConfigs) {
              if (stream.label === 'sophon_video_camera_large') {
                if (stream.state === 'active') {
                  videoBoxText2Ele.style.display = 'block'
                } else {
                  videoBoxText2Ele.style.display = 'none'
                }
                break
              }
            }
          }
          if (streamConfigWithPublisherInfo.label !== 'sophon_video_screen_share') {
            aliWebrtc.setDisplayRemoteVideo(streamConfigWithPublisherInfo.userId, video, 1)
          } else {
            aliWebrtc.setDisplayRemoteVideo(streamConfigWithPublisherInfo.userId, video, 2)
          }
          // aliWebrtc.setDisplayRemoteVideo(streamConfigWithPublisherInfo.userId, video, 1)
        }
      }).catch((err: any) => {
        console.log(`订阅断开 重新订阅失败${err}`)
        detelePublisher(streamConfigWithPublisherInfo.userId)
        removeDom(streamConfigWithPublisherInfo.userId)
      })
  }

  function autoSub(publisher: any, label: string) {
    var i = publisher.streamConfigs.findIndex(((e:any) => e.label === label && e.state === 'active' && e.subscribed === false
    ))

    if (i > -1) {
      var o = publisher.streamConfigs[i]
      o.userId = publisher.userId
      o.displayName = publisher.displayName
      unSubn(o)
    }
  }

  function updatePublisherStream(publisher: any, index: number) {
    let oldStreamConfigs = JSON.parse(JSON.stringify(publisherList[index].streamConfigs))
    let newStreamConfigs = publisher.streamConfigs
    let subscribeInfo = getSubscribeInfo(publisher.userId)
    oldStreamConfigs.forEach((v: any, i: any, a: any) => {
      let newStream = newStreamConfigs.getObjByProprety(v.label, 'label')
      // 判断流状态改变了 但不确定我们是否订阅了该流
      if (v.state !== newStream.state) {
        console.log(`流的状态变了${v.label}`, v, v.type, `>${v.state}>>${newStream.state}>`, newStream, subscribeInfo)
        // 并且要取消订阅某个流,不然就不能再次订阅了
        subscribeInfo.subscribeInfoArr.forEach((sv) => {
          if (v.label === sv.label) {
            console.log('setConfigRemote取消订阅调用[api]:subscribe', publisher.userId, sv.type, sv.label)
            setConfigRemote(publisher.userId, sv.type, sv.label).then((re: any) => {
              // 移除dom
              removeDom(publisher.userId)
            }).catch((error: any) => {
              console.error('流的状态变了重新订阅出问题', error)
            })
          }
        })
      }
    })
    publisherList.splice(index, 1, publisher)

    setTimeout(() => {
      autoSub(publisher, 'sophon_video_screen_share')
      autoSub(publisher, 'sophon_video_camera_large')
    }, 2000)
  }

  function init() {
    /**
      * remote用户加入房间 onJoin
      * 更新在线用户列表
      */
    aliWebrtc.on('onJoin', (publisher: any) => {
      aliWebrtc.configRemoteAudio(publisher.userId, false)
      aliWebrtc.configRemoteCameraTrack(publisher.userId, false, false)

      if (publisher.userId && !compareIsOwner(publisher.userId)) {
        console.log(`join: ${publisher.userId}`)
        updateUserList()
      }
      // 重置订阅状态
      // 默认订阅远端音频和视频大流,但需要调用subscribe才能生效
      // 这里取消默认订阅,根据需求进行订阅
      // aliWebrtc.configRemoteAudio(publisher.userId, true)
      // aliWebrtc.configRemoteCameraTrack(publisher.userId, true, true)
      // showAlert(publisher.displayName + '加入房间','success')
      // console.log(`${publisher.displayName}加入房间`)
    })

    aliWebrtc.on('onNotify', (data: any) => {
      console.log('用户状态回调')
      console.log(data)
    })

    /**
     * remote流发布事件 onPublish
     * 将该用户新增到推流列表
     * 若该用户已存在推流列表,则进行状态更新
     */
    aliWebrtc.on('onPublisher', (publisher: any) => {
      console.log('onPublisher', publisher)
      let index = (publisherList as any).getIndexByProprety(publisher.userId, 'userId')
      if (index === -1) {
        // 新增
        publisherList.push(publisher)
        if (publisher.userId !== aliToken.userid) {
          const o = publisher.streamConfigs.findIndex(((e: any) => e.type === 'audio' && e.state === 'active'
          ))
          const n = publisher.streamConfigs.findIndex(((e: any) => e.label === 'sophon_video_screen_share' && e.state === 'active'
          ))
          let r = publisher.streamConfigs.findIndex(((e: any) => e.label === 'sophon_video_camera_large' && e.state === 'active'
          ))
          if (r === -1 && (r = publisher.streamConfigs.findIndex(((e: any) => e.label === 'sophon_video_camera_small' && e.state === 'active'
          ))) > -1 && o > -1) {
            const a = publisher.streamConfigs[o]
            a.userId = publisher.userId
            a.displayName = publisher.displayName
            unSubn(a)
          }
          if (n > -1) {
            const s = publisher.streamConfigs[n]
            s.userId = publisher.userId
            s.displayName = publisher.displayName
            unSubn(s)
          }
          if (r > -1) {
            const c = publisher.streamConfigs[r]
            c.userId = publisher.userId
            c.displayName = publisher.displayName
            unSubn(c)
          }
        }
      } else {
        // 流状态更新
        updatePublisherStream(publisher, index)
      }
    })

    /**
     * remote流结束发布事件 onUnPublisher
     * 推流列表删除该用户
     * 移除用户视图
     * 初始化订阅状态
     */
    aliWebrtc.on('onUnPublisher', (publisher: any) => {
      console.log('onUnPublisher', publisher)
      detelePublisher(publisher.userId)
      removeDom(publisher.userId)
      initialization(publisher.userId)
    })

    /**
     * 检测到用户离开频道
     * 更新用户列表
     * 移除用户视图
     */
    aliWebrtc.on('onLeave', (publisher: any) => {
      if (publisher.userId.includes(ownerId)) {
        onOwnerLeave()
      }
      initialization(publisher.userId)
      updateUserList()
      removeDom(publisher.userId)
      // message.info(`${publisher.displayName}离开房间`)
    })
  }

  function getConfigAndJoinRoom() {
    let userId: string
    if (currentUser && currentUser.user_id) {
      userId = `${String(currentUser.user_id)}3`
    } else {
      return
    }

    $dp.aliRTC.channelToken
      .replace({ channel_id: channelId, user_id: userId })
      .get()
      .then((token: any) => {
        aliToken = token
        aliToken.channel = token.channel_id
        aliToken.userid = token.user_id
        joinRoom(aliToken)
      })
      .catch((error:any) => {
        console.log(error)
        message.warning('aliwebrtc token get failed!')
      })
  }

  function doJoinRoomProc(authInfo: any) {
    aliWebrtc.joinChannel(authInfo, nickName).then(() => {
      // showAlert('加入房间成功', 'success', 0)
      // 4. 发布本地流
      aliWebrtc.configLocalAudioPublish = true
      aliWebrtc.configLocalCameraPublish = isCameraEnable
      aliWebrtc.publish().then((res: any) => {
        // Msg.warn(t('webrtc success'))
        // setTimeout(() => {
        //   console.log('发布流成功')
        // }, 1000)
        console.log('发布流成功')
      }, (error: any) => {
        let errorTitle = `[推流失败]${error.message}`
        console.log(errorTitle)
        // $('.streamType').show()
        showAlert(`[推流失败]${error.message}`, 'danger', 0)
        message.warning(`[推流失败]${error.message}`)
      })
    }).catch((error: any) => {
      // showAlert('[加入房间失败]' + error.message, 'danger',0)
      message.warning(`[加入房间失败]${error.message}`)
    })
  }

  function joinRoom(authInfo: any) {
    // 1.预览
    var localVideo = document.getElementById('local-video-currentuser')
    // var localVideo = $('.local-video video')
    aliWebrtc.startPreview(localVideo).then((obj: any) => {
      showAlert('----[开启预览成功]', 'danger', 0)
      setTimeout(() => {
        let videoLocalELe = document.getElementById('local-video-currentuser')
        // console.log(videoLocalELe.videoWidth, videoLocalELe.videoHeight)
        let videoWidth: number = (videoLocalELe as any).videoWidth
        let videoHeight: number = (videoLocalELe as any).videoHeight
        if (videoWidth < 50 || videoHeight < 50) {
          setTimeout(() => {
            videoLocalELe = document.getElementById('local-video-currentuser')
            videoWidth = (videoLocalELe as any).videoWidth
            videoHeight = (videoLocalELe as any).videoHeight
            console.log(videoWidth, videoHeight)
            if (videoWidth < 50 || videoHeight < 50) {
              isCameraEnable = false
              // this.setState({
              //   openCamera: false
              // })
              let name2 = document.getElementById('video-box-text-2')
              if (name2) {
                name2.style.display = 'none'
              }
            }
            doJoinRoomProc(authInfo)
          }, 2000)
        } else {
          doJoinRoomProc(authInfo)
        }
      }, 2000)
    }).catch((error: any) => {
      showAlert(`[开启预览失败]${error.message}`, 'danger', 0)
      isCameraEnable = false
      // this.setState({
      //   openCamera: false
      // })
      let name2 = document.getElementById('video-box-text-2')
      if (name2) {
        name2.style.display = 'none'
      }
      doJoinRoomProc(authInfo)
    })
  }

  function audioAction() {
    if (!openAudia) {
      console.log('open Audia')
      // window.aliWebrtc.enableHighDefinitionPreview(true)
      aliWebrtc.configLocalAudioPublish = true
      aliWebrtc.publish().then((res:any) => {
        setTimeout(() => {
          console.log('发布流成功')
        }, 1000)
      }, (error:any) => {
        // $('.streamType').show()
        showAlert(`[推流失败]${error.message}`, 'danger', 0)
      })
      setOpenAudia(true)
    } else {
      console.log('close Audia')
      // window.aliWebrtc.enableHighDefinitionPreview(false)
      aliWebrtc.configLocalAudioPublish = false
      aliWebrtc.unPublish().then(() => {
        aliWebrtc.publish().then((res:any) => {
          setTimeout(() => {
            console.log('发布流成功')
          }, 1000)
        }, (error:any) => {
          // $('.streamType').show()
          showAlert(`[推流失败]${error.message}`, 'danger', 0)
        })
      }, (error:any) => {
        console.log(error.message)
      })
      setOpenAudia(false)
    }
  }

  function cameraAction() {
    if (!openCamera) {
      console.log('open camera')
      if (!isCameraEnable) {
        // Modal.warning({ title: t('bad camera') })
        return
      }
      let winTips = document.getElementById('local-video-currentuser-parent')
      if (winTips) {
        winTips.style.display = 'block'
      }

      let name2 = document.getElementById('video-box-text-2')
      if (name2) {
        name2.style.display = 'block'
      }
      aliWebrtc.configLocalCameraPublish = true
      aliWebrtc.publish().then((res:any) => {
        setTimeout(() => {
          console.log('发布流成功')
        }, 2000)
      }, (error:any) => {
        showAlert(`[推流失败]${error.message}`, 'danger', 0)
      })
      setOpenCamera(true)
    } else {
      console.log('close camera')
      let winTips = document.getElementById('local-video-currentuser-parent')
      if (winTips) {
        winTips.style.display = 'none'
      }
      let name2 = document.getElementById('video-box-text-2')
      if (name2) {
        name2.style.display = 'none'
      }

      aliWebrtc.configLocalCameraPublish = false
      aliWebrtc.unPublish().then(() => {
        aliWebrtc.publish().then((res:any) => {
          setTimeout(() => {
            console.log('发布流成功')
          }, 2000)
        }, (error:any) => {
          // $('.streamType').show()
          showAlert(`[推流失败]${error.message}`, 'danger', 0)
        })
      }, (error:any) => {
        console.log(error.message)
      })
      setOpenCamera(false)
    }
  }

  function createAliyun() {
    publisherList = []

    /**
     * AliWebRTC isSupport检测
     */
    aliWebrtc.isSupport().then((re: any) => {
      console.log(re)
      init()
      getConfigAndJoinRoom()
    }).catch((error: any) => {
      // self.sendCmdMsg(NTF_MSG_TYPE.LIVE_CANCEL_APPLY_CONNECT, LIVE_CONNECT_TYPE.APPLY)
      // let message
      // $bus.preprocess.publish(CTL_MSG_TYPE.LIVE_CMD_MSG, {
      //   type: NTF_MSG_TYPE.LIVE_CANCEL_APPLY_CONNECT,
      //   data: {}
      // })
      // if (!error.audioDevice) {
      //   message = this.t('audio not found')
      // } else if (!error.videoDevice) {
      //   message = this.t('video not found')
      // } else {
      //   message = error.message
      // }

      // Modal.warning({
      //   title: message,
      //   onOK() {
      //   }
      // })
    })
  }

  useEffect(() => {
    // runningMarquee()
    createAliyun()
    return () => {
      console.log('----container leavechannel')
      aliWebrtc.stopPreview().then().catch()
      aliWebrtc.leaveChannel()
    }
  }, [])

  return (
    <div>
      <div className={styles['remote-user-list']}>
        <div className={styles['remote-user-list-video']} id="remote-user-list-video">
          <div className={styles['video-box']}>
            <div className={styles['video-box-text']}>
              <p className={styles['video-text-p']}>{nickName}</p>
            </div>
            <div className={styles['video-box-parent']} id="local-video-currentuser-parent">
              <video id="local-video-currentuser" autoPlay controls={false} width="146px" height="110px" />
            </div>
            <div className={styles['video-box-text-2']} id="video-box-text-2">
              <p className={styles['video-text-p-2']}>{nickName}</p>
            </div>
          </div>
        </div>
      </div>
      <div className={styles['local-video']}>
        <div className={styles['local-video-window-close']} id="local-video-window-close">
          <div className={styles['local-video-window-close-tips']}>
            <h1 className={styles['local-video-window-close-tips-title']}>{t('closed camera')}</h1>
          </div>
        </div>
        <div className={styles['local-video-window-parent']}>
          <video id="local-video-window" autoPlay controls={false} width="100%" height="100%"> </video>
        </div>
      </div>
      <div className={styles['bottom-view']}>
        <div className={styles['operation-container-head']} onClick={() => audioAction()}><img className={styles.img} src={openAudia ? audioicon : audiocloseicon} width="30px" /></div>
        <div className={styles['operation-container-head']} onClick={() => cameraAction()}><img className={styles.img} src={openCamera ? cameraicon : cameracloseicon} width="30px" margin-left="-15px" /></div>
        {/* <div className={styles['operation-container-righticon']} type="primary" onClick={() => this.audioAction()}><img className={styles['img']} src={this.state.openAudia ? audioicon : audiocloseicon} align="left" width="30px" /></div>
                    <div className={styles['operation-container-head']} type="primary" onClick={() => this.cameraAction()}><img className={styles['img']} src={this.state.openCamera ? cameraicon : cameracloseicon} width="30px" margin-left="-15px" /></div> */}
      </div>
    </div>
  )
}

export default WebRTC

 

标签:publisher,let,userId,aliWebrtc,video,今日,any
来源: https://www.cnblogs.com/slivens/p/14064950.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有