3 changed files with 449 additions and 1 deletions
@ -0,0 +1,419 @@
@@ -0,0 +1,419 @@
|
||||
<template> |
||||
<div class="flex-column flex-justify-start flex-align-center"> |
||||
<video |
||||
:style="{ width: '100%', height: '100%' }" |
||||
id="video-webrtc" |
||||
ref="videowebrtc" |
||||
controls |
||||
class="mt20" |
||||
></video> |
||||
<p class="fz24">Live streaming source selection</p> |
||||
|
||||
<div class=""> |
||||
<template v-if="liveState && isDockLive"> |
||||
<span class="mr10">Lens:</span> |
||||
<a-radio-group v-model:value="lensSelected" button-style="solid"> |
||||
<a-radio-button v-for="lens in lensList" :key="lens" :value="lens">{{lens}}</a-radio-button> |
||||
</a-radio-group> |
||||
</template> |
||||
<template v-else> |
||||
<a-select |
||||
style="width: 100px" |
||||
placeholder="Select Live Type" |
||||
@select="onLiveTypeSelect" |
||||
v-model:value="livetypeSelected" |
||||
> |
||||
<a-select-option |
||||
v-for="item in liveTypeList" |
||||
:key="item.label" |
||||
:value="item.value" |
||||
> |
||||
{{ item.label }} |
||||
</a-select-option> |
||||
</a-select> |
||||
<a-select |
||||
class="ml10" |
||||
style="width:100px" |
||||
placeholder="Select Drone" |
||||
v-model:value="droneSelected" |
||||
> |
||||
<a-select-option |
||||
v-for="item in droneList" |
||||
:key="item.value" |
||||
:value="item.value" |
||||
@click="onDroneSelect(item)" |
||||
>{{ item.label }}</a-select-option |
||||
> |
||||
</a-select> |
||||
<a-select |
||||
class="ml10" |
||||
style="width:100px" |
||||
placeholder="Select Camera" |
||||
v-model:value="cameraSelected" |
||||
> |
||||
<a-select-option |
||||
v-for="item in cameraList" |
||||
:key="item.value" |
||||
:value="item.value" |
||||
@click="onCameraSelect(item)" |
||||
>{{ item.label }}</a-select-option |
||||
> |
||||
</a-select> |
||||
<!-- <a-select |
||||
class="ml10" |
||||
style="width:150px" |
||||
placeholder="Select Lens" |
||||
v-model:value="videoSelected" |
||||
> |
||||
<a-select-option |
||||
v-for="item in videoList" |
||||
:key="item.value" |
||||
:value="item.value" |
||||
@click="onVideoSelect(item)" |
||||
>{{ item.label }}</a-select-option |
||||
> |
||||
</a-select> --> |
||||
</template> |
||||
<a-select |
||||
class="ml10" |
||||
style="width:100px" |
||||
placeholder="Select Clarity" |
||||
@select="onClaritySelect" |
||||
v-model:value="claritySelected" |
||||
> |
||||
<a-select-option |
||||
v-for="item in clarityList" |
||||
:key="item.value" |
||||
:value="item.value" |
||||
>{{ item.label }}</a-select-option |
||||
> |
||||
</a-select> |
||||
</div> |
||||
<div class="mt20"> |
||||
<p class="fz10" v-if="livetypeSelected == 2"> |
||||
Please use VLC media player to play the RTSP livestream !!! |
||||
</p> |
||||
<p class="fz10" v-if="livetypeSelected == 2"> |
||||
RTSP Parameter:{{ rtspData }} |
||||
</p> |
||||
</div> |
||||
<div class="flex-row flex-justify-center flex-align-center" style="margin-bottom: 20px;"> |
||||
<a-button v-if="liveState && isDockLive" type="primary" large @click="onSwitch">Switch Lens</a-button> |
||||
<a-button v-else type="primary" large @click="onStart">Play</a-button> |
||||
<a-button class="ml20" type="primary" large @click="onStop" |
||||
>Stop</a-button |
||||
> |
||||
<!-- <a-button class="ml20" type="primary" large @click="onUpdateQuality" |
||||
>Update Clarity</a-button |
||||
> |
||||
<a-button v-if="!liveState || !isDockLive" class="ml20" type="primary" large @click="onRefresh" |
||||
>Refresh Live Capacity</a-button |
||||
> --> |
||||
</div> |
||||
</div> |
||||
</template> |
||||
|
||||
<script lang="ts" setup> |
||||
import { message } from 'ant-design-vue' |
||||
import { onMounted, reactive, ref } from 'vue' |
||||
import { CURRENT_CONFIG as config } from '/@/api/http/config' |
||||
import { changeLivestreamLens, getLiveCapacity, setLivestreamQuality, startLivestream, stopLivestream } from '/@/api/manage' |
||||
import { getRoot } from '/@/root' |
||||
import jswebrtc from '/@/vendors/jswebrtc.min.js' |
||||
const root = getRoot() |
||||
|
||||
interface SelectOption { |
||||
value: any, |
||||
label: string, |
||||
more?: any |
||||
} |
||||
|
||||
const liveTypeList: SelectOption[] = [ |
||||
{ |
||||
value: 1, |
||||
label: 'RTMP' |
||||
}, |
||||
{ |
||||
value: 2, |
||||
label: 'RTSP' |
||||
}, |
||||
{ |
||||
value: 3, |
||||
label: 'GB28181' |
||||
} |
||||
] |
||||
const clarityList: SelectOption[] = [ |
||||
{ |
||||
value: 0, |
||||
label: 'Adaptive' |
||||
}, |
||||
{ |
||||
value: 1, |
||||
label: 'Smooth' |
||||
}, |
||||
{ |
||||
value: 2, |
||||
label: 'Standard' |
||||
}, |
||||
{ |
||||
value: 3, |
||||
label: 'HD' |
||||
}, |
||||
{ |
||||
value: 4, |
||||
label: 'Super Clear' |
||||
} |
||||
] |
||||
|
||||
const videowebrtc = ref(null) |
||||
const livestreamSource = ref() |
||||
const droneList = ref() |
||||
const cameraList = ref() |
||||
const videoList = ref() |
||||
const droneSelected = ref() |
||||
const cameraSelected = ref() |
||||
const videoSelected = ref() |
||||
const claritySelected = ref() |
||||
const videoId = ref() |
||||
const liveState = ref<boolean>(false) |
||||
const livetypeSelected = ref() |
||||
const rtspData = ref() |
||||
const lensList = ref<string[]>([]) |
||||
const lensSelected = ref<String>() |
||||
const isDockLive = ref(false) |
||||
const nonSwitchable = 'normal' |
||||
|
||||
const onRefresh = async () => { |
||||
droneList.value = [] |
||||
cameraList.value = [] |
||||
videoList.value = [] |
||||
droneSelected.value = null |
||||
cameraSelected.value = null |
||||
videoSelected.value = null |
||||
await getLiveCapacity({}) |
||||
.then(res => { |
||||
console.log(res) |
||||
if (res.code === 0) { |
||||
if (res.data === null) { |
||||
console.warn('warning: get live capacity is null!!!') |
||||
return |
||||
} |
||||
const resData: Array<[]> = res.data |
||||
console.log('live_capacity:', resData) |
||||
livestreamSource.value = resData |
||||
|
||||
const temp: Array<SelectOption> = [] |
||||
if (livestreamSource.value) { |
||||
livestreamSource.value.forEach((ele: any) => { |
||||
temp.push({ label: ele.name + '-' + ele.sn, value: ele.sn, more: ele.cameras_list }) |
||||
}) |
||||
droneList.value = temp |
||||
} |
||||
} |
||||
}) |
||||
.catch(error => { |
||||
message.error(error) |
||||
console.error(error) |
||||
}) |
||||
} |
||||
|
||||
onMounted(() => { |
||||
onRefresh() |
||||
}) |
||||
const onStart = async () => { |
||||
console.log( |
||||
'Param:', |
||||
livetypeSelected.value, |
||||
droneSelected.value, |
||||
cameraSelected.value, |
||||
videoSelected.value, |
||||
claritySelected.value |
||||
) |
||||
const timestamp = new Date().getTime().toString() |
||||
if ( |
||||
livetypeSelected.value == null || |
||||
droneSelected.value == null || |
||||
cameraSelected.value == null || |
||||
claritySelected.value == null |
||||
) { |
||||
message.warn('waring: not select live para!!!') |
||||
return |
||||
} |
||||
videoId.value = |
||||
droneSelected.value + '/' + cameraSelected.value + '/' + (videoSelected.value || nonSwitchable + '-0') |
||||
|
||||
let liveURL = '' |
||||
switch (livetypeSelected.value) { |
||||
case 1: { |
||||
// RTMP |
||||
liveURL = config.rtmpURL + timestamp |
||||
break |
||||
} |
||||
case 2: { |
||||
// RTSP |
||||
liveURL = `userName=${config.rtspUserName}&password=${config.rtspPassword}&port=${config.rtspPort}` |
||||
break |
||||
} |
||||
case 3: { |
||||
liveURL = `serverIP=${config.gbServerIp}&serverPort=${config.gbServerPort}&serverID=${config.gbServerId}&agentID=${config.gbAgentId}&agentPassword=${config.gbPassword}&localPort=${config.gbAgentPort}&channel=${config.gbAgentChannel}` |
||||
break |
||||
} |
||||
default: |
||||
console.warn('warning: live type is not correct!!!') |
||||
break |
||||
} |
||||
await startLivestream({ |
||||
url: liveURL, |
||||
video_id: videoId.value, |
||||
url_type: livetypeSelected.value, |
||||
video_quality: claritySelected.value |
||||
}) |
||||
.then(res => { |
||||
if (res.code !== 0) { |
||||
return |
||||
} |
||||
if (livetypeSelected.value === 3) { |
||||
const url = res.data.url |
||||
const videoElement = videowebrtc.value |
||||
// gb28181,it will fail if not wait. |
||||
message.loading({ |
||||
content: 'Loding...', |
||||
duration: 4, |
||||
onClose () { |
||||
const player = new jswebrtc.Player(url, { |
||||
video: videoElement, |
||||
autoplay: true, |
||||
onPlay: (obj: any) => { |
||||
console.log('start play livestream') |
||||
} |
||||
}) |
||||
} |
||||
}) |
||||
} else if (livetypeSelected.value === 2) { |
||||
console.log(res) |
||||
rtspData.value = |
||||
'url:' + |
||||
res.data.url + |
||||
'&username:' + |
||||
res.data.username + |
||||
'&password:' + |
||||
res.data.password |
||||
} else if (livetypeSelected.value === 1) { |
||||
const url = res.data.url |
||||
const videoElement = videowebrtc.value |
||||
console.log('start live:', url) |
||||
console.log(videoElement) |
||||
const player = new jswebrtc.Player(url, { |
||||
video: videoElement, |
||||
autoplay: true, |
||||
onPlay: (obj: any) => { |
||||
console.log('start play livestream') |
||||
} |
||||
}) |
||||
} |
||||
liveState.value = true |
||||
}) |
||||
.catch(err => { |
||||
console.error(err) |
||||
}) |
||||
} |
||||
const onStop = () => { |
||||
videoId.value = |
||||
droneSelected.value + '/' + cameraSelected.value + '/' + (videoSelected.value || nonSwitchable + '-0') |
||||
|
||||
stopLivestream({ |
||||
video_id: videoId.value |
||||
}).then(res => { |
||||
if (res.code === 0) { |
||||
message.success(res.message) |
||||
liveState.value = false |
||||
lensSelected.value = undefined |
||||
console.log('stop play livestream') |
||||
} |
||||
}) |
||||
} |
||||
|
||||
const onUpdateQuality = () => { |
||||
if (!liveState.value) { |
||||
message.info('Please turn on the livestream first.') |
||||
return |
||||
} |
||||
setLivestreamQuality({ |
||||
video_id: videoId.value, |
||||
video_quality: claritySelected.value |
||||
}).then(res => { |
||||
if (res.code === 0) { |
||||
message.success('Set the clarity to ' + clarityList[claritySelected.value].label) |
||||
} |
||||
}) |
||||
} |
||||
|
||||
const onLiveTypeSelect = (val: any) => { |
||||
livetypeSelected.value = val |
||||
} |
||||
const onDroneSelect = (val: SelectOption) => { |
||||
droneSelected.value = val.value |
||||
const temp: Array<SelectOption> = [] |
||||
cameraList.value = [] |
||||
cameraSelected.value = undefined |
||||
videoSelected.value = undefined |
||||
videoList.value = [] |
||||
lensList.value = [] |
||||
if (!val.more) { |
||||
return |
||||
} |
||||
val.more.forEach((ele: any) => { |
||||
temp.push({ label: ele.name, value: ele.index, more: ele.videos_list }) |
||||
}) |
||||
cameraList.value = temp |
||||
} |
||||
const onCameraSelect = (val: SelectOption) => { |
||||
cameraSelected.value = val.value |
||||
const result: Array<SelectOption> = [] |
||||
videoSelected.value = undefined |
||||
videoList.value = [] |
||||
lensList.value = [] |
||||
if (!val.more) { |
||||
return |
||||
} |
||||
|
||||
val.more.forEach((ele: any) => { |
||||
result.push({ label: ele.type, value: ele.index, more: ele.switch_video_types }) |
||||
}) |
||||
videoList.value = result |
||||
if (videoList.value.length === 0) { |
||||
return |
||||
} |
||||
const firstVideo: SelectOption = videoList.value[0] |
||||
videoSelected.value = firstVideo.value |
||||
lensList.value = firstVideo.more |
||||
lensSelected.value = firstVideo.label |
||||
isDockLive.value = lensList.value?.length > 0 |
||||
} |
||||
const onVideoSelect = (val: SelectOption) => { |
||||
videoSelected.value = val.value |
||||
lensList.value = val.more |
||||
lensSelected.value = val.label |
||||
} |
||||
const onClaritySelect = (val: any) => { |
||||
claritySelected.value = val |
||||
} |
||||
const onSwitch = () => { |
||||
if (lensSelected.value === undefined || lensSelected.value === nonSwitchable) { |
||||
message.info('The ' + nonSwitchable + ' lens cannot be switched, please select the lens to be switched.', 8) |
||||
return |
||||
} |
||||
changeLivestreamLens({ |
||||
video_id: videoId.value, |
||||
video_type: lensSelected.value |
||||
}).then(res => { |
||||
if (res.code === 0) { |
||||
message.success('Switching live camera successfully.') |
||||
} |
||||
}) |
||||
} |
||||
</script> |
||||
|
||||
<style lang="scss" scoped> |
||||
@import '/@/styles/index.scss'; |
||||
</style> |
Loading…
Reference in new issue