2023年4月24日 更改为rtmp直播方式,
This commit is contained in:
parent
5c7dd98370
commit
8de8b89348
|
@ -81,5 +81,6 @@ module.exports = defineConfig({
|
||||||
'vue/no-deprecated-v-on-native-modifier': 'off',
|
'vue/no-deprecated-v-on-native-modifier': 'off',
|
||||||
'vue/no-v-html': 'off',
|
'vue/no-v-html': 'off',
|
||||||
'prefer-const': 'off',
|
'prefer-const': 'off',
|
||||||
|
'no-irregular-whitespace': 'off',
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
|
@ -28,6 +28,8 @@
|
||||||
theme = htmlRoot = null;
|
theme = htmlRoot = null;
|
||||||
}
|
}
|
||||||
})();
|
})();
|
||||||
|
|
||||||
|
window.HELP_IMPROVE_VIDEOJS = false;
|
||||||
</script>
|
</script>
|
||||||
<div id="app">
|
<div id="app">
|
||||||
<style>
|
<style>
|
||||||
|
@ -172,5 +174,7 @@
|
||||||
<script type="text/javascript" src="/resource/js/webrtc/webrtcstreamer.js"></script>
|
<script type="text/javascript" src="/resource/js/webrtc/webrtcstreamer.js"></script>
|
||||||
<!-- <script type="module" src="/resource/js/webrtc/adapter.min.js"></script>
|
<!-- <script type="module" src="/resource/js/webrtc/adapter.min.js"></script>
|
||||||
<script type="module" src="/resource/js/webrtc/webrtcstreamer.js"></script> -->
|
<script type="module" src="/resource/js/webrtc/webrtcstreamer.js"></script> -->
|
||||||
|
<!-- <link href="https://vjs.zencdn.net/7.4.1/video-js.css" rel="stylesheet">
|
||||||
|
<script src='https://vjs.zencdn.net/7.4.1/video.js'></script> -->
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|
|
@ -59,6 +59,7 @@
|
||||||
"echarts": "^5.3.2",
|
"echarts": "^5.3.2",
|
||||||
"emoji-mart-vue-fast": "^11.1.1",
|
"emoji-mart-vue-fast": "^11.1.1",
|
||||||
"enquire.js": "^2.1.6",
|
"enquire.js": "^2.1.6",
|
||||||
|
"flv.js": "^1.6.2",
|
||||||
"intro.js": "^5.1.0",
|
"intro.js": "^5.1.0",
|
||||||
"lodash-es": "^4.17.21",
|
"lodash-es": "^4.17.21",
|
||||||
"lodash.get": "^4.4.2",
|
"lodash.get": "^4.4.2",
|
||||||
|
@ -77,6 +78,7 @@
|
||||||
"sortablejs": "^1.15.0",
|
"sortablejs": "^1.15.0",
|
||||||
"tinymce": "^5.10.3",
|
"tinymce": "^5.10.3",
|
||||||
"vditor": "^3.8.13",
|
"vditor": "^3.8.13",
|
||||||
|
"video.js": "^8.0.4",
|
||||||
"vue": "^3.2.33",
|
"vue": "^3.2.33",
|
||||||
"vue-cropper": "^0.5.6",
|
"vue-cropper": "^0.5.6",
|
||||||
"vue-cropperjs": "^5.0.0",
|
"vue-cropperjs": "^5.0.0",
|
||||||
|
|
|
@ -48,6 +48,8 @@ async function bootstrap() {
|
||||||
// 注册全局组件
|
// 注册全局组件
|
||||||
registerGlobComp(app);
|
registerGlobComp(app);
|
||||||
|
|
||||||
|
app.use(vue3videoPlay);
|
||||||
|
|
||||||
//CAS单点登录
|
//CAS单点登录
|
||||||
await useSso().ssoLogin();
|
await useSso().ssoLogin();
|
||||||
|
|
||||||
|
|
|
@ -82,9 +82,25 @@ const site: AppRouteModule = {
|
||||||
name: 'LiveBroadcastRoom',
|
name: 'LiveBroadcastRoom',
|
||||||
component: () => import('/@/views/site/common/webRTC/index.vue'),
|
component: () => import('/@/views/site/common/webRTC/index.vue'),
|
||||||
meta: {
|
meta: {
|
||||||
title: '直播',
|
title: '直播rtsp',
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
|
{
|
||||||
|
path: 'liveFlvView',
|
||||||
|
name: 'LiveFlvBroadcastRoom',
|
||||||
|
component: () => import('/@/views/site/common/video/flvjs/index.vue'),
|
||||||
|
meta: {
|
||||||
|
title: '直播flv.js',
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: 'livem3u8View',
|
||||||
|
name: 'Live3u8BroadcastRoom',
|
||||||
|
component: () => import('/@/views/site/common/video/videojs/index.vue'),
|
||||||
|
meta: {
|
||||||
|
title: '直播video.js',
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
],
|
],
|
||||||
};
|
};
|
||||||
|
|
|
@ -13,82 +13,35 @@
|
||||||
{{ item.jsmc }}-{{ item.xm }}
|
{{ item.jsmc }}-{{ item.xm }}
|
||||||
</a-menu-item>
|
</a-menu-item>
|
||||||
</a-menu>
|
</a-menu>
|
||||||
<!-- document.querySelector('.ant-layout .jeecg-default-layout-main > div').style.height -->
|
|
||||||
</a-col>
|
</a-col>
|
||||||
<a-col :span="20">
|
<a-col :span="20">
|
||||||
<!-- <a-row> -->
|
|
||||||
<!-- <a-col :span="12" v-if="currentItem?.child?.录播主机">
|
|
||||||
<div>{{ currentItem?.child?.录播主机?.xm }}</div>
|
|
||||||
<bVideo :ref="el=> bVideoRefs['main']=el" :videoOption="{ autoPlay: true }" :videoKey="'main'"/>
|
|
||||||
</a-col> -->
|
|
||||||
<!-- <a-col :span="12">
|
|
||||||
<a-row>
|
|
||||||
<a-col v-for="(item,index) of calcOtherVideo()" :span="12">
|
|
||||||
<div>{{ index }}</div>
|
|
||||||
<bVideo :ref="el=> bVideoRefs[index]=el" :videoOption="{ autoPlay: true }" :videoKey="'other-'+item.id"/>
|
|
||||||
</a-col>
|
|
||||||
</a-row>
|
|
||||||
</a-col> -->
|
|
||||||
<!-- <a-col v-for="(item,index) of calcOtherVideo()" :span="4">
|
|
||||||
</a-col> -->
|
|
||||||
<!-- <a-col :span="4"> -->
|
|
||||||
<!-- <bVideo ref="bVideoLeftRef" :videoOption="{ autoPlay: true }" :videoKey="'left-'+currentItem?.child?.学生定位?.id"/> -->
|
|
||||||
<!-- </a-col> -->
|
|
||||||
<!-- </a-row> -->
|
|
||||||
<div>
|
<div>
|
||||||
<a-card :title="mainVideoCardBoxTitle" class="videoCardMain">
|
<a-card :title="mainVideoCardBoxTitle" class="videoCardMain" style="width:100%">
|
||||||
<video id="mainVideo" v-bind="videoOption" style="width:100%" @click.prevent.stop></video>
|
<bVideo ref="mainVideo" videoId="mainVideo"></bVideo>
|
||||||
</a-card>
|
</a-card>
|
||||||
</div>
|
</div>
|
||||||
<div style="display: flex;flex-direction: row;flex-wrap: nowrap;overflow-x: scroll;">
|
<div style="display: flex;flex-direction: row;flex-wrap: nowrap;overflow-x: scroll;">
|
||||||
<div v-for="(item,index) of calcOtherVideo()" class="videoMax">
|
<div v-for="(item,index) of calcOtherVideo()" class="videoMax">
|
||||||
<a-card :title="item?.xm" style="width: 300px" class="videoCardMain">
|
<a-card :title="item?.xm" style="width: 300px" class="videoCardMain">
|
||||||
<bVideo :ref="el=> bVideoRefs[index]=el" :videoOption="{ autoPlay: true, onClick: bVideoClick }" :videoKey="'other-'+item.id"/>
|
<!-- <bVideo :ref="el=> bVideoRefs[index]=el" :src="'http://127.0.0.1/live_hls/soures.m3u8'" type="application/x-mpegURL" :videoId="'other-'+item.id"/> -->
|
||||||
|
<!-- <bVideo :ref="el=> bVideoRefs[index]=el" :videoOption="{ autoPlay: true, userActions: { click: bVideoClick } }" :src="'http://127.0.0.1/live_hls/soures.m3u8'" type="application/x-mpegURL" :videoId="'other-'+item.id"/> -->
|
||||||
|
<bVideo :ref="el=> bVideoRefs[index]=el" :videoOption="{ autoPlay: true, userActions: { click: bVideoClick } }" :src="item.pullUrl" type="application/x-mpegURL" :videoId="'other-'+item.id"/>
|
||||||
|
<!-- <bVideo :ref="el=> bVideoRefs[index]=el" :src="'http://bylwcs.nenu.edu.cn:8089/live_hls/123.m3u8'" type="application/x-mpegURL" :videoId="'other-'+item.id"/> -->
|
||||||
</a-card>
|
</a-card>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</a-col>
|
</a-col>
|
||||||
</a-row>
|
</a-row>
|
||||||
</div>
|
</div>
|
||||||
<!-- <a-layout>
|
|
||||||
<a-layout-sider width="200" style="background: #fff">
|
|
||||||
<a-menu
|
|
||||||
v-model:openKeys="openKeys"
|
|
||||||
v-model:selectedKeys="selectedKeys"
|
|
||||||
:style="{ height: '100%', borderRight: 0 }"
|
|
||||||
mode="inline"
|
|
||||||
>
|
|
||||||
<a-menu-item v-for="(item, index) of leftList" :key="index" @click="(e) => titleClick(e,item)" :title="`${item.xq}-${item.jsmc}-${item.xm}`">
|
|
||||||
{{ item.xq }}-{{ item.jsmc }}-{{ item.xm }}
|
|
||||||
</a-menu-item>
|
|
||||||
</a-menu>
|
|
||||||
|
|
||||||
</a-layout-sider>
|
|
||||||
<a-layout>
|
|
||||||
<a-layout-content> -->
|
|
||||||
<!-- {{ currentItem }} -->
|
|
||||||
<!-- <bVideo ref="bVideoMainRef" :videoOption="{ autoPlay: true }" :videoKey="'main'+currentItem.id"/> -->
|
|
||||||
<!-- <a-row>
|
|
||||||
<a-col :span="12">
|
|
||||||
<bVideo ref="bVideoMainRef" :videoOption="{ autoPlay: true }" :videoKey="'main'+currentItem.id"/>
|
|
||||||
</a-col>
|
|
||||||
<a-col :span="12">
|
|
||||||
<bVideo ref="bVideoLeftRef" :videoOption="{ autoPlay: true }" :videoKey="'main2'+currentItem.id"/>
|
|
||||||
</a-col>
|
|
||||||
</a-row> -->
|
|
||||||
<!-- </a-layout-content>
|
|
||||||
</a-layout> -->
|
|
||||||
<!-- </a-layout> -->
|
|
||||||
</template>
|
</template>
|
||||||
<script lang="ts" setup name="zhihuijiaoshiIndexPage">
|
<script lang="ts" setup name="zhihuijiaoshiIndexPage">
|
||||||
import type { MenuProps } from 'ant-design-vue';
|
|
||||||
import { defHttp } from '/@/utils/http/axios';
|
import { defHttp } from '/@/utils/http/axios';
|
||||||
import { useMessage } from "/@/hooks/web/useMessage";
|
import { ref, onMounted } from 'vue';
|
||||||
import { ref, onMounted, onBeforeUnmount, reactive, computed, VideoHTMLAttributes } from 'vue';
|
import bVideo from '/@/views/site/common/video/videojs/video.vue';
|
||||||
import bVideo from '/@/views/site/common/webRTC/video.vue';
|
|
||||||
import { nextTick } from 'vue';
|
import { nextTick } from 'vue';
|
||||||
|
|
||||||
const bVideoRefs = <any>ref([]);
|
const bVideoRefs = <any>ref([]);
|
||||||
|
const mainVideo = <any>ref();
|
||||||
const _document = window.document;
|
const _document = window.document;
|
||||||
// const bVideoLeftRef = ref();
|
// const bVideoLeftRef = ref();
|
||||||
|
|
||||||
|
@ -97,25 +50,6 @@ const currentItem = <any>ref({});
|
||||||
const topWidth = <any>ref('0');
|
const topWidth = <any>ref('0');
|
||||||
const mainVideoCardBoxTitle = <any>ref('');
|
const mainVideoCardBoxTitle = <any>ref('');
|
||||||
|
|
||||||
const videoOption = reactive({
|
|
||||||
// width: '800', //播放器高度
|
|
||||||
// height: '450', //播放器高度
|
|
||||||
color: "#409eff", //主题色
|
|
||||||
title: '', //视频名称
|
|
||||||
//src: "https://go.dreamwq.com/videos/IronMan.mp4", //视频源
|
|
||||||
muted: true, //静音
|
|
||||||
playsinline: true,
|
|
||||||
webFullScreen: false,
|
|
||||||
// speedRate: ["0.75", "1.0", "1.25", "1.5", "2.0"], //播放倍速
|
|
||||||
autoPlay: false, //自动播放
|
|
||||||
loop: false, //循环播放
|
|
||||||
mirror: false, //镜像画面
|
|
||||||
ligthOff: false, //关灯模式
|
|
||||||
volume: 0.3, //默认音量大小
|
|
||||||
controls: true, //是否显示控制器
|
|
||||||
});
|
|
||||||
|
|
||||||
|
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
list({ pageSize: -1, sfyx: '0' }).then(res => {
|
list({ pageSize: -1, sfyx: '0' }).then(res => {
|
||||||
let list = (res?.records) ?? [];
|
let list = (res?.records) ?? [];
|
||||||
|
@ -136,16 +70,12 @@ onMounted(() => {
|
||||||
});
|
});
|
||||||
|
|
||||||
leftList.value = Object.values(map);
|
leftList.value = Object.values(map);
|
||||||
topWidth.value = _document?.querySelector('.ant-layout .jeecg-default-layout-main > div')?.style?.height?? '0';
|
//计算左侧菜单高度
|
||||||
// console.log(_document?.querySelector('.ant-layout .jeecg-default-layout-main > div')?.style?.height?? '0')
|
let mainDiv = <any>_document?.querySelector('.ant-layout .jeecg-default-layout-main > div');
|
||||||
|
topWidth.value =mainDiv?.style?.height?? '0';
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
// const topWidthCalc = computed(() => {
|
|
||||||
// return _document?.querySelector('.ant-layout .jeecg-default-layout-main > div')?.style?.height?? '0';
|
|
||||||
// });
|
|
||||||
// xxx = document.querySelector('.ant-layout .jeecg-default-layout-main > div').style.height
|
|
||||||
//
|
|
||||||
enum Api {
|
enum Api {
|
||||||
list = '/jiaoshi/kcZhihuijiaoshi/list',
|
list = '/jiaoshi/kcZhihuijiaoshi/list',
|
||||||
}
|
}
|
||||||
|
@ -158,62 +88,30 @@ const list = (params) => defHttp.get({ url: Api.list, params });
|
||||||
|
|
||||||
const selectedKeys = ref<string[]>(['1']);
|
const selectedKeys = ref<string[]>(['1']);
|
||||||
const openKeys = ref<string[]>(['sub1']);
|
const openKeys = ref<string[]>(['sub1']);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 点击左侧菜单回调
|
||||||
|
* @param e
|
||||||
|
* @param item
|
||||||
|
*/
|
||||||
const titleClick = (e: Event, item: any) => {
|
const titleClick = (e: Event, item: any) => {
|
||||||
console.log('titleClick ->', e, item);
|
console.log('titleClick ->', e, item);
|
||||||
currentItem.value = item;
|
currentItem.value = {};
|
||||||
playerVideo(item);
|
|
||||||
|
nextTick(() => {
|
||||||
|
currentItem.value = item;
|
||||||
|
nextTick(() => {
|
||||||
|
//播放第一个
|
||||||
|
let one = <any>Object.values(calcOtherVideo())[0];
|
||||||
|
bVideoClick({ target: { playerId: 'other-'+ one.id} })
|
||||||
|
});
|
||||||
|
// playerVideo(item);
|
||||||
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
function playerVideo(item){
|
/**
|
||||||
nextTick(() => {
|
* 拆分对象(过滤器)
|
||||||
|
*/
|
||||||
//changshang == 奥威亚
|
|
||||||
// bVideoMainRef.value.connectFn(item.ip);
|
|
||||||
//bVideoMainRef.value.connectFn('rtsp://176.139.87.16/axis-media/media.amp','external');
|
|
||||||
// bVideoLeftRef.value.connectFn('rtsp://176.139.87.16/axis-media/media.amp','external');
|
|
||||||
|
|
||||||
//rtsp://admin:admin@10.250.116.235:8554/live
|
|
||||||
console.log('bVideoRefs ->',bVideoRefs,Object.values(bVideoRefs.value));
|
|
||||||
|
|
||||||
(Object.keys(bVideoRefs.value)).forEach((key) => {
|
|
||||||
console.log(`🚀 ~ file: index.vue:180 ~ key:`, key)
|
|
||||||
// x.connectFn('rtsp://admin:admin@10.250.116.235:8554/live','external')
|
|
||||||
// if(Number(Number(Math.random()).toFixed(1))*10 >= 5){
|
|
||||||
// x.connectFn('rtsp://127.0.0.1:8554/video','external');
|
|
||||||
// }else{
|
|
||||||
// x.connectFn(`rtsp://${x.ip}/live`,'external')
|
|
||||||
// }
|
|
||||||
// return;
|
|
||||||
let videoRef = bVideoRefs.value[key];
|
|
||||||
console.log(`🚀 ~ file: index.vue:187 ~ videoRef:`, videoRef)
|
|
||||||
|
|
||||||
let childItem = currentItem.value.child[key];
|
|
||||||
console.log(`🚀 ~ file: index.vue:189 ~ childItem:`, childItem)
|
|
||||||
if(!childItem){
|
|
||||||
console.log('无法找到视频链接对象,currentItem.value.child[key] ->',currentItem,key);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if(childItem.changshang == '奥威亚'){
|
|
||||||
videoRef.connectFn(`rtsp://${childItem.ip}/stream/0?config.login=web`,'external')
|
|
||||||
}else if(childItem.changshang == '卓智'){
|
|
||||||
videoRef.connectFn(`rtsp://${childItem.ip}/live`,'external')
|
|
||||||
}else{
|
|
||||||
videoRef.connectFn(`rtsp://${childItem.ip}/stream/0?config.login=web`,'external')
|
|
||||||
}
|
|
||||||
|
|
||||||
});
|
|
||||||
|
|
||||||
// (Object.values(bVideoRefs.value)).forEach((videoRef: any) => {
|
|
||||||
|
|
||||||
// console.log(`🚀 ~ file: index.vue:148 ~ playerVideo ~ videoRef:`, videoRef);
|
|
||||||
// });
|
|
||||||
setTimeout(() => {
|
|
||||||
switchVideoToMain();
|
|
||||||
},1000);
|
|
||||||
})
|
|
||||||
//bVideoRefs['main'].connectFn('rtsp://admin:admin@10.250.116.235:8554/live','external');
|
|
||||||
}
|
|
||||||
|
|
||||||
function calcOtherVideo() :any{
|
function calcOtherVideo() :any{
|
||||||
if(!currentItem.value.child) return {};
|
if(!currentItem.value.child) return {};
|
||||||
let map = {};
|
let map = {};
|
||||||
|
@ -225,46 +123,21 @@ function calcOtherVideo() :any{
|
||||||
return map;
|
return map;
|
||||||
}
|
}
|
||||||
|
|
||||||
function switchVideoToMain(){
|
/**
|
||||||
console.log(`🚀 ~ file: index.vue:188 ~ switchVideoToMain ~ switchVideoToMain: 自动切换第一个子界面到主界面`);
|
* 点击时切换至大屏
|
||||||
nextTick(() => {
|
* @param e
|
||||||
let firstBox = <HTMLVideoElement> document.querySelector('.videoMax');
|
*/
|
||||||
let titleBox = <HTMLVideoElement> firstBox?.querySelector('.ant-card-head-title');
|
|
||||||
let title = titleBox?.textContent;
|
|
||||||
|
|
||||||
mainVideoCardBoxTitle.value = title;
|
|
||||||
|
|
||||||
let mainVideo = <HTMLVideoElement> document.querySelector('#mainVideo');
|
|
||||||
let firstVideo = <HTMLVideoElement> firstBox.querySelector('video');
|
|
||||||
mainVideo.srcObject = firstVideo.srcObject
|
|
||||||
mainVideo.play();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
function bVideoClick(e){
|
function bVideoClick(e){
|
||||||
console.log(`bVideoClick: 切换至主界面`);
|
console.log(`bVideoClick: 点击切换至主界面`);
|
||||||
let mainVideo = <HTMLVideoElement> document.querySelector('#mainVideo');
|
console.log('e =>',e);
|
||||||
let currentVideo = <HTMLVideoElement> e.srcElement;
|
|
||||||
|
|
||||||
let title = currentVideo?.parentElement?.parentElement?.querySelector('.ant-card-head-title')?.textContent
|
let mainVideo = <any> document.querySelector('#mainVideo');
|
||||||
mainVideoCardBoxTitle.value = title;
|
let currentVideo = <any> document.querySelector('#'+e.target.playerId);
|
||||||
console.log(`🚀 --------------------------------------------------------------------🚀`);
|
let src = currentVideo.player?.src();
|
||||||
console.log(`🚀 ~ file: index.vue:238 ~ bVideoClick ~ currentVideo:`, currentVideo);
|
|
||||||
console.log(`🚀 --------------------------------------------------------------------🚀`);
|
|
||||||
|
|
||||||
mainVideo.srcObject = currentVideo.srcObject
|
mainVideo?.player?.src([{type:'application/x-mpegURL',src }])
|
||||||
mainVideo.play();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
//页面销毁时销毁webRtc
|
|
||||||
onBeforeUnmount(() => {
|
|
||||||
bVideoRefs.value.forEach(x => {
|
|
||||||
x.closeWebRtcStreamerFn();
|
|
||||||
});
|
|
||||||
})
|
|
||||||
|
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
<style lang="less" scoped>
|
<style lang="less" scoped>
|
||||||
.videoMax{
|
.videoMax{
|
||||||
|
|
|
@ -0,0 +1,282 @@
|
||||||
|
<template>
|
||||||
|
<div style="width:100%;height: 100%;">
|
||||||
|
<a-row>
|
||||||
|
<a-col :span="4">
|
||||||
|
<a-menu
|
||||||
|
v-model:openKeys="openKeys"
|
||||||
|
v-model:selectedKeys="selectedKeys"
|
||||||
|
style="overflow: hidden;overflow-y:scroll"
|
||||||
|
:style="{ height: `calc(100vh - ${topWidth})`, borderRight: 0 }"
|
||||||
|
mode="inline"
|
||||||
|
>
|
||||||
|
<a-menu-item v-for="(item, index) of leftList" :key="index" @click="(e) => titleClick(e,item)" :title="`${item.jsmc}-${item.xm}`">
|
||||||
|
{{ item.jsmc }}-{{ item.xm }}
|
||||||
|
</a-menu-item>
|
||||||
|
</a-menu>
|
||||||
|
<!-- document.querySelector('.ant-layout .jeecg-default-layout-main > div').style.height -->
|
||||||
|
</a-col>
|
||||||
|
<a-col :span="20">
|
||||||
|
<!-- <a-row> -->
|
||||||
|
<!-- <a-col :span="12" v-if="currentItem?.child?.录播主机">
|
||||||
|
<div>{{ currentItem?.child?.录播主机?.xm }}</div>
|
||||||
|
<bVideo :ref="el=> bVideoRefs['main']=el" :videoOption="{ autoPlay: true }" :videoKey="'main'"/>
|
||||||
|
</a-col> -->
|
||||||
|
<!-- <a-col :span="12">
|
||||||
|
<a-row>
|
||||||
|
<a-col v-for="(item,index) of calcOtherVideo()" :span="12">
|
||||||
|
<div>{{ index }}</div>
|
||||||
|
<bVideo :ref="el=> bVideoRefs[index]=el" :videoOption="{ autoPlay: true }" :videoKey="'other-'+item.id"/>
|
||||||
|
</a-col>
|
||||||
|
</a-row>
|
||||||
|
</a-col> -->
|
||||||
|
<!-- <a-col v-for="(item,index) of calcOtherVideo()" :span="4">
|
||||||
|
</a-col> -->
|
||||||
|
<!-- <a-col :span="4"> -->
|
||||||
|
<!-- <bVideo ref="bVideoLeftRef" :videoOption="{ autoPlay: true }" :videoKey="'left-'+currentItem?.child?.学生定位?.id"/> -->
|
||||||
|
<!-- </a-col> -->
|
||||||
|
<!-- </a-row> -->
|
||||||
|
<div>
|
||||||
|
<a-card :title="mainVideoCardBoxTitle" class="videoCardMain">
|
||||||
|
<video id="mainVideo" v-bind="videoOption" style="width:100%" @click.prevent.stop></video>
|
||||||
|
</a-card>
|
||||||
|
</div>
|
||||||
|
<div style="display: flex;flex-direction: row;flex-wrap: nowrap;overflow-x: scroll;">
|
||||||
|
<div v-for="(item,index) of calcOtherVideo()" class="videoMax">
|
||||||
|
<a-card :title="item?.xm" style="width: 300px" class="videoCardMain">
|
||||||
|
<bVideo :ref="el=> bVideoRefs[index]=el" :videoOption="{ autoPlay: true, onClick: bVideoClick }" :videoKey="'other-'+item.id"/>
|
||||||
|
</a-card>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</a-col>
|
||||||
|
</a-row>
|
||||||
|
</div>
|
||||||
|
<!-- <a-layout>
|
||||||
|
<a-layout-sider width="200" style="background: #fff">
|
||||||
|
<a-menu
|
||||||
|
v-model:openKeys="openKeys"
|
||||||
|
v-model:selectedKeys="selectedKeys"
|
||||||
|
:style="{ height: '100%', borderRight: 0 }"
|
||||||
|
mode="inline"
|
||||||
|
>
|
||||||
|
<a-menu-item v-for="(item, index) of leftList" :key="index" @click="(e) => titleClick(e,item)" :title="`${item.xq}-${item.jsmc}-${item.xm}`">
|
||||||
|
{{ item.xq }}-{{ item.jsmc }}-{{ item.xm }}
|
||||||
|
</a-menu-item>
|
||||||
|
</a-menu>
|
||||||
|
|
||||||
|
</a-layout-sider>
|
||||||
|
<a-layout>
|
||||||
|
<a-layout-content> -->
|
||||||
|
<!-- {{ currentItem }} -->
|
||||||
|
<!-- <bVideo ref="bVideoMainRef" :videoOption="{ autoPlay: true }" :videoKey="'main'+currentItem.id"/> -->
|
||||||
|
<!-- <a-row>
|
||||||
|
<a-col :span="12">
|
||||||
|
<bVideo ref="bVideoMainRef" :videoOption="{ autoPlay: true }" :videoKey="'main'+currentItem.id"/>
|
||||||
|
</a-col>
|
||||||
|
<a-col :span="12">
|
||||||
|
<bVideo ref="bVideoLeftRef" :videoOption="{ autoPlay: true }" :videoKey="'main2'+currentItem.id"/>
|
||||||
|
</a-col>
|
||||||
|
</a-row> -->
|
||||||
|
<!-- </a-layout-content>
|
||||||
|
</a-layout> -->
|
||||||
|
<!-- </a-layout> -->
|
||||||
|
</template>
|
||||||
|
<script lang="ts" setup name="zhihuijiaoshiIndexPage">
|
||||||
|
import type { MenuProps } from 'ant-design-vue';
|
||||||
|
import { defHttp } from '/@/utils/http/axios';
|
||||||
|
import { useMessage } from "/@/hooks/web/useMessage";
|
||||||
|
import { ref, onMounted, onBeforeUnmount, reactive, computed, VideoHTMLAttributes } from 'vue';
|
||||||
|
import bVideo from '/@/views/site/common/webRTC/video.vue';
|
||||||
|
import { nextTick } from 'vue';
|
||||||
|
|
||||||
|
const bVideoRefs = <any>ref([]);
|
||||||
|
const _document = window.document;
|
||||||
|
// const bVideoLeftRef = ref();
|
||||||
|
|
||||||
|
const leftList = <any>ref([]);
|
||||||
|
const currentItem = <any>ref({});
|
||||||
|
const topWidth = <any>ref('0');
|
||||||
|
const mainVideoCardBoxTitle = <any>ref('');
|
||||||
|
|
||||||
|
const videoOption = reactive({
|
||||||
|
// width: '800', //播放器高度
|
||||||
|
// height: '450', //播放器高度
|
||||||
|
color: "#409eff", //主题色
|
||||||
|
title: '', //视频名称
|
||||||
|
//src: "https://go.dreamwq.com/videos/IronMan.mp4", //视频源
|
||||||
|
muted: true, //静音
|
||||||
|
playsinline: true,
|
||||||
|
webFullScreen: false,
|
||||||
|
// speedRate: ["0.75", "1.0", "1.25", "1.5", "2.0"], //播放倍速
|
||||||
|
autoPlay: false, //自动播放
|
||||||
|
loop: false, //循环播放
|
||||||
|
mirror: false, //镜像画面
|
||||||
|
ligthOff: false, //关灯模式
|
||||||
|
volume: 0.3, //默认音量大小
|
||||||
|
controls: true, //是否显示控制器
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
onMounted(() => {
|
||||||
|
list({ pageSize: -1, sfyx: '0' }).then(res => {
|
||||||
|
let list = (res?.records) ?? [];
|
||||||
|
//聚合
|
||||||
|
let map = {};
|
||||||
|
list.forEach(x => {
|
||||||
|
let item = map[x.jsmc];
|
||||||
|
if(item){
|
||||||
|
item.child[x.xm] = x;
|
||||||
|
}else{
|
||||||
|
let child = {};
|
||||||
|
child[x.xm] = x;
|
||||||
|
map[x.jsmc] = {
|
||||||
|
...x,
|
||||||
|
child
|
||||||
|
};
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
leftList.value = Object.values(map);
|
||||||
|
topWidth.value = _document?.querySelector('.ant-layout .jeecg-default-layout-main > div')?.style?.height?? '0';
|
||||||
|
// console.log(_document?.querySelector('.ant-layout .jeecg-default-layout-main > div')?.style?.height?? '0')
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
// const topWidthCalc = computed(() => {
|
||||||
|
// return _document?.querySelector('.ant-layout .jeecg-default-layout-main > div')?.style?.height?? '0';
|
||||||
|
// });
|
||||||
|
// xxx = document.querySelector('.ant-layout .jeecg-default-layout-main > div').style.height
|
||||||
|
//
|
||||||
|
enum Api {
|
||||||
|
list = '/jiaoshi/kcZhihuijiaoshi/list',
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* 列表接口
|
||||||
|
* @param params
|
||||||
|
*/
|
||||||
|
const list = (params) => defHttp.get({ url: Api.list, params });
|
||||||
|
|
||||||
|
|
||||||
|
const selectedKeys = ref<string[]>(['1']);
|
||||||
|
const openKeys = ref<string[]>(['sub1']);
|
||||||
|
const titleClick = (e: Event, item: any) => {
|
||||||
|
console.log('titleClick ->', e, item);
|
||||||
|
currentItem.value = item;
|
||||||
|
playerVideo(item);
|
||||||
|
};
|
||||||
|
|
||||||
|
function playerVideo(item){
|
||||||
|
nextTick(() => {
|
||||||
|
|
||||||
|
//changshang == 奥威亚
|
||||||
|
// bVideoMainRef.value.connectFn(item.ip);
|
||||||
|
//bVideoMainRef.value.connectFn('rtsp://176.139.87.16/axis-media/media.amp','external');
|
||||||
|
// bVideoLeftRef.value.connectFn('rtsp://176.139.87.16/axis-media/media.amp','external');
|
||||||
|
|
||||||
|
//rtsp://admin:admin@10.250.116.235:8554/live
|
||||||
|
console.log('bVideoRefs ->',bVideoRefs,Object.values(bVideoRefs.value));
|
||||||
|
|
||||||
|
(Object.keys(bVideoRefs.value)).forEach((key) => {
|
||||||
|
console.log(`🚀 ~ file: index.vue:180 ~ key:`, key)
|
||||||
|
// x.connectFn('rtsp://admin:admin@10.250.116.235:8554/live','external')
|
||||||
|
// if(Number(Number(Math.random()).toFixed(1))*10 >= 5){
|
||||||
|
// x.connectFn('rtsp://127.0.0.1:8554/video','external');
|
||||||
|
// }else{
|
||||||
|
// x.connectFn(`rtsp://${x.ip}/live`,'external')
|
||||||
|
// }
|
||||||
|
// return;
|
||||||
|
let videoRef = bVideoRefs.value[key];
|
||||||
|
console.log(`🚀 ~ file: index.vue:187 ~ videoRef:`, videoRef)
|
||||||
|
|
||||||
|
let childItem = currentItem.value.child[key];
|
||||||
|
console.log(`🚀 ~ file: index.vue:189 ~ childItem:`, childItem)
|
||||||
|
if(!childItem){
|
||||||
|
console.log('无法找到视频链接对象,currentItem.value.child[key] ->',currentItem,key);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if(childItem.changshang == '奥威亚'){
|
||||||
|
videoRef.connectFn(`rtsp://${childItem.ip}/stream/0?config.login=web`,'external')
|
||||||
|
}else if(childItem.changshang == '卓智'){
|
||||||
|
videoRef.connectFn(`rtsp://${childItem.ip}/live`,'external')
|
||||||
|
}else{
|
||||||
|
videoRef.connectFn(`rtsp://${childItem.ip}/stream/0?config.login=web`,'external')
|
||||||
|
}
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
// (Object.values(bVideoRefs.value)).forEach((videoRef: any) => {
|
||||||
|
|
||||||
|
// console.log(`🚀 ~ file: index.vue:148 ~ playerVideo ~ videoRef:`, videoRef);
|
||||||
|
// });
|
||||||
|
setTimeout(() => {
|
||||||
|
switchVideoToMain();
|
||||||
|
},1000);
|
||||||
|
})
|
||||||
|
//bVideoRefs['main'].connectFn('rtsp://admin:admin@10.250.116.235:8554/live','external');
|
||||||
|
}
|
||||||
|
|
||||||
|
function calcOtherVideo() :any{
|
||||||
|
if(!currentItem.value.child) return {};
|
||||||
|
let map = {};
|
||||||
|
Object.keys(currentItem.value.child).forEach(key => {
|
||||||
|
// if(key != '录播主机' && key.indexOf('音频处理器') ==-1){
|
||||||
|
map[key] = currentItem.value.child[key];
|
||||||
|
// }
|
||||||
|
});
|
||||||
|
return map;
|
||||||
|
}
|
||||||
|
|
||||||
|
function switchVideoToMain(){
|
||||||
|
console.log(`🚀 ~ file: index.vue:188 ~ switchVideoToMain ~ switchVideoToMain: 自动切换第一个子界面到主界面`);
|
||||||
|
nextTick(() => {
|
||||||
|
let firstBox = <HTMLVideoElement> document.querySelector('.videoMax');
|
||||||
|
let titleBox = <HTMLVideoElement> firstBox?.querySelector('.ant-card-head-title');
|
||||||
|
let title = titleBox?.textContent;
|
||||||
|
|
||||||
|
mainVideoCardBoxTitle.value = title;
|
||||||
|
|
||||||
|
let mainVideo = <HTMLVideoElement> document.querySelector('#mainVideo');
|
||||||
|
let firstVideo = <HTMLVideoElement> firstBox.querySelector('video');
|
||||||
|
mainVideo.srcObject = firstVideo.srcObject
|
||||||
|
mainVideo.play();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function bVideoClick(e){
|
||||||
|
console.log(`bVideoClick: 切换至主界面`);
|
||||||
|
let mainVideo = <HTMLVideoElement> document.querySelector('#mainVideo');
|
||||||
|
let currentVideo = <HTMLVideoElement> e.srcElement;
|
||||||
|
|
||||||
|
let title = currentVideo?.parentElement?.parentElement?.querySelector('.ant-card-head-title')?.textContent
|
||||||
|
mainVideoCardBoxTitle.value = title;
|
||||||
|
console.log(`🚀 --------------------------------------------------------------------🚀`);
|
||||||
|
console.log(`🚀 ~ file: index.vue:238 ~ bVideoClick ~ currentVideo:`, currentVideo);
|
||||||
|
console.log(`🚀 --------------------------------------------------------------------🚀`);
|
||||||
|
|
||||||
|
mainVideo.srcObject = currentVideo.srcObject
|
||||||
|
mainVideo.play();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//页面销毁时销毁webRtc
|
||||||
|
onBeforeUnmount(() => {
|
||||||
|
bVideoRefs.value.forEach(x => {
|
||||||
|
x.closeWebRtcStreamerFn();
|
||||||
|
});
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
|
</script>
|
||||||
|
<style lang="less" scoped>
|
||||||
|
.videoMax{
|
||||||
|
width: 300px;
|
||||||
|
}
|
||||||
|
.videoCardMain {
|
||||||
|
:deep(.ant-card-body) {
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/* 隐藏video 进度条 */
|
||||||
|
video::-webkit-media-controls-timeline {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
</style>
|
|
@ -17,7 +17,9 @@
|
||||||
</div>
|
</div>
|
||||||
<span class="topTitle">
|
<span class="topTitle">
|
||||||
{{ projectName }}
|
{{ projectName }}
|
||||||
<RouterLink hidden target='_blank' :to="{path:'/site/liveView',query:{ url: 'rtsp://176.139.87.16/axis-media/media.amp' }}">直播测试页</RouterLink>
|
<RouterLink hidden target='_blank' :to="{path:'/site/liveView',query:{ url: 'rtsp://176.139.87.16/axis-media/media.amp' }}">直播测试页rtsp</RouterLink>
|
||||||
|
<RouterLink hidden target='_blank' :to="{path:'/site/liveFlvView',query:{ url: 'rtsp://176.139.87.16/axis-media/media.amp' }}">直播测试页flv</RouterLink>
|
||||||
|
<RouterLink hidden target='_blank' :to="{path:'/site/livem3u8View',query:{ url: 'rtsp://176.139.87.16/axis-media/media.amp' }}">直播测试页m3u8</RouterLink>
|
||||||
</span>
|
</span>
|
||||||
<span class="topRight">
|
<span class="topRight">
|
||||||
<a-dropdown>
|
<a-dropdown>
|
||||||
|
|
|
@ -0,0 +1,78 @@
|
||||||
|
<template>
|
||||||
|
<!-- <div @click="onPlay">点击开始播放(连接)直播</div>
|
||||||
|
<div @click="onPlay2">点击开始播放(连接)直播2</div> -->
|
||||||
|
<!-- <div>{{ route.query.url }}</div> -->
|
||||||
|
<!-- <bVideo ref="bVideoRef"/> -->
|
||||||
|
<!-- <video id="video" muted playsinline controls style=""></video> -->
|
||||||
|
<!-- <video id="myVideo" class="video-js vjs-default-skin vjs-big-play-centered" controls autoplay data-setup='{}' style='width: 100%;height: auto'>
|
||||||
|
<source id="source" src="http://127.0.0.1/01.m3u8" type="application/x-mpegURL"/>
|
||||||
|
</video> -->
|
||||||
|
<div>--不好用,屏蔽掉</div>
|
||||||
|
</template>
|
||||||
|
<script lang="ts" setup>
|
||||||
|
// import { ref, onMounted, onBeforeUnmount} from 'vue';
|
||||||
|
// import { useRoute } from 'vue-router'
|
||||||
|
// import flvjs from 'flv.js'
|
||||||
|
// // import bVideo from '/@/views/site/common/webRTC/video.vue';
|
||||||
|
|
||||||
|
|
||||||
|
// // const bVideoRef = ref();
|
||||||
|
|
||||||
|
// const route = useRoute();
|
||||||
|
|
||||||
|
// // //页面销毁时销毁webRtc
|
||||||
|
// // onBeforeUnmount(() => {
|
||||||
|
// // bVideoRef.value.closeWebRtcStreamerFn();
|
||||||
|
// // })
|
||||||
|
|
||||||
|
// onMounted(() => {
|
||||||
|
// if(route.query.url){
|
||||||
|
// if (flvjs.isSupported()) {
|
||||||
|
// var videoDom = <HTMLVideoElement> document.getElementById('video')
|
||||||
|
// // 创建一个播放器实例
|
||||||
|
// let option = <flvjs.MediaDataSource>({
|
||||||
|
// type: 'flv', // 媒体类型,默认是 flv
|
||||||
|
// cors: true, //跨域
|
||||||
|
// isLive: true, // 是否是直播流
|
||||||
|
// hasAudio: true, // 是否有音频
|
||||||
|
// hanVideo: true, // 是否有视频
|
||||||
|
// // url: 'ws://127.0.0.1:1935/live/soures', // 流地址
|
||||||
|
// // url: 'ws://127.0.0.1/live_hls/soures', // 流地址
|
||||||
|
// url: 'http://127.0.0.1/live_hls/soures.m3u8', // 流地址
|
||||||
|
// })
|
||||||
|
// let config = <any>({
|
||||||
|
// // 其他的配置项可以根据项目实际情况参考 api 去配置
|
||||||
|
// autoCleanupMinBackwardDuration: true, // 清除缓存 对 SourceBuffer 进行自动清理
|
||||||
|
// })
|
||||||
|
// var player = flvjs.createPlayer(option, config);
|
||||||
|
// player.attachMediaElement(videoDom)
|
||||||
|
// player.load()
|
||||||
|
// player.play()
|
||||||
|
|
||||||
|
// //this.player = player
|
||||||
|
// }
|
||||||
|
|
||||||
|
// // bVideoRef.value.connectFn(route.query.url);
|
||||||
|
// }
|
||||||
|
// })
|
||||||
|
|
||||||
|
// onMounted(() => {
|
||||||
|
// var myVideo = videojs('myVideo', {
|
||||||
|
// bigPlayButton: true,
|
||||||
|
// textTrackDisplay: false,
|
||||||
|
// posterImage: false,
|
||||||
|
// errorDisplay: false,
|
||||||
|
// })
|
||||||
|
// myVideo.play()
|
||||||
|
// })
|
||||||
|
|
||||||
|
</script>
|
||||||
|
<style lang="less" scoped>
|
||||||
|
video {
|
||||||
|
//margin: auto;
|
||||||
|
//left: 0;
|
||||||
|
//right: 0;
|
||||||
|
//position: relative;
|
||||||
|
background: grey;
|
||||||
|
}
|
||||||
|
</style>
|
|
@ -0,0 +1,83 @@
|
||||||
|
<template>
|
||||||
|
<!-- <div @click="onPlay2">点击开始播放(连接)直播2</div> -->
|
||||||
|
<!-- <div>{{ route.query.url }}</div> -->
|
||||||
|
<video
|
||||||
|
id="my-player"
|
||||||
|
class="video-js"
|
||||||
|
controls
|
||||||
|
preload="auto"
|
||||||
|
poster="//vjs.zencdn.net/v/oceans.png"
|
||||||
|
>
|
||||||
|
<!-- <source src="//vjs.zencdn.net/v/oceans.mp4" type="video/mp4"/>
|
||||||
|
<source src="//vjs.zencdn.net/v/oceans.webm" type="video/webm"/>
|
||||||
|
<source src="//vjs.zencdn.net/v/oceans.ogv" type="video/ogg"/> -->
|
||||||
|
<!-- <source src="http://127.0.0.1/live_hls/soures.m3u8" type="video/mp4"/> -->
|
||||||
|
<!-- <source src="http://127.0.0.1/live_hls/soures.m3u8" type="rtmp/flv"/> -->
|
||||||
|
<p class="vjs-no-js">
|
||||||
|
要观看此视频,请启用JavaScript,并考虑升级web浏览器
|
||||||
|
<a href="https://videojs.com/html5-video-support/" target="_blank">
|
||||||
|
支持HTML5视频
|
||||||
|
</a>
|
||||||
|
</p>
|
||||||
|
</video>
|
||||||
|
</template>
|
||||||
|
<script lang="ts" setup>
|
||||||
|
import { ref, onMounted, onBeforeUnmount} from 'vue';
|
||||||
|
import { useRoute } from 'vue-router'
|
||||||
|
|
||||||
|
import videojs from "video.js";
|
||||||
|
import "video.js/dist/video-js.css";
|
||||||
|
// import bVideo from '/@/views/site/common/webRTC/video.vue';
|
||||||
|
|
||||||
|
|
||||||
|
// const bVideoRef = ref();
|
||||||
|
|
||||||
|
const route = useRoute();
|
||||||
|
|
||||||
|
// //页面销毁时销毁webRtc
|
||||||
|
// onBeforeUnmount(() => {
|
||||||
|
// bVideoRef.value.closeWebRtcStreamerFn();
|
||||||
|
// })
|
||||||
|
|
||||||
|
// onMounted(() => {
|
||||||
|
// if(route.query.url){
|
||||||
|
// bVideoRef.value.connectFn(route.query.url);
|
||||||
|
// }
|
||||||
|
// })
|
||||||
|
|
||||||
|
onMounted(() => {
|
||||||
|
if(route.query.url){
|
||||||
|
var player = videojs('my-player',{
|
||||||
|
autoplay: true,
|
||||||
|
controls: true,
|
||||||
|
muted: true,
|
||||||
|
preload: 'auto',
|
||||||
|
language: 'zh-CN',
|
||||||
|
playbackRates: [1,2,3,4,5,8,10,20],
|
||||||
|
trechIrder: ['flash'],
|
||||||
|
sources: [{
|
||||||
|
// type: 'rtmp/flv',
|
||||||
|
// src: 'rtmp://127.0.0.1:1935/live/soures',
|
||||||
|
type: route.query.type??'application/x-mpegURL',
|
||||||
|
src: route.query.url??'http://127.0.0.1/live_hls/soures.m3u8',
|
||||||
|
}],
|
||||||
|
flash: {
|
||||||
|
swf: 'https://cnd.bootcdn.net/ajax/libs/videojs-swf/5.4.2/video-js.swf',
|
||||||
|
}
|
||||||
|
},() => {
|
||||||
|
console.log("加载完成!");
|
||||||
|
|
||||||
|
});
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
</script>
|
||||||
|
<style lang="less" scoped>
|
||||||
|
video {
|
||||||
|
//margin: auto;
|
||||||
|
//left: 0;
|
||||||
|
//right: 0;
|
||||||
|
//position: relative;
|
||||||
|
background: grey;
|
||||||
|
}
|
||||||
|
</style>
|
|
@ -0,0 +1,32 @@
|
||||||
|
// import { ref, nextTick, onBeforeUnmount} from 'vue';
|
||||||
|
|
||||||
|
// export const rtcServerUrl = import.meta.env.VITE_GLOB_RTC_SERVER;
|
||||||
|
|
||||||
|
export function getDefOptions(object) {
|
||||||
|
// const windowObj = <any>window;
|
||||||
|
// const WebRtcStreamer = windowObj.WebRtcStreamer;
|
||||||
|
let o = {
|
||||||
|
autoplay: true,
|
||||||
|
controls: true,
|
||||||
|
muted: true,
|
||||||
|
errorDisplay: false,
|
||||||
|
preload: 'auto',
|
||||||
|
language: 'zh-CN',
|
||||||
|
aspectRatio: "16:9",
|
||||||
|
fluid: true,
|
||||||
|
liveui: true,
|
||||||
|
hotkeys: false,
|
||||||
|
// playbackRates: [1,2,3,4,5,8,10,20],
|
||||||
|
trechIrder: ['flash'],
|
||||||
|
// sources: [{
|
||||||
|
// // type: 'rtmp/flv',
|
||||||
|
// // src: 'rtmp://127.0.0.1:1935/live/soures',
|
||||||
|
// type: 'application/x-mpegURL',
|
||||||
|
// src: 'http://127.0.0.1/live_hls/soures.m3u8',
|
||||||
|
// }],
|
||||||
|
flash: {
|
||||||
|
swf: 'https://cnd.bootcdn.net/ajax/libs/videojs-swf/5.4.2/video-js.swf',
|
||||||
|
}
|
||||||
|
};
|
||||||
|
return Object.assign(o,object);
|
||||||
|
}
|
|
@ -0,0 +1,66 @@
|
||||||
|
<template>
|
||||||
|
<!-- <div @click="onPlay2">点击开始播放(连接)直播2</div> -->
|
||||||
|
<!-- <div>{{ route.query.url }}</div> -->
|
||||||
|
<video
|
||||||
|
:id="props.videoId"
|
||||||
|
playsinline="true"
|
||||||
|
class="video-js"
|
||||||
|
controls
|
||||||
|
preload="auto"
|
||||||
|
poster="//vjs.zencdn.net/v/oceans.png"
|
||||||
|
>
|
||||||
|
<p class="vjs-no-js">
|
||||||
|
要观看此视频,请启用JavaScript,并考虑升级web浏览器
|
||||||
|
<a href="https://videojs.com/html5-video-support/" target="_blank">
|
||||||
|
支持HTML5视频
|
||||||
|
</a>
|
||||||
|
</p>
|
||||||
|
</video>
|
||||||
|
</template>
|
||||||
|
<script lang="ts" setup>
|
||||||
|
import { ref, onMounted, onBeforeUnmount} from 'vue';
|
||||||
|
import { propTypes } from '/@/utils/propTypes';
|
||||||
|
import { getDefOptions } from './util.ts';
|
||||||
|
|
||||||
|
import videojs from "video.js";
|
||||||
|
import "video.js/dist/video-js.css";
|
||||||
|
|
||||||
|
const props = defineProps({
|
||||||
|
videoId: propTypes.string.def('playerId'),
|
||||||
|
src: propTypes.string.def(''),
|
||||||
|
type: propTypes.string.def('application/x-mpegURL'),
|
||||||
|
videoOption: propTypes.object.def({}),
|
||||||
|
});
|
||||||
|
|
||||||
|
const player = ref();
|
||||||
|
|
||||||
|
onMounted(() => {
|
||||||
|
let sources = [ { type: props.type, src: props.src, } ];
|
||||||
|
let playerMain = <any> videojs(props.videoId, getDefOptions(Object.assign({ sources },props.videoOption)),() => {
|
||||||
|
console.log("加载完成!",playerMain,props.videoOption);
|
||||||
|
playerMain.on('pause', function(...d) {
|
||||||
|
console.log('点击了??',...d);
|
||||||
|
|
||||||
|
// myAwesomePlayer.play();
|
||||||
|
// ...so you can do here all the stuff you want while the video is playing
|
||||||
|
|
||||||
|
});
|
||||||
|
});
|
||||||
|
player.value = playerMain;
|
||||||
|
|
||||||
|
})
|
||||||
|
|
||||||
|
defineExpose({
|
||||||
|
player
|
||||||
|
});
|
||||||
|
|
||||||
|
</script>
|
||||||
|
<style lang="less" scoped>
|
||||||
|
// video {
|
||||||
|
// //margin: auto;
|
||||||
|
// //left: 0;
|
||||||
|
// //right: 0;
|
||||||
|
// //position: relative;
|
||||||
|
// background: grey;
|
||||||
|
// }
|
||||||
|
</style>
|
|
@ -0,0 +1,52 @@
|
||||||
|
<template>
|
||||||
|
<!-- <div @click="onPlay">点击开始播放(连接)直播</div>
|
||||||
|
<div @click="onPlay2">点击开始播放(连接)直播2</div> -->
|
||||||
|
<!-- <div>{{ route.query.url }}</div> -->
|
||||||
|
<!-- 使用webRTC-streamer播放rtsp流,但是没有声音。。。 -->
|
||||||
|
<bVideo ref="bVideoRef"/>
|
||||||
|
<!-- <video id="video" muted="" playsinline="" controls="" style="opacity: 1;"></video> -->
|
||||||
|
<!-- <video id="myVideo" class="video-js vjs-default-skin vjs-big-play-centered" controls autoplay data-setup='{}' style='width: 100%;height: auto'>
|
||||||
|
<source id="source" src="http://127.0.0.1/01.m3u8" type="application/x-mpegURL"/>
|
||||||
|
</video> -->
|
||||||
|
</template>
|
||||||
|
<script lang="ts" setup>
|
||||||
|
import { ref, onMounted, onBeforeUnmount} from 'vue';
|
||||||
|
import { useRoute } from 'vue-router'
|
||||||
|
import bVideo from '/@/views/site/common/webRTC/video.vue';
|
||||||
|
|
||||||
|
|
||||||
|
const bVideoRef = ref();
|
||||||
|
|
||||||
|
const route = useRoute();
|
||||||
|
|
||||||
|
//页面销毁时销毁webRtc
|
||||||
|
onBeforeUnmount(() => {
|
||||||
|
bVideoRef.value.closeWebRtcStreamerFn();
|
||||||
|
})
|
||||||
|
|
||||||
|
onMounted(() => {
|
||||||
|
if(route.query.url){
|
||||||
|
bVideoRef.value.connectFn(route.query.url);
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
// onMounted(() => {
|
||||||
|
// var myVideo = videojs('myVideo', {
|
||||||
|
// bigPlayButton: true,
|
||||||
|
// textTrackDisplay: false,
|
||||||
|
// posterImage: false,
|
||||||
|
// errorDisplay: false,
|
||||||
|
// })
|
||||||
|
// myVideo.play()
|
||||||
|
// })
|
||||||
|
|
||||||
|
</script>
|
||||||
|
<style lang="less" scoped>
|
||||||
|
video {
|
||||||
|
//margin: auto;
|
||||||
|
//left: 0;
|
||||||
|
//right: 0;
|
||||||
|
//position: relative;
|
||||||
|
background: grey;
|
||||||
|
}
|
||||||
|
</style>
|
|
@ -4,6 +4,9 @@
|
||||||
<!-- <div>{{ route.query.url }}</div> -->
|
<!-- <div>{{ route.query.url }}</div> -->
|
||||||
<bVideo ref="bVideoRef"/>
|
<bVideo ref="bVideoRef"/>
|
||||||
<!-- <video id="video" muted="" playsinline="" controls="" style="opacity: 1;"></video> -->
|
<!-- <video id="video" muted="" playsinline="" controls="" style="opacity: 1;"></video> -->
|
||||||
|
<!-- <video id="myVideo" class="video-js vjs-default-skin vjs-big-play-centered" controls autoplay data-setup='{}' style='width: 100%;height: auto'>
|
||||||
|
<source id="source" src="http://127.0.0.1/01.m3u8" type="application/x-mpegURL"/>
|
||||||
|
</video> -->
|
||||||
</template>
|
</template>
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { ref, onMounted, onBeforeUnmount} from 'vue';
|
import { ref, onMounted, onBeforeUnmount} from 'vue';
|
||||||
|
|
Loading…
Reference in New Issue