From 4dccbb68399da2d46943b8d613585afb49aa5455 Mon Sep 17 00:00:00 2001
From: sean.zhou <sean.zhou@dji.com>
Date: Fri, 22 Jul 2022 20:48:54 +0800
Subject: [PATCH] V1.1.0 for dock
---
src/pages/page-pilot/pilot-liveshare.vue | 301 +++++++++++++++++++++++++++++++++++--------------
1 files changed, 214 insertions(+), 87 deletions(-)
diff --git a/src/pages/page-pilot/pilot-liveshare.vue b/src/pages/page-pilot/pilot-liveshare.vue
index da54d73..2c778a5 100644
--- a/src/pages/page-pilot/pilot-liveshare.vue
+++ b/src/pages/page-pilot/pilot-liveshare.vue
@@ -1,16 +1,17 @@
<template>
- <div
- class="width-100vw height-100vh flex-column flex-justify-start flex-align-start"
- >
+ <div class="width100 flex-column flex-justify-start flex-align-start" style="background-color: white;">
+
+ <p class="fz16 ml10 mt15 mb10 color-text-title color-font-bold" style="color: #939393">
+ Before starting manually, please select the publish mode and livestream type
+ </p>
<div
- class="mt20 flex-row flex-align-center flex-justify-between"
- style="width: 100%"
- >
+ class="mt15 flex-row flex-align-center flex-justify-between"
+ style="width: 100%;">
<p class="ml10 mb0 fz16" style="color: black">
Select Video Publish Mode:
</p>
<a-select
- style="width: 200px"
+ style="width: 200px; margin-right: 20px;"
placeholder="Select Mode"
@select="onPublishModeSelect"
>
@@ -24,16 +25,18 @@
</a-select>
</div>
- <a-divider dashed class="mt10 mb0"></a-divider>
-
+ <div class="ml10 mr10" style="width: 96%; margin-top: -10px;">
+ <a-divider />
+ </div>
<div
- class="flex-row flex-align-center flex-justify-between mt10"
- style="width: 100%"
+ class="flex-row flex-align-center flex-justify-between"
+ style="width: 100%; margin-top: -10px;"
>
- <p class="ml10 mb0 fz16" style="color: black">Select Live Share Type:</p>
+ <p class="ml10 mb0 fz16">Select Livestream Type:</p>
<a-select
- style="width: 200px"
+ style="width: 200px; margin-right: 20px;"
placeholder="Select Live Type"
+ :value="liveStreamStatus.type"
@select="onLiveTypeSelect"
>
<a-select-option
@@ -45,141 +48,265 @@
</a-select-option>
</a-select>
</div>
- <a-divider dashed class="mt10 mb0"></a-divider>
+ <div class="ml10 mr10" style="width: 96%; margin-top: -10px;">
+ <a-divider />
+ </div>
+ <div class="width-100" style="margin-top: -10px;">
+ <div class="ml10" style="width: 97%;">
+ <span class="fz16">Param: </span>
+ <span v-if="liveStreamStatus.type === ELiveTypeValue.Agora" style="word-break: break-all; color: #75c5f6;">{{ agoraParam }}</span>
+ <span v-else-if="liveStreamStatus.type === ELiveTypeValue.RTMP" style="word-break: break-all; color: #75c5f6;">{{ rtmpParam }}</span>
+ <span v-else-if="liveStreamStatus.type === ELiveTypeValue.RTSP" style="word-break: break-all; color: #75c5f6;">{{ rtspParam }}</span>
+ <span v-else-if="liveStreamStatus.type === ELiveTypeValue.GB28181" style="word-break: break-all; color: #75c5f6;">{{ gb28181Param }}</span>
+ <span v-else></span>
+ </div>
- <div
- class="flex-row flex-align-center flex-justify-center mt20"
- style="width: 100%"
- >
- <p>Live Share State: {{ liveState }}</p>
</div>
- <div
- class="flex-row flex-align-center flex-justify-center mt20"
- style="width: 100%"
- >
- <a-button type="primary" @click="onPlay">Play</a-button>
- <a-button class="ml20" type="primary" @click="onGetConfig"
- >Get Config</a-button
- >
- <a-button class="ml20" type="primary" @click="onGetStatus"
- >Get Status</a-button
- >
+ <div class="ml10 mr10" style="width: 96%; margin-top: -10px;">
+ <a-divider />
</div>
+ <div class="mb20 flex-row flex-align-center flex-justify-center"
+ style="width: 100%; ">
+ <a-button class="flex-column fz20 flex-align-center flex-justify-center" style="width: 100px;" type="ghost" @click="onPlay">Play</a-button>
+ <a-button class="flex-column fz20 flex-align-center flex-justify-center ml40" style="width: 100px;" type="ghost" @click="onStop">Stop</a-button>
+ </div>
+ <a-button v-if="playVisiable" class="flex-column flex-align-center" shape="circle" @click="showLivingStatus"
+ style="position: fixed; top: 13vh; left: 5vw; opacity: 0.8; background-color: rgb(0,0,0,0)">
+ <template #icon><CaretRightFilled style="font-size: 26px; color: " /></template>
+ </a-button>
+
+ <a-drawer placement="right" v-model:visible="drawerVisible" width="280px" :mask="false" @close="closeDrawer">
+ <div class="fz16 width-100">
+ <div class="mt20" style=" margin-bottom: -10px;">
+ <span class="fz20 flex-row flex-align-center flex-justify-center">
+ <font :color="liveState === EStatusValue.LIVING ? 'green' : liveState === EStatusValue.CONNECTED ? 'blue' : 'red'">{{ liveState }}</font></span>
+ </div>
+ <a-divider />
+ <div style=" margin-top: -10px; margin-bottom: -15px;">
+ <span>Frame Rate:</span><span style="float: right; color: #75c5f6;">{{ liveStreamStatus.fps }}<span v-if="liveStreamStatus.fps != -1"> fps</span></span><br/>
+ </div>
+ <a-divider />
+ <div style=" margin-top: -10px; margin-bottom: -10px;">
+ <span>Video Bit Rate:</span><span style="float: right; color: #75c5f6;">{{ liveStreamStatus.videoBitRate }}<span v-if="liveStreamStatus.videoBitRate != -1"> kbps</span></span><br/>
+ </div>
+ <a-divider />
+ <div style=" margin-top: -10px; margin-bottom: -10px;">
+ <span>Audio Bit Rate:</span><span style="float: right; color: #75c5f6;">{{ liveStreamStatus.audioBitRate }}<span v-if="liveStreamStatus.audioBitRate != -1"> kbps</span></span><br/>
+ </div>
+ <a-divider />
+ <div style=" margin-top: -10px; margin-bottom: -10px;">
+ <span>Packet Loss Rate:</span><span style="float: right; color: #75c5f6;">{{ liveStreamStatus.dropRate }}<span v-if="liveStreamStatus.dropRate != -1"> %</span></span><br/>
+ </div>
+ <a-divider />
+ <div style=" margin-top: -10px; margin-bottom: -10px;">
+ <span>RTT:</span><span style="float: right; color: #75c5f6;">{{ liveStreamStatus.rtt }}<span v-if="liveStreamStatus.rtt != -1"> ms</span></span><br/>
+ </div>
+ <a-divider />
+ <div style=" margin-top: -10px;">
+ <span >Jitter:</span><span style="float: right; color: #75c5f6;">{{ liveStreamStatus.jitter }}</span><br/>
+ </div>
+ </div>
+ </a-drawer>
</div>
</template>
<script lang="ts" setup>
import { message } from 'ant-design-vue'
-import { onMounted, ref } from 'vue'
-import { CURRENT_CONFIG as config } from '/@/api/http/config'
+import { onMounted, reactive, ref, UnwrapRef } from 'vue'
+import { CURRENT_CONFIG as config, CURRENT_CONFIG } from '/@/api/http/config'
+import { ELiveTypeName, ELiveTypeValue, GB28181Param, LiveConfigParam, LiveStreamStatus, RTSPParam, EVideoPublishType } from '/@/api/live-stream'
import apiPilot from '/@/api/pilot-bridge'
import { getRoot } from '/@/root'
+import { ELiveStatusValue, EStatusValue } from '/@/types'
+import { CaretRightFilled } from '@ant-design/icons-vue'
const root = getRoot()
const publishModeList = [
{
- value: 'video-on-demand',
- label: 'video-on-demand'
+ value: EVideoPublishType.VideoOnDemand,
+ label: EVideoPublishType.VideoOnDemand
},
{
- value: 'video-by-manual',
- label: 'video-by-manual'
+ value: EVideoPublishType.VideoByManual,
+ label: EVideoPublishType.VideoByManual
},
{
- value: 'video-demand-aux-manual',
- label: 'video-demand-aux-manual'
+ value: EVideoPublishType.VideoDemandAuxManual,
+ label: EVideoPublishType.VideoDemandAuxManual
}
]
const liveTypeList = [
{
- value: 1,
- label: 'AGORA'
+ value: ELiveTypeValue.Agora,
+ label: ELiveTypeName.Agora
},
{
- value: 2,
- label: 'RTMP'
+ value: ELiveTypeValue.RTMP,
+ label: ELiveTypeName.RTMP
},
{
- value: 3,
- label: 'RTSP'
+ value: ELiveTypeValue.RTSP,
+ label: ELiveTypeName.RTSP
},
{
- value: 4,
- label: 'GB28181'
+ value: ELiveTypeValue.GB28181,
+ label: ELiveTypeName.GB28181
}
]
const agoraParam = {
- uid: config.agoraAPPID,
+ uid: '2892130292',
token: config.agoraToken,
channelId: config.agoraChannel
}
const rtmpParam = {
- url: config.rtmpURL + '12345'
+ url: config.rtmpURL + new Date().getTime()
}
-const liveState = ref<string>('STOP')
-const livetypeSelected = ref<number>(1)
-const publishModeSelected = ref<string>('video-demand-aux-manual')
+const rtspParam: RTSPParam = {
+ userName: CURRENT_CONFIG.rtspUserName,
+ password: CURRENT_CONFIG.rtspPassword,
+ port: CURRENT_CONFIG.rtspPort
+}
+const gb28181Param: GB28181Param = {
+ serverIp: CURRENT_CONFIG.gbServerIp,
+ serverPort: CURRENT_CONFIG.gbServerPort,
+ serverId: CURRENT_CONFIG.gbServerId,
+ agentId: CURRENT_CONFIG.gbAgentId,
+ password: CURRENT_CONFIG.gbPassword,
+ agentPort: CURRENT_CONFIG.gbAgentPort,
+ agentChannel: CURRENT_CONFIG.gbAgentChannel
+}
+
+const playVisiable = ref(false)
+const drawerVisible = ref(false)
+const liveState = ref(EStatusValue.DISCONNECT)
+const liveTypeSelected = ref<string>()
+const publishModeSelected = ref<string>()
+const liveStreamStatus: LiveStreamStatus = reactive({
+ audioBitRate: -1,
+ dropRate: -1,
+ fps: -1,
+ jitter: -1,
+ quality: -1,
+ rtt: -1,
+ status: -1,
+ type: -1,
+ videoBitRate: -1
+})
onMounted(() => {
- const status: any = apiPilot.getLiveshareStatus()
- console.log(status)
- // liveState.value =
- // status.status === 0
- // ? 'Cannot connect to server'
- // : status.status === 1
- // ? 'Connect to server'
- // : 'Playing'
+ const config: LiveConfigParam = JSON.parse(apiPilot.getLiveshareConfig())
+ liveStreamStatus.type = config.type
+ refreshLiveType()
- // console.log(liveState.value)
+ window.liveStatusCallback = arg => {
+ liveStatusCallback(arg)
+ }
})
-const onLiveTypeSelect = (val: any) => {
- livetypeSelected.value = val
- message.info('set livetype:' + livetypeSelected.value, 5)
+
+const liveStatusCallback = async (arg: LiveStreamStatus) => {
+ liveStreamStatus.fps = arg.fps
+ liveStreamStatus.audioBitRate = arg.audioBitRate
+ liveStreamStatus.dropRate = arg.dropRate
+ liveStreamStatus.jitter = arg.jitter
+ liveStreamStatus.rtt = arg.rtt
+ liveStreamStatus.videoBitRate = arg.videoBitRate
+ liveStreamStatus.quality = arg.quality
+ liveStreamStatus.type = arg.type
+ liveStreamStatus.status = arg.status
+
+ switch (liveStreamStatus.status) {
+ case ELiveStatusValue.LIVING:
+ liveState.value = EStatusValue.LIVING
+ break
+ case ELiveStatusValue.CONNECTED:
+ liveState.value = EStatusValue.CONNECTED
+ break
+ default:
+ liveState.value = EStatusValue.DISCONNECT
+ }
+}
+function refreshLiveType () {
+ switch (liveStreamStatus.type) {
+ case ELiveTypeValue.Agora:
+ liveTypeSelected.value = ELiveTypeName.Agora
+ break
+ case ELiveTypeValue.RTMP:
+ liveTypeSelected.value = ELiveTypeName.RTMP
+ break
+ case ELiveTypeValue.RTSP:
+ liveTypeSelected.value = ELiveTypeName.RTSP
+ break
+ case ELiveTypeValue.GB28181:
+ liveTypeSelected.value = ELiveTypeName.GB28181
+ break
+ default:
+ liveTypeSelected.value = ELiveTypeName.Unknown
+ }
+}
+const onLiveTypeSelect = (val: number) => {
+ liveStreamStatus.type = val
+ refreshLiveType()
}
const onPublishModeSelect = (val: string) => {
publishModeSelected.value = val
- message.info(
- 'set publish mode res:' +
- apiPilot.setVideoPublishType(publishModeSelected.value),
- 5
- )
+ apiPilot.setVideoPublishType(publishModeSelected.value)
}
const onPlay = () => {
- switch (livetypeSelected.value) {
+ if (!publishModeSelected.value) {
+ message.warn('Please select publish mode!')
+ return
+ }
+ if (liveTypeSelected.value === ELiveTypeName.Unknown) {
+ message.warn('Please select livestream type!')
+ return
+ }
+ switch (liveStreamStatus.type) {
case 1: {
- message.info('agoraParam:' + JSON.stringify(agoraParam))
- apiPilot.setLiveshareConfig(1, JSON.stringify(agoraParam))
- apiPilot.startLiveshare()
+ apiPilot.setLiveshareConfig(ELiveTypeValue.Agora, JSON.stringify(agoraParam))
break
}
case 2: {
- message.info('rtmpParam:' + JSON.stringify(rtmpParam))
- apiPilot.setLiveshareConfig(2, JSON.stringify(rtmpParam))
- message.info(apiPilot.startLiveshare())
+ apiPilot.setLiveshareConfig(ELiveTypeValue.RTMP, JSON.stringify(rtmpParam))
break
}
case 3: {
- message.info('rtspParam:' + config.rtspPara)
- apiPilot.setLiveshareConfig(3, config.rtspPara)
- apiPilot.startLiveshare()
+ apiPilot.setLiveshareConfig(ELiveTypeValue.RTSP, JSON.stringify(rtspParam))
break
}
case 4: {
- message.info('gb28181Param:' + config.gb28181Para)
- apiPilot.setLiveshareConfig(4, config.gb28181Para)
- apiPilot.startLiveshare()
+ apiPilot.setLiveshareConfig(ELiveTypeValue.GB28181, JSON.stringify(gb28181Param))
break
}
}
+ const status = apiPilot.startLiveshare()
+ if (status) {
+ playVisiable.value = true
+ drawerVisible.value = true
+ message.success('success')
+ }
}
-const onGetStatus = () => {
- const status = apiPilot.getLiveshareStatus()
- message.info(status, 5)
+
+const showLivingStatus = () => {
+ drawerVisible.value = !drawerVisible.value
}
-const onGetConfig = () => {
- const status = apiPilot.getLiveshareConfig()
- message.info(status, 5)
+
+const onStop = () => {
+ const status = apiPilot.stopLiveshare()
+ if (status) {
+ message.success('success')
+ playVisiable.value = false
+ drawerVisible.value = false
+ setTimeout(() => {
+ let key: (keyof LiveStreamStatus)
+ for (key in liveStreamStatus) {
+ if (key === 'type') {
+ continue
+ }
+ liveStreamStatus[key] = -1
+ }
+ }, 2000)
+ }
}
</script>
--
Gitblit v1.9.3