guoshilong
2023-11-13 54849757852f6ab40eb17afbd03d1d839b60a38d
src/components/livestream-agora.vue
@@ -1,7 +1,7 @@
<template>
  <div class="mt20 flex-column flex-justify-start flex-align-center">
    <div id="player" style="width: 720px; height: 420px; border: 1px solid"></div>
    <p class="fz24">Live streaming source selection</p>
    <p class="fz24">直播源选择</p>
    <div class="flex-row flex-justify-center flex-align-center mt10">
      <template v-if="livePara.liveState && dronePara.isDockLive">
        <span class="mr10">Lens:</span>
@@ -12,7 +12,7 @@
      <template v-else>
      <a-select
        style="width:150px"
        placeholder="Select Drone"
        placeholder="选择设备"
        v-model:value="dronePara.droneSelected"
      >
        <a-select-option
@@ -26,7 +26,7 @@
      <a-select
        class="ml10"
        style="width:150px"
        placeholder="Select Camera"
        placeholder="选择相机"
        v-model:value="dronePara.cameraSelected"
      >
        <a-select-option
@@ -54,7 +54,7 @@
      <a-select
        class="ml10"
        style="width:150px"
        placeholder="Select Clarity"
        placeholder="选择画质"
        @select="onClaritySelect"
      >
        <a-select-option
@@ -66,7 +66,7 @@
      </a-select>
    </div>
    <p class="fz16 mt10">
      Note: Obtain The Following Parameters From https://console.agora.io
      <!-- 注意:从中获取以下参数https://console.agora.io -->
    </p>
    <div class="flex-row flex-justify-center flex-align-center">
      <span class="mr10">AppId:</span>
@@ -76,7 +76,6 @@
        class="ml10"
        v-model:value="agoraPara.token"
        placeholder="Token"
        @change="encodeToken"
      ></a-input>
      <span class="ml10">Channel:</span>
      <a-input
@@ -86,16 +85,16 @@
      ></a-input>
    </div>
    <div class="mt20 flex-row flex-justify-center flex-align-center">
      <a-button v-if="livePara.liveState && dronePara.isDockLive" type="primary" large @click="onSwitch">Switch Lens</a-button>
      <a-button v-else type="primary" large @click="onStart">Play</a-button>
      <a-button v-if="livePara.liveState && dronePara.isDockLive" type="primary" large @click="onSwitch">切换镜头</a-button>
      <a-button v-else type="primary" large @click="onStart">播放</a-button>
      <a-button class="ml20" type="primary" large @click="onStop"
        >Stop</a-button
        >暂停</a-button
      >
      <a-button class="ml20" type="primary" large @click="onUpdateQuality"
        >Update Clarity</a-button
        >更新画质</a-button
      >
      <a-button v-if="!livePara.liveState || !dronePara.isDockLive" class="ml20" type="primary" large @click="onRefresh"
        >Refresh Live Capacity</a-button
        >刷新实时容量</a-button
      >
    </div>
  </div>
@@ -169,7 +168,6 @@
  liveState: false
})
const nonSwitchable = 'normal'
const onRefresh = async () => {
  dronePara.droneList = []
  dronePara.cameraList = []
@@ -204,11 +202,14 @@
onMounted(() => {
  onRefresh()
  agoraPara.token = encodeURIComponent(agoraPara.token)
  agoraClient = AgoraRTC.createClient({ mode: 'live', codec: 'vp8' })
  agoraClient.setClientRole('audience', { level: 2 })
  if (agoraClient.connectionState === 'DISCONNECTED') {
    agoraClient.join(agoraPara.appid, agoraPara.channel, agoraPara.token)
  }
  // Subscribe when a remote user publishes a stream
  agoraClient.on('user-joined', async (user: IAgoraRTCRemoteUser) => {
    message.info('user[' + user.uid + '] join')
    message.info('用户[' + user.uid + '] 加入')
  })
  agoraClient.on('user-published', async (user: IAgoraRTCRemoteUser, mediaType: 'audio' | 'video') => {
    await agoraClient.subscribe(user, mediaType)
@@ -217,29 +218,23 @@
      // Get `RemoteVideoTrack` in the `user` object.
      const remoteVideoTrack = user.videoTrack!
      // Dynamically create a container in the form of a DIV element for playing the remote video track.
      const remotePlayerContainer: any = document.getElementById('player')
      remotePlayerContainer.id = user.uid.toString()
      remoteVideoTrack.play(remotePlayerContainer)
      remoteVideoTrack.play(document.getElementById('player') as HTMLElement)
    }
  })
  agoraClient.on('user-unpublished', async (user: any) => {
    console.log('unpublish live:', user)
    message.info('unpublish live')
    message.info('取消发布')
  })
  agoraClient.on('exception', async (e: any) => {
    console.log(e)
    message.error(e.msg)
  })
})
const handleError = (err: any) => {
  console.error(err)
}
const handleJoinChannel = (uid: any) => {
  agoraPara.uid = uid
}
const encodeToken = (e: any) => {
  agoraPara.token = encodeURIComponent(agoraPara.token)
}
const onStart = async () => {
  const that = this
@@ -262,8 +257,7 @@
  }
  agoraClient.setClientRole('audience', { level: 2 })
  if (agoraClient.connectionState === 'DISCONNECTED') {
    agoraClient
      .join(agoraPara.appid, agoraPara.channel, agoraPara.token)
    await agoraClient.join(agoraPara.appid, agoraPara.channel, agoraPara.token)
  }
  livePara.videoId =
    dronePara.droneSelected +
@@ -277,7 +271,7 @@
    '&sn=' +
    dronePara.droneSelected +
    '&token=' +
    agoraPara.token +
    encodeURIComponent(agoraPara.token) +
    '&uid=' +
    agoraPara.uid
@@ -298,6 +292,14 @@
    })
}
const onStop = async () => {
  if (
    dronePara.droneSelected == null ||
    dronePara.cameraSelected == null ||
    dronePara.claritySelected == null
  ) {
    message.warn('waring: not select live para!!!')
    return
  }
  livePara.videoId =
    dronePara.droneSelected +
    '/' +
@@ -308,10 +310,10 @@
  }).then(res => {
    if (res.code === 0) {
      message.success(res.message)
      livePara.liveState = false
      dronePara.lensSelected = ''
      console.log('stop play livestream')
    }
    livePara.liveState = false
    dronePara.lensSelected = ''
    console.log('stop play livestream')
  })
}
const onDroneSelect = (val: SelectOption) => {
@@ -350,7 +352,7 @@
  dronePara.videoSelected = firstVideo.value
  dronePara.lensList = firstVideo.more
  dronePara.lensSelected = firstVideo.label
  dronePara.isDockLive = dronePara.lensList.length > 0
  dronePara.isDockLive = dronePara.lensList?.length > 0
}
const onVideoSelect = (val: SelectOption) => {
  dronePara.videoSelected = val.value
@@ -362,7 +364,7 @@
}
const onUpdateQuality = () => {
  if (!livePara.liveState) {
    message.info('Please turn on the livestream first.')
    message.info('请先打开直播')
    return
  }
  setLivestreamQuality({
@@ -370,14 +372,14 @@
    video_quality: dronePara.claritySelected
  }).then(res => {
    if (res.code === 0) {
      message.success('Set the clarity to ' + clarityList[dronePara.claritySelected].label)
      message.success('将清晰度设置为 ' + clarityList[dronePara.claritySelected].label)
    }
  })
}
const onSwitch = () => {
  if (dronePara.lensSelected === undefined || dronePara.lensSelected === nonSwitchable) {
    message.info('The ' + nonSwitchable + ' lens cannot be switched, please select the lens to be switched.', 8)
    message.info('当前 ' + nonSwitchable + ' 镜头无法切换,请选择要切换的镜头', 8)
    return
  }
  changeLivestreamLens({
@@ -385,7 +387,7 @@
    video_type: dronePara.lensSelected
  }).then(res => {
    if (res.code === 0) {
      message.success('Switching live camera successfully.')
      message.success('切换实时摄像头成功')
    }
  })
}