mirror of
https://gitee.com/pan648540858/wvp-GB28181-pro.git
synced 2026-05-26 06:57:50 +08:00
重构播放器分享功能,为各处播放器增加播放器切换能力
This commit is contained in:
parent
a22ba288fc
commit
fac2195ace
@ -95,5 +95,4 @@ public class RegisterResponseProcessor extends SIPResponseProcessorAbstract {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -139,7 +139,7 @@ public class RtpServerServiceImpl implements IReceiveRtpServerService {
|
||||
ssrc = ssrcFactory.getPlaySsrc(mediaServer);
|
||||
}
|
||||
|
||||
String streamId = String.format("%08x", Long.parseLong(ssrc)).toLowerCase();
|
||||
String streamId = String.format("%08x", Long.parseLong(ssrc)).toUpperCase();
|
||||
String streamReplace = String.format("%s_%s", device.getDeviceId(), channel.getDeviceId());
|
||||
|
||||
int tcpMode = device.getStreamMode().equals("TCP-ACTIVE")? 2: (device.getStreamMode().equals("TCP-PASSIVE")? 1:0);
|
||||
@ -309,7 +309,7 @@ public class RtpServerServiceImpl implements IReceiveRtpServerService {
|
||||
// 收流超时
|
||||
// 关闭收流端口
|
||||
String closeStreamId = rtpServerParam.getMediaServer().isRtpEnable()
|
||||
? String.format("%08x", rtpServerParam.getSsrc()) : rtpServerParam.getStreamId();
|
||||
? String.format("%08x", rtpServerParam.getSsrc()).toUpperCase() : rtpServerParam.getStreamId();
|
||||
mediaServerService.closeRTPServer(rtpServerParam.getMediaServer(), rtpServerParam.getApp(), closeStreamId);
|
||||
subscribe.removeSubscribe(rtpHook);
|
||||
callback.run(InviteErrorCode.ERROR_FOR_STREAM_TIMEOUT.getCode(), InviteErrorCode.ERROR_FOR_STREAM_TIMEOUT.getMsg(), null);
|
||||
@ -324,8 +324,15 @@ public class RtpServerServiceImpl implements IReceiveRtpServerService {
|
||||
|
||||
int rtpServerPort;
|
||||
if (rtpServerParam.getMediaServer().isRtpEnable()) {
|
||||
String zlmStreamId = String.format("%08x", rtpServerParam.getSsrc());
|
||||
Long checkSsrc = rtpServerParam.isSsrcCheck() ? rtpServerParam.getSsrc() : 0L;
|
||||
String zlmStreamId;
|
||||
long checkSsrc;
|
||||
if (rtpServerParam.getSsrc() != null) {
|
||||
zlmStreamId = String.format("%08x", rtpServerParam.getSsrc()).toUpperCase();
|
||||
checkSsrc = rtpServerParam.isSsrcCheck() ? rtpServerParam.getSsrc() : 0L;
|
||||
}else {
|
||||
zlmStreamId = rtpServerParam.getStreamId();
|
||||
checkSsrc = 0L;
|
||||
}
|
||||
rtpServerPort = mediaServerService.createRTPServer(rtpServerParam.getMediaServer(), rtpServerParam.getApp(), zlmStreamId, checkSsrc, rtpServerParam.getPort(), rtpServerParam.isOnlyAuto(),
|
||||
rtpServerParam.isDisableAudio(), rtpServerParam.isReUsePort(), rtpServerParam.getTcpMode());
|
||||
} else {
|
||||
|
||||
@ -7,7 +7,7 @@ import getPageTitle from '@/utils/get-page-title'
|
||||
|
||||
NProgress.configure({ showSpinner: false }) // NProgress Configuration
|
||||
|
||||
const whiteList = ['/login'] // no redirect whitelist
|
||||
const whiteList = ['/login', '/play/share'] // no redirect whitelist
|
||||
|
||||
router.beforeEach(async(to, from, next) => {
|
||||
// start progress bar
|
||||
|
||||
@ -288,15 +288,10 @@ export const constantRoutes = [
|
||||
]
|
||||
},
|
||||
{
|
||||
path: '/play/wasm/:url',
|
||||
name: 'wasmPlayer',
|
||||
path: '/play/share',
|
||||
name: 'sharePlayer',
|
||||
hidden: true,
|
||||
component: () => import('@/views/common/jessibuca.vue')
|
||||
},
|
||||
{
|
||||
path: '/play/rtc/:url',
|
||||
name: 'rtcPlayer',
|
||||
component: () => import('@/views/common/rtcPlayer.vue')
|
||||
component: () => import('@/views/common/share.vue')
|
||||
},
|
||||
// 404 page must be placed at the end !!!
|
||||
{ path: '*', redirect: '/404', hidden: true }
|
||||
|
||||
@ -164,7 +164,6 @@
|
||||
<div v-else-if="playbackStreamInfo">
|
||||
<h265web
|
||||
ref="playbackPlayer"
|
||||
:video-url="playbackVideoUrl"
|
||||
:height="'400px'"
|
||||
:show-button="false"
|
||||
:has-audio="true"
|
||||
@ -315,6 +314,11 @@ export default {
|
||||
this.playbackVideoUrl = data['ws_flv']
|
||||
}
|
||||
this.playbackLoading = false
|
||||
this.$nextTick(() => {
|
||||
if (this.$refs.playbackPlayer) {
|
||||
this.$refs.playbackPlayer.play(this.playbackVideoUrl)
|
||||
}
|
||||
})
|
||||
}).catch(err => {
|
||||
this.playbackLoading = false
|
||||
this.playbackError = (err && err.msg) ? err.msg : '回放请求失败,请检查通道是否有该时段录像'
|
||||
|
||||
@ -60,7 +60,6 @@
|
||||
</div>
|
||||
<h265web
|
||||
ref="recordVideoPlayer"
|
||||
:video-url="videoUrl"
|
||||
:height="'calc(100vh - 250px)'"
|
||||
:show-button="false"
|
||||
:has-audio="true"
|
||||
@ -465,6 +464,11 @@ export default {
|
||||
this.streamInfo = data
|
||||
this.videoUrl = this.getUrlByStreamInfo()
|
||||
this.hasAudio = this.streamInfo.tracks && this.streamInfo.tracks.length > 1
|
||||
this.$nextTick(() => {
|
||||
if (this.$refs.recordVideoPlayer) {
|
||||
this.$refs.recordVideoPlayer.play(this.videoUrl)
|
||||
}
|
||||
})
|
||||
})
|
||||
}
|
||||
},
|
||||
|
||||
@ -1,19 +1,28 @@
|
||||
<template>
|
||||
<div id="cloudRecordPlayer" style="height: 100%">
|
||||
<div class="cloud-record-playBox" :style="playBoxStyle">
|
||||
<h265web v-if="playerType === 'H265web'" ref="recordVideoPlayer" :video-url="videoUrl" :height="'calc(100% - 250px)'" :show-button="false" @playTimeChange="showPlayTimeChange" @playStatusChange="playingChange"/>
|
||||
<jessibucaPlayer
|
||||
v-if="playerType === 'Jessibuca'"
|
||||
ref="recordVideoPlayer"
|
||||
:height="'calc(100% - 250px)'"
|
||||
:show-button="false"
|
||||
:video-url="videoUrl"
|
||||
@playTimeChange="showPlayTimeChange"
|
||||
@playStatusChange="playingChange"
|
||||
fluent
|
||||
autoplay
|
||||
live
|
||||
/>
|
||||
<rtcPlayer
|
||||
v-if="playerType === 'WebRTC'"
|
||||
ref="recordVideoPlayer"
|
||||
:has-audio="true"
|
||||
:show-controls="false"
|
||||
style="height: calc(100% - 250px)"
|
||||
autoplay
|
||||
@playTimeChange="showPlayTimeChange"
|
||||
@playStatusChange="playingChange"
|
||||
/>
|
||||
<h265web v-if="playerType === 'H265web'" ref="recordVideoPlayer" :height="'calc(100% - 250px)'" :show-button="false" @playTimeChange="showPlayTimeChange" @playStatusChange="playingChange"/>
|
||||
</div>
|
||||
<div class="cloud-record-player-option-box">
|
||||
<div class="cloud-record-show-time">
|
||||
@ -70,10 +79,11 @@
|
||||
<div class="cloud-record-record-play-control-item record-play-control-player">
|
||||
|
||||
<el-dropdown @command="changePlayerType" :popper-append-to-body='false' >
|
||||
<a target="_blank" class="cloud-record-record-play-control-item record-play-control-speed" title="选择播放器">{{ playerType }}</a>
|
||||
<a target="_blank" class="cloud-record-record-play-control-item record-play-control-speed" title="选择播放器">{{ playerLabel }}</a>
|
||||
<el-dropdown-menu slot="dropdown">
|
||||
<el-dropdown-item command="H265web" >H265web</el-dropdown-item>
|
||||
<el-dropdown-item command="Jessibuca" >Jessibuca</el-dropdown-item>
|
||||
<el-dropdown-item command="WebRTC" >WebRTC</el-dropdown-item>
|
||||
<el-dropdown-item command="H265web" >H265web</el-dropdown-item>
|
||||
</el-dropdown-menu>
|
||||
</el-dropdown>
|
||||
</div>
|
||||
@ -88,18 +98,18 @@
|
||||
<script>
|
||||
|
||||
import h265web from '../common/h265web.vue'
|
||||
import jessibucaPlayer from '@/views/common/jessibuca.vue'
|
||||
import rtcPlayer from '../common/rtcPlayer.vue'
|
||||
import moment from 'moment'
|
||||
import momentDurationFormatSetup from 'moment-duration-format'
|
||||
import screenfull from 'screenfull'
|
||||
import jessibucaPlayer from '@/views/common/jessibuca.vue'
|
||||
|
||||
momentDurationFormatSetup(moment)
|
||||
|
||||
export default {
|
||||
name: 'CloudRecordPlayer',
|
||||
components: {
|
||||
jessibucaPlayer,
|
||||
h265web
|
||||
jessibucaPlayer, rtcPlayer, h265web
|
||||
},
|
||||
props: ['showListCallback', 'showNextCallback', 'showLastCallback', 'lastDiable', 'nextDiable'],
|
||||
data() {
|
||||
@ -119,6 +129,11 @@ export default {
|
||||
playing: false,
|
||||
initTime: null,
|
||||
playerType: 'Jessibuca',
|
||||
playerUrls: {
|
||||
Jessibuca: ['ws_flv', 'wss_flv'],
|
||||
WebRTC: ['rtc', 'rtcs'],
|
||||
H265web: ['ws_flv', 'wss_flv']
|
||||
},
|
||||
playSpeedRange: [1, 2, 4, 6, 8, 16, 20]
|
||||
}
|
||||
},
|
||||
@ -157,6 +172,10 @@ export default {
|
||||
}else {
|
||||
return ''
|
||||
}
|
||||
},
|
||||
playerLabel() {
|
||||
const labels = { Jessibuca: 'Jessibuca', WebRTC: 'WebRTC', H265web: 'H265Web' }
|
||||
return labels[this.playerType] || 'Jessibuca'
|
||||
}
|
||||
},
|
||||
created() {
|
||||
@ -168,9 +187,6 @@ export default {
|
||||
this.$destroy('recordVideoPlayer')
|
||||
},
|
||||
methods: {
|
||||
changePlayer(command) {
|
||||
this.playerType = command
|
||||
},
|
||||
timeProcessMouseup(event) {
|
||||
this.isMousedown = false
|
||||
},
|
||||
@ -228,21 +244,15 @@ export default {
|
||||
if (this.playerType === playerType) {
|
||||
return
|
||||
}
|
||||
let streamInfo = this.streamInfo
|
||||
let videoUrl = this.videoUrl
|
||||
this.$refs.recordVideoPlayer.destroy()
|
||||
this.seekRecord(0, () => {
|
||||
this.playerType = playerType
|
||||
if (this.streamInfo) {
|
||||
this.videoUrl = this.getUrlByStreamInfo()
|
||||
this.$nextTick(() => {
|
||||
setTimeout(() => {
|
||||
this.playerType = playerType
|
||||
this.playerTime = 0
|
||||
this.streamInfo = streamInfo
|
||||
this.videoUrl = videoUrl
|
||||
}, 1000)
|
||||
|
||||
if (this.$refs.recordVideoPlayer) {
|
||||
this.$refs.recordVideoPlayer.play(this.videoUrl)
|
||||
}
|
||||
})
|
||||
})
|
||||
|
||||
}
|
||||
},
|
||||
seekBackward() {
|
||||
// 快退五秒
|
||||
@ -290,15 +300,31 @@ export default {
|
||||
this.isFullScreen = true
|
||||
},
|
||||
setStreamInfo(streamInfo, timeLen, startTime) {
|
||||
const keys = this.playerUrls[this.playerType]
|
||||
if (location.protocol === 'https:') {
|
||||
this.videoUrl = streamInfo['wss_flv']
|
||||
this.videoUrl = streamInfo[keys[1]]
|
||||
} else {
|
||||
this.videoUrl = streamInfo['ws_flv']
|
||||
this.videoUrl = streamInfo[keys[0]]
|
||||
}
|
||||
console.log(location.protocol)
|
||||
this.streamInfo = streamInfo
|
||||
this.timeLen = timeLen
|
||||
this.startTime = startTime
|
||||
this.$nextTick(() => {
|
||||
if (this.$refs.recordVideoPlayer) {
|
||||
this.$refs.recordVideoPlayer.play(this.videoUrl)
|
||||
}
|
||||
})
|
||||
},
|
||||
getUrlByStreamInfo() {
|
||||
if (!this.streamInfo) return ''
|
||||
const keys = this.playerUrls[this.playerType]
|
||||
if (location.protocol === 'https:') {
|
||||
this.videoUrl = this.streamInfo[keys[1]]
|
||||
} else {
|
||||
this.videoUrl = this.streamInfo[keys[0]]
|
||||
}
|
||||
return this.videoUrl
|
||||
},
|
||||
seekRecord(playSeekValue, callback) {
|
||||
this.$store.dispatch('cloudRecord/seek', {
|
||||
|
||||
@ -23,7 +23,6 @@
|
||||
v-if="activePlayer === 'jessibuca'"
|
||||
ref="jessibuca"
|
||||
:visible.sync="showVideoDialog"
|
||||
:video-url="videoUrl"
|
||||
:error="videoError"
|
||||
:message="videoError"
|
||||
:has-audio="hasAudio"
|
||||
@ -37,7 +36,6 @@
|
||||
v-if="activePlayer === 'webRTC'"
|
||||
ref="webRTC"
|
||||
:visible.sync="showVideoDialog"
|
||||
:video-url="videoUrl"
|
||||
:error="videoError"
|
||||
:message="videoError"
|
||||
height="100px"
|
||||
@ -51,7 +49,6 @@
|
||||
<h265web
|
||||
v-if="activePlayer === 'h265web'"
|
||||
ref="h265web"
|
||||
:video-url="videoUrl"
|
||||
:error="videoError"
|
||||
:message="videoError"
|
||||
:has-audio="hasAudio"
|
||||
@ -67,7 +64,6 @@
|
||||
v-if="Object.keys(this.player).length == 1 && this.player.jessibuca"
|
||||
ref="jessibuca"
|
||||
:visible.sync="showVideoDialog"
|
||||
:video-url="videoUrl"
|
||||
:error="videoError"
|
||||
:message="videoError"
|
||||
:has-audio="hasAudio"
|
||||
@ -77,9 +73,8 @@
|
||||
/>
|
||||
<rtc-player
|
||||
v-if="Object.keys(this.player).length == 1 && this.player.webRTC"
|
||||
ref="jessibuca"
|
||||
ref="rtcPlayer"
|
||||
:visible.sync="showVideoDialog"
|
||||
:video-url="videoUrl"
|
||||
:error="videoError"
|
||||
:message="videoError"
|
||||
height="100px"
|
||||
@ -90,9 +85,8 @@
|
||||
/>
|
||||
<h265web
|
||||
v-if="Object.keys(this.player).length == 1 && this.player.h265web"
|
||||
ref="jessibuca"
|
||||
ref="h265web"
|
||||
:visible.sync="showVideoDialog"
|
||||
:video-url="videoUrl"
|
||||
:error="videoError"
|
||||
:message="videoError"
|
||||
height="100px"
|
||||
@ -430,9 +424,12 @@ export default {
|
||||
},
|
||||
computed: {
|
||||
getPlayerShared: function() {
|
||||
const typeMap = { jessibuca: 0, webRTC: 1, h265web: 2 }
|
||||
const type = typeMap[this.activePlayer] || 0
|
||||
const baseUrl = window.location.origin + '/#/play/share?type=' + type + '&url=' + encodeURIComponent(this.videoUrl)
|
||||
return {
|
||||
sharedUrl: window.location.origin + '/#/play/wasm/' + encodeURIComponent(this.videoUrl),
|
||||
sharedIframe: '' + window.location.origin + '<iframe src="/public#/play/wasm/"></iframe>' + encodeURIComponent(this.videoUrl) + '',
|
||||
sharedUrl: baseUrl,
|
||||
sharedIframe: '<iframe src="' + baseUrl + '"></iframe>',
|
||||
sharedRtmp: this.videoUrl
|
||||
}
|
||||
}
|
||||
|
||||
@ -7,21 +7,21 @@
|
||||
v-if="Object.keys(this.player).length > 1">
|
||||
<el-tab-pane label="Jessibuca" name="jessibuca">
|
||||
<jessibucaPlayer v-if="activePlayer === 'jessibuca'" ref="jessibuca" :visible.sync="showVideoDialog"
|
||||
:videoUrl="videoUrl" :error="videoError" :message="videoError"
|
||||
:error="videoError" :message="videoError"
|
||||
:hasAudio="hasAudio" fluent autoplay live></jessibucaPlayer>
|
||||
</el-tab-pane>
|
||||
<el-tab-pane label="WebRTC" name="webRTC">
|
||||
<rtc-player v-if="activePlayer === 'webRTC'" ref="webRTC" :visible.sync="showVideoDialog"
|
||||
:videoUrl="videoUrl" :error="videoError" :message="videoError" height="100px"
|
||||
:error="videoError" :message="videoError" height="100px"
|
||||
:hasAudio="hasAudio" fluent autoplay live></rtc-player>
|
||||
</el-tab-pane>
|
||||
<el-tab-pane label="h265web">h265web敬请期待</el-tab-pane>
|
||||
</el-tabs>
|
||||
<jessibucaPlayer v-if="Object.keys(this.player).length == 1 && this.player.jessibuca" ref="jessibuca"
|
||||
:visible.sync="showVideoDialog" :videoUrl="videoUrl" :error="videoError" :message="videoError"
|
||||
:visible.sync="showVideoDialog" :error="videoError" :message="videoError"
|
||||
:hasAudio="hasAudio" fluent autoplay live></jessibucaPlayer>
|
||||
<rtc-player v-if="Object.keys(this.player).length == 1 && this.player.webRTC" ref="jessibuca"
|
||||
:visible.sync="showVideoDialog" :videoUrl="videoUrl" :error="videoError" :message="videoError"
|
||||
:visible.sync="showVideoDialog" :error="videoError" :message="videoError"
|
||||
height="100px" :hasAudio="hasAudio" fluent autoplay live></rtc-player>
|
||||
|
||||
</div>
|
||||
@ -266,9 +266,12 @@ export default {
|
||||
},
|
||||
computed: {
|
||||
getPlayerShared: function () {
|
||||
const typeMap = { jessibuca: 0, webRTC: 1, h265web: 2 }
|
||||
const type = typeMap[this.activePlayer] || 0
|
||||
const baseUrl = window.location.origin + '/#/play/share?type=' + type + '&url=' + encodeURIComponent(this.videoUrl)
|
||||
return {
|
||||
sharedUrl: window.location.origin + '/#/play/wasm/' + encodeURIComponent(this.videoUrl),
|
||||
sharedIframe: '<iframe src="' + window.location.origin + '/#/play/wasm/' + encodeURIComponent(this.videoUrl) + '"></iframe>',
|
||||
sharedUrl: baseUrl,
|
||||
sharedIframe: '<iframe src="' + baseUrl + '"></iframe>',
|
||||
sharedRtmp: this.videoUrl
|
||||
};
|
||||
}
|
||||
@ -359,6 +362,13 @@ export default {
|
||||
this.activePlayer = tab.name;
|
||||
this.videoUrl = this.getUrlByStreamInfo()
|
||||
console.log(this.videoUrl)
|
||||
if (this.$refs[this.activePlayer]) {
|
||||
this.$refs[this.activePlayer].play(this.videoUrl)
|
||||
} else {
|
||||
this.$nextTick(() => {
|
||||
this.$refs[this.activePlayer].play(this.videoUrl)
|
||||
})
|
||||
}
|
||||
},
|
||||
openDialog: function (tab, deviceId, channelId, param) {
|
||||
if (this.showVideoDialog) {
|
||||
|
||||
@ -64,32 +64,14 @@ export default {
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
videoUrl(newData, oldData) {
|
||||
this.play(newData)
|
||||
},
|
||||
playing(newData, oldData) {
|
||||
this.$emit('playStatusChange', newData)
|
||||
},
|
||||
immediate: true
|
||||
},
|
||||
mounted() {
|
||||
const paramUrl = decodeURIComponent(this.$route.params.url)
|
||||
window.onresize = () => {
|
||||
this.updatePlayerDomSize()
|
||||
}
|
||||
this.btnDom = document.getElementById('buttonsBox')
|
||||
console.log('初始化时的地址为: ' + paramUrl)
|
||||
if (paramUrl) {
|
||||
this.play(this.videoUrl)
|
||||
}
|
||||
},
|
||||
mounted() {},
|
||||
destroyed() {
|
||||
if (h265webPlayer[this._uid]) {
|
||||
h265webPlayer[this._uid].destroy()
|
||||
}
|
||||
this.playing = false
|
||||
this.loaded = false
|
||||
this.playerLoading = false
|
||||
this.destroy()
|
||||
},
|
||||
methods: {
|
||||
updatePlayerDomSize() {
|
||||
@ -244,6 +226,9 @@ export default {
|
||||
this.playing = false
|
||||
this.err = ''
|
||||
},
|
||||
stop: function() {
|
||||
this.destroy()
|
||||
},
|
||||
fullscreenSwich: function() {
|
||||
const isFull = this.isFullscreen()
|
||||
if (isFull) {
|
||||
|
||||
@ -50,38 +50,14 @@ export default {
|
||||
playerTime: 0,
|
||||
rotate: 0,
|
||||
vod: true, // 点播
|
||||
forceNoOffscreen: false
|
||||
forceNoOffscreen: false,
|
||||
localVideoUrl: this.videoUrl
|
||||
}
|
||||
},
|
||||
created() {
|
||||
if (this.$route.params.url) {
|
||||
const paramUrl = decodeURIComponent(this.$route.params.url)
|
||||
console.log(paramUrl)
|
||||
if (!this.videoUrl) {
|
||||
this.videoUrl = paramUrl
|
||||
}
|
||||
}
|
||||
this.btnDom = document.getElementById('buttonsBox')
|
||||
},
|
||||
mounted() {
|
||||
if (this.videoUrl) {
|
||||
this.$nextTick(() => {
|
||||
this.play(this.videoUrl)
|
||||
})
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
videoUrl: {
|
||||
handler(newVal) {
|
||||
if (newVal) {
|
||||
this.$nextTick(() => {
|
||||
this.play(newVal)
|
||||
})
|
||||
}
|
||||
},
|
||||
immediate: false
|
||||
}
|
||||
},
|
||||
mounted() {},
|
||||
destroyed() {
|
||||
if (jessibucaPlayer[this._uid]) {
|
||||
jessibucaPlayer[this._uid].videoPTS = 0
|
||||
@ -223,7 +199,10 @@ export default {
|
||||
console.warn('Jessibuca -> invalid url, skip play')
|
||||
return
|
||||
}
|
||||
this.videoUrl = url
|
||||
if (this.playing) {
|
||||
this.stop()
|
||||
}
|
||||
this.localVideoUrl = url
|
||||
console.log('Jessibuca -> url: ', url)
|
||||
if (!jessibucaPlayer[this._uid]) {
|
||||
this.create()
|
||||
|
||||
@ -12,7 +12,7 @@ export default {
|
||||
name: 'RtcPlayer',
|
||||
props: {
|
||||
videoUrl: { type: String, default: '' },
|
||||
error: { type: String, default: '' },
|
||||
error: { default: '' },
|
||||
hasaudio: { type: Boolean, default: false },
|
||||
showControls: { type: Boolean, default: true }
|
||||
},
|
||||
@ -21,28 +21,16 @@ export default {
|
||||
timer: null
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
videoUrl(newData, oldData) {
|
||||
this.pause()
|
||||
this.play(newData)
|
||||
},
|
||||
immediate: true
|
||||
},
|
||||
mounted() {
|
||||
const paramUrl = decodeURIComponent(this.$route.params.url)
|
||||
this.$nextTick(() => {
|
||||
if (typeof (this.videoUrl) === 'undefined') {
|
||||
this.videoUrl = paramUrl
|
||||
}
|
||||
console.log('初始化时的地址为: ' + this.videoUrl)
|
||||
this.play(this.videoUrl)
|
||||
})
|
||||
},
|
||||
|
||||
mounted() {},
|
||||
destroyed() {
|
||||
clearTimeout(this.timer)
|
||||
},
|
||||
methods: {
|
||||
play: function(url) {
|
||||
if (webrtcPlayer != null) {
|
||||
this.pause()
|
||||
}
|
||||
webrtcPlayer = new ZLMRTCClient.Endpoint({
|
||||
element: document.getElementById('webRtcPlayerBox'), // video 标签
|
||||
debug: true, // 是否打印日志
|
||||
@ -87,6 +75,9 @@ export default {
|
||||
webrtcPlayer = null
|
||||
}
|
||||
},
|
||||
stop: function() {
|
||||
this.pause()
|
||||
},
|
||||
eventcallbacK: function(type, message) {
|
||||
console.log('player 事件回调')
|
||||
console.log(type)
|
||||
|
||||
54
web/src/views/common/share.vue
Normal file
54
web/src/views/common/share.vue
Normal file
@ -0,0 +1,54 @@
|
||||
<template>
|
||||
<div style="width: 100vw; height: 100vh; background-color: #000; overflow: hidden;">
|
||||
<jessibucaPlayer
|
||||
v-if="playerType === 0"
|
||||
ref="player"
|
||||
:show-button="true"
|
||||
style="width: 100%; height: 100%"
|
||||
/>
|
||||
<rtc-player
|
||||
v-if="playerType === 1"
|
||||
ref="player"
|
||||
:show-controls="true"
|
||||
style="width: 100%; height: 100%"
|
||||
/>
|
||||
<h265web
|
||||
v-if="playerType === 2"
|
||||
ref="player"
|
||||
:show-button="true"
|
||||
style="width: 100%; height: 100%"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import jessibucaPlayer from './jessibuca.vue'
|
||||
import rtcPlayer from './rtcPlayer.vue'
|
||||
import h265web from './h265web.vue'
|
||||
|
||||
export default {
|
||||
name: 'SharePlayer',
|
||||
components: { jessibucaPlayer, rtcPlayer, h265web },
|
||||
data() {
|
||||
return {
|
||||
playerType: 0
|
||||
}
|
||||
},
|
||||
created() {
|
||||
const type = parseInt(this.$route.query.type)
|
||||
if (!isNaN(type) && type >= 0 && type <= 2) {
|
||||
this.playerType = type
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
const url = this.$route.query.url
|
||||
if (url) {
|
||||
this.$nextTick(() => {
|
||||
if (this.$refs.player) {
|
||||
this.$refs.player.play(decodeURIComponent(url))
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
@ -71,7 +71,6 @@
|
||||
<rtcPlayer
|
||||
v-if="activePlayer === 'webRTC'"
|
||||
ref="recordVideoPlayer"
|
||||
:video-url="videoUrl"
|
||||
:has-audio="true"
|
||||
:show-controls="false"
|
||||
style="height: calc(100vh - 220px)"
|
||||
@ -82,7 +81,6 @@
|
||||
<h265web
|
||||
v-if="activePlayer === 'h265web'"
|
||||
ref="recordVideoPlayer"
|
||||
:video-url="videoUrl"
|
||||
:height="'calc(100vh - 220px)'"
|
||||
:show-button="false"
|
||||
:has-audio="true"
|
||||
|
||||
@ -41,7 +41,6 @@
|
||||
v-if="activePlayer === 'webRTC'"
|
||||
ref="webRTC"
|
||||
:visible.sync="showVideoDialog"
|
||||
:video-url="videoUrl"
|
||||
:error="videoError"
|
||||
:message="videoError"
|
||||
height="100px"
|
||||
@ -55,7 +54,6 @@
|
||||
<h265web
|
||||
v-if="activePlayer === 'h265web'"
|
||||
ref="h265web"
|
||||
:video-url="videoUrl"
|
||||
:error="videoError"
|
||||
:message="videoError"
|
||||
:has-audio="hasAudio"
|
||||
@ -397,9 +395,12 @@ export default {
|
||||
},
|
||||
computed: {
|
||||
getPlayerShared: function() {
|
||||
const typeMap = { jessibuca: 0, webRTC: 1, h265web: 2 }
|
||||
const type = typeMap[this.activePlayer] || 0
|
||||
const baseUrl = window.location.origin + '/#/play/share?type=' + type + '&url=' + encodeURIComponent(this.videoUrl)
|
||||
return {
|
||||
sharedUrl: window.location.origin + '/#/play/wasm/' + encodeURIComponent(this.videoUrl),
|
||||
sharedIframe: '<iframe src="' + window.location.origin + '/#/play/wasm/' + encodeURIComponent(this.videoUrl) + '"></iframe>',
|
||||
sharedUrl: baseUrl,
|
||||
sharedIframe: '<iframe src="' + baseUrl + '"></iframe>',
|
||||
sharedRtmp: this.videoUrl
|
||||
}
|
||||
}
|
||||
|
||||
@ -52,9 +52,29 @@
|
||||
<div class="el-icon-loading" />
|
||||
<div style="width: 100%; line-height: 2rem">正在加载</div>
|
||||
</div>
|
||||
<h265web
|
||||
<jessibucaPlayer
|
||||
v-if="activePlayer === 'jessibuca'"
|
||||
ref="recordVideoPlayer"
|
||||
:has-audio="true"
|
||||
:height="'calc(100vh - 250px)'"
|
||||
:show-button="false"
|
||||
autoplay
|
||||
@playStatusChange="playingChange"
|
||||
@playTimeChange="showPlayTimeChange"
|
||||
/>
|
||||
<rtcPlayer
|
||||
v-if="activePlayer === 'webRTC'"
|
||||
ref="recordVideoPlayer"
|
||||
:has-audio="true"
|
||||
:show-controls="false"
|
||||
style="height: calc(100vh - 250px)"
|
||||
autoplay
|
||||
@playStatusChange="playingChange"
|
||||
@playTimeChange="showPlayTimeChange"
|
||||
/>
|
||||
<h265web
|
||||
v-if="activePlayer === 'h265web'"
|
||||
ref="recordVideoPlayer"
|
||||
:video-url="videoUrl"
|
||||
:height="'calc(100vh - 250px)'"
|
||||
:show-button="false"
|
||||
:has-audio="true"
|
||||
@ -176,6 +196,18 @@
|
||||
</div>
|
||||
<div style="text-align: right;">
|
||||
<div class="record-play-control" style="background-color: transparent; box-shadow: 0 0 10px transparent">
|
||||
<el-dropdown @command="changePlayer">
|
||||
<a
|
||||
target="_blank"
|
||||
class="record-play-control-item record-play-control-speed"
|
||||
title="切换播放器"
|
||||
>{{ playerLabel }}</a>
|
||||
<el-dropdown-menu slot="dropdown">
|
||||
<el-dropdown-item command="jessibuca">Jessibuca</el-dropdown-item>
|
||||
<el-dropdown-item command="webRTC">WebRTC</el-dropdown-item>
|
||||
<el-dropdown-item command="h265web">H265Web</el-dropdown-item>
|
||||
</el-dropdown-menu>
|
||||
</el-dropdown>
|
||||
<a
|
||||
v-if="!isFullScreen"
|
||||
target="_blank"
|
||||
@ -203,6 +235,8 @@
|
||||
<script>
|
||||
|
||||
import h265web from '../../common/h265web.vue'
|
||||
import jessibucaPlayer from '../../common/jessibuca.vue'
|
||||
import rtcPlayer from '../../common/rtcPlayer.vue'
|
||||
import VideoTimeline from '../../common/VideoTimeLine/index.vue'
|
||||
import recordDownload from '../../dialog/recordDownload.vue'
|
||||
import ChooseTimeRange from '../../dialog/chooseTimeRange.vue'
|
||||
@ -212,7 +246,7 @@ import screenfull from 'screenfull'
|
||||
export default {
|
||||
name: 'DeviceRecord',
|
||||
components: {
|
||||
h265web, VideoTimeline, recordDownload, ChooseTimeRange
|
||||
h265web, jessibucaPlayer, rtcPlayer, VideoTimeline, recordDownload, ChooseTimeRange
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
@ -225,6 +259,7 @@ export default {
|
||||
detailFiles: [],
|
||||
videoUrl: null,
|
||||
streamInfo: null,
|
||||
streamId: '',
|
||||
loading: false,
|
||||
chooseDate: null,
|
||||
playTime: null,
|
||||
@ -246,6 +281,12 @@ export default {
|
||||
timelineControl: false,
|
||||
showOtherSpeed: true,
|
||||
timeSegments: [],
|
||||
activePlayer: 'jessibuca',
|
||||
playerUrls: {
|
||||
jessibuca: ['ws_flv', 'wss_flv'],
|
||||
webRTC: ['rtc', 'rtcs'],
|
||||
h265web: ['ws_flv', 'wss_flv']
|
||||
},
|
||||
pickerOptions: {
|
||||
cellClassName: (date) => {
|
||||
// 通过显示一个点标识这一天有录像
|
||||
@ -260,6 +301,10 @@ export default {
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
playerLabel() {
|
||||
const labels = { jessibuca: 'Jessibuca', webRTC: 'WebRTC', h265web: 'H265Web' }
|
||||
return labels[this.activePlayer] || 'Jessibuca'
|
||||
},
|
||||
boxStyle() {
|
||||
if (this.showSidebar) {
|
||||
return {
|
||||
@ -293,6 +338,18 @@ export default {
|
||||
window.removeEventListener('beforeunload', this.stopPlayRecord)
|
||||
},
|
||||
methods: {
|
||||
changePlayer(player) {
|
||||
if (this.activePlayer === player) return
|
||||
this.activePlayer = player
|
||||
if (this.streamInfo) {
|
||||
this.videoUrl = this.getUrlByStreamInfo()
|
||||
this.$nextTick(() => {
|
||||
if (this.$refs.recordVideoPlayer) {
|
||||
this.$refs.recordVideoPlayer.play(this.videoUrl)
|
||||
}
|
||||
})
|
||||
}
|
||||
},
|
||||
sidebarControl() {
|
||||
this.showSidebar = !this.showSidebar
|
||||
},
|
||||
@ -438,16 +495,23 @@ export default {
|
||||
})
|
||||
.then((data) => {
|
||||
this.streamInfo = data
|
||||
this.streamId = data.stream
|
||||
this.videoUrl = this.getUrlByStreamInfo()
|
||||
this.hasAudio = this.streamInfo.tracks && this.streamInfo.tracks.length > 1
|
||||
this.$nextTick(() => {
|
||||
if (this.$refs.recordVideoPlayer) {
|
||||
this.$refs.recordVideoPlayer.play(this.videoUrl)
|
||||
}
|
||||
})
|
||||
})
|
||||
}
|
||||
},
|
||||
getUrlByStreamInfo() {
|
||||
const keys = this.playerUrls[this.activePlayer]
|
||||
if (location.protocol === 'https:') {
|
||||
this.videoUrl = this.streamInfo['wss_flv']
|
||||
this.videoUrl = this.streamInfo[keys[1]]
|
||||
} else {
|
||||
this.videoUrl = this.streamInfo['ws_flv']
|
||||
this.videoUrl = this.streamInfo[keys[0]]
|
||||
}
|
||||
return this.videoUrl
|
||||
},
|
||||
|
||||
@ -20,10 +20,10 @@
|
||||
>
|
||||
<el-tab-pane label="Jessibuca" name="jessibuca">
|
||||
<jessibucaPlayer
|
||||
style="min-height: 22.5vw"
|
||||
v-if="activePlayer === 'jessibuca'"
|
||||
ref="jessibuca"
|
||||
:visible.sync="showVideoDialog"
|
||||
:video-url="videoUrl"
|
||||
:error="videoError"
|
||||
:message="videoError"
|
||||
:has-audio="hasAudio"
|
||||
@ -37,7 +37,6 @@
|
||||
v-if="activePlayer === 'webRTC'"
|
||||
ref="webRTC"
|
||||
:visible.sync="showVideoDialog"
|
||||
:video-url="videoUrl"
|
||||
:error="videoError"
|
||||
:message="videoError"
|
||||
height="100px"
|
||||
@ -51,7 +50,6 @@
|
||||
<h265web
|
||||
v-if="activePlayer === 'h265web'"
|
||||
ref="h265web"
|
||||
:video-url="videoUrl"
|
||||
:error="videoError"
|
||||
:message="videoError"
|
||||
:has-audio="hasAudio"
|
||||
@ -63,44 +61,6 @@
|
||||
|
||||
</el-tab-pane>
|
||||
</el-tabs>
|
||||
<jessibucaPlayer
|
||||
v-if="Object.keys(this.player).length == 1 && this.player.jessibuca"
|
||||
ref="jessibuca"
|
||||
:visible.sync="showVideoDialog"
|
||||
:video-url="videoUrl"
|
||||
:error="videoError"
|
||||
:message="videoError"
|
||||
:has-audio="hasAudio"
|
||||
fluent
|
||||
autoplay
|
||||
live
|
||||
/>
|
||||
<rtc-player
|
||||
v-if="Object.keys(this.player).length == 1 && this.player.webRTC"
|
||||
ref="jessibuca"
|
||||
:visible.sync="showVideoDialog"
|
||||
:video-url="videoUrl"
|
||||
:error="videoError"
|
||||
:message="videoError"
|
||||
height="100px"
|
||||
:has-audio="hasAudio"
|
||||
fluent
|
||||
autoplay
|
||||
live
|
||||
/>
|
||||
<h265web
|
||||
v-if="Object.keys(this.player).length == 1 && this.player.h265web"
|
||||
ref="jessibuca"
|
||||
:visible.sync="showVideoDialog"
|
||||
:video-url="videoUrl"
|
||||
:error="videoError"
|
||||
:message="videoError"
|
||||
height="100px"
|
||||
:has-audio="hasAudio"
|
||||
fluent
|
||||
autoplay
|
||||
live
|
||||
/>
|
||||
</div>
|
||||
<div id="shared" style="text-align: right; margin-top: 1rem;">
|
||||
|
||||
@ -354,6 +314,7 @@
|
||||
|
||||
<script>
|
||||
import rtcPlayer from '../../common/rtcPlayer.vue'
|
||||
import elDragDialog from '@/directive/el-drag-dialog'
|
||||
import crypto from 'crypto'
|
||||
import jessibucaPlayer from '../../common/jessibuca.vue'
|
||||
import mediaInfo from '../../common/mediaInfo.vue'
|
||||
@ -361,6 +322,7 @@ import H265web from '../../common/h265web.vue'
|
||||
|
||||
export default {
|
||||
name: 'DevicePlayer',
|
||||
directives: { elDragDialog },
|
||||
components: {
|
||||
mediaInfo, H265web,
|
||||
jessibucaPlayer, rtcPlayer
|
||||
@ -414,9 +376,12 @@ export default {
|
||||
},
|
||||
computed: {
|
||||
getPlayerShared: function() {
|
||||
const typeMap = { jessibuca: 0, webRTC: 1, h265web: 2 }
|
||||
const type = typeMap[this.activePlayer] || 0
|
||||
const baseUrl = window.location.origin + '/#/play/share?type=' + type + '&url=' + encodeURIComponent(this.videoUrl)
|
||||
return {
|
||||
sharedUrl: window.location.origin + '/#/play/wasm/' + encodeURIComponent(this.videoUrl),
|
||||
sharedIframe: '' + window.location.origin + '<iframe src="/public#/play/wasm/"></iframe>' + encodeURIComponent(this.videoUrl) + '',
|
||||
sharedUrl: baseUrl,
|
||||
sharedIframe: '<iframe src="' + baseUrl + '"></iframe>',
|
||||
sharedRtmp: this.videoUrl
|
||||
}
|
||||
}
|
||||
@ -440,6 +405,13 @@ export default {
|
||||
changePlayer: function(tab) {
|
||||
this.activePlayer = tab.name
|
||||
this.videoUrl = this.getUrlByStreamInfo()
|
||||
if (this.$refs[this.activePlayer]) {
|
||||
this.$refs[this.activePlayer].play(this.videoUrl)
|
||||
} else {
|
||||
this.$nextTick(() => {
|
||||
this.$refs[this.activePlayer].play(this.videoUrl)
|
||||
})
|
||||
}
|
||||
},
|
||||
openDialog: function(tab, deviceId, channelId, param) {
|
||||
if (this.showVideoDialog) {
|
||||
|
||||
@ -33,8 +33,7 @@
|
||||
<div v-if="!videoUrl[i-1]" class="no-signal">{{ videoTip[i-1]?videoTip[i-1]:"无信号" }}</div>
|
||||
<player
|
||||
v-else
|
||||
:ref="'player'[i-1]"
|
||||
:video-url="videoUrl[i-1]"
|
||||
:ref="'player' + i"
|
||||
fluent
|
||||
autoplay
|
||||
:show-button="true"
|
||||
@ -220,6 +219,15 @@ export default {
|
||||
setTimeout(() => {
|
||||
window.localStorage.setItem('videoUrl', JSON.stringify(_this.videoUrl))
|
||||
}, 100)
|
||||
this.$nextTick(() => {
|
||||
const refName = 'player' + (idx + 1)
|
||||
if (this.$refs[refName]) {
|
||||
const player = this.$refs[refName] instanceof Array ? this.$refs[refName][0] : this.$refs[refName]
|
||||
if (player && player.play) {
|
||||
player.play(url)
|
||||
}
|
||||
}
|
||||
})
|
||||
},
|
||||
checkPlayByParam() {
|
||||
const query = this.$route.query
|
||||
|
||||
@ -87,8 +87,8 @@
|
||||
<el-table-column prop="stream" label="流ID" min-width="200" />
|
||||
<el-table-column label="推流状态" min-width="100">
|
||||
<template v-slot:default="scope">
|
||||
<el-tag v-if="scope.row.pushing && $myServerId !== scope.row.serverId" size="medium" style="border-color: #ecf1af">推流中</el-tag>
|
||||
<el-tag v-if="scope.row.pushing && $myServerId === scope.row.serverId" size="medium">推流中</el-tag>
|
||||
<el-tag v-if="scope.row.pushing && myServerId !== scope.row.serverId" size="medium" style="border-color: #ecf1af">推流中</el-tag>
|
||||
<el-tag v-if="scope.row.pushing && myServerId === scope.row.serverId" size="medium">推流中</el-tag>
|
||||
<el-tag v-if="!scope.row.pushing" size="medium" type="info">已停止</el-tag>
|
||||
</template>
|
||||
</el-table-column>
|
||||
@ -189,6 +189,11 @@ export default {
|
||||
destroyed() {
|
||||
clearTimeout(this.updateLooper)
|
||||
},
|
||||
computed: {
|
||||
myServerId() {
|
||||
return this.$store.getters.serverId
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
initData: function() {
|
||||
this.loading = true
|
||||
|
||||
Loading…
Reference in New Issue
Block a user