mkl_power_box/components/mklVideoPlay1.0.2.js

758 lines
31 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

/**
* 该播放器支持H5stream、hls、rtmp
* 需要引用以下JS
*
<!-- VUE依赖 -->
<script src="https://cdn.makalu.cc/js/vue/vue.js"></script>
<!-- 请求依赖 -->
<script src="https://cdn.makalu.cc/js/axios/axios.min.js"></script>
<!-- rtmp 支持依赖 -->
<script src="https://cdn.makalu.cc/js/videojs/5.19/video.min.js"></script>
<!-- hls 支持依赖 -->
<script src="https://cdn.makalu.cc/js/hls/hls.min.js"></script>
<!-- h5steam 支持依赖 -->
<script src="https://cdn.makalu.cc/js/platform/1.3.5/platform.js"></script>
<script src="https://cdn.makalu.cc/js/h5splayer/h5splayer.js"></script>
<script src="https://cdn.makalu.cc/js/h5splayer/h5splayerhelper.js"></script>
* 使用:
* <mkl-video-play></mkl-video-play>
* param
* token: 视频token
* type: 类型h5s/hls/rtmp
* width: 播放界面宽当宽度小于600时不启用云台控制
* height: 播放界面高
* outTime: 超时检测时间单位用于hls和rtmpm默认是10秒
*/
Vue.component("mkl-video-play", {
template: `
<div :style="playDivCss">
<video v-if="type != 'hk' && type != 'hzhk' && !exception" ref="playDiv"
style="height: 100%;width: 100%"
@click="play"
controls
autoplay
muted
webkit-playsinline
playsinline></video>
<div v-if="(type == 'hk' || type == 'hzhk') && !exception" id="HKPlayWindowControl" style="height: 100%;width: 100%;text-align: center;background-color: #000000;color: #FFFFFF"">
<div v-show="restartInit"><br/><br/><br/>插件未启动,正在尝试启动,请稍候...</div>
<div v-show="initError">
<br/><br/><br/>
<p>插件启动失败,请检查插件是否安装!</p>
<p>该插件只能用于window系统</p>
<el-link type="primary" href="https://file-other.makalu.cc/%E6%8F%92%E4%BB%B6/VideoWebPlugin.exe">
点击这里下载播放组件
</el-link>
<p>插件安装成功后刷新当前页面!</p>
</div>
</div>
<!-- <video v-else-if="type === 'hls' && !exception" ref="playDiv"
@click="play"
style="height: 100%;width: 100%"
autoplay
muted
controls="true"></video>
<video v-else-if="type === 'rtmp' && !exception" ref="playDiv"
style="height: 100%;width: 100%"
class="video-js vjs-default-skin vjs-big-play-centered" controls
preload="auto"
@click="play"
muted
autoplay="autoplay"
data-setup='{}'>
</video>-->
<div v-if="exception" :style="exStyle">
<img style="width: 100%;height: 100%" src="http://file-other.makalu.cc/icon/videoEx.jpg"/>
</div>
<div style="
position: absolute;
right: 0px;
top: 10px;
background-color: black;
color: azure;
padding: 10px;
border-top-left-radius: 5px;
border-bottom-left-radius: 5px;
font-size: 12px" v-if="ptz">
<span @click="openPTZ = !openPTZ" style="cursor: pointer;margin-right: 10px">云台控制</span>
<img style="width: 15px;height: 15px;cursor: pointer" @click="fullScreenFun"
:src="'http://file-other.makalu.cc/icon' + (fullScreenShow ? '/no-full-screen-icon.png':'/full-screen-icon.png')"/>
</div>
<div v-show="openPTZ" style="position: absolute;bottom: 0px;right: 0px;">
<div :style="PTZDiv">
<div :style="PTZTop" @mousedown="tripodHandle('UP')" @mouseup="stop"></div>
<div :style="PTZBottom" @mousedown="tripodHandle('DOWN')" @mouseup="stop"></div>
<div :style="PTZLeft" @mousedown="tripodHandle('LEFT')" @mouseup="stop"></div>
<div :style="PTZRight" @mousedown="tripodHandle('RIGHT')" @mouseup="stop"></div>
</div>
<br/>
<div>
<button :style="VIBtnCss" @mousedown="tripodHandle('zoomout')" @mouseup="stop">-
</button>
<button :style="zoomViewCss"> 焦 距</button>
<button :style="VIBtnCss" @mousedown="tripodHandle('zoomin')" @mouseup="stop">+</button>
</div>
<br/>
<!-- <div>
<button :style="VIBtnCss" onclick="tripodHandle('ZOOM_OUT')">-
</button>
<button :style="zoomViewCss"> 微 距</button>
<button :style="VIBtnCss" onclick="tripodHandle('ZOOM_IN')">+</button>
</div>-->
</div>
<mkl-video-play
v-if="fullScreen && fullScreenShow"
@fullScreenFun="fullScreenCloseFun"
style="position: fixed;top:0;left: 0;z-index: 998"
:token="token" :type="type"
:width="fullScreenWidth"
:height="fullScreenHeight" :ptz="true" :fullScreen="false"></mkl-video-play>
</div>
`,
props: {
//视频token
"token": {
type: String,
default: ""
},
//播放器类型
"type": {
type: String,
default: "hls"
},
//播放器宽
"width": {
type: Number / String,
default: 320
},
//播放器高
"height": {
type: Number / String,
default: 240
},
//超时时间
"outTime": {
type: Number,
default: 10
},
//是否显示云台控制
"ptz": {
type: Boolean,
default: false
},
//是否启用全屏
"fullScreen": {
type: Boolean,
default: true
},
//是否启用自动重连
"restart": {
type: Boolean,
default: true
},
"openOrClose": {
type: String,
default: "open"
}
},
data() {
return {
isplay: true,
videoHost: "http://video.makalu.cc",
h5s: "",
hls: new Hls(),
hlsvideo: undefined,
rtmpVideo: "",
exception: false,
exMsg: "数据加载异常,请刷新重试...",
openPTZ: false,
fullScreenShow: false,
fullScreenWidth: "0px",
fullScreenHeight: "0px",
timeoutDetection: undefined,
timeoutDetectionInit: undefined,
initCount: 0,
pubKey: "",
restartInit: false,
initError: false,
oWebControl: undefined
}
},
methods: {
clearContext() {
try{
if (this.oWebControl && this.oWebControl != null) {
this.oWebControl.JS_HideWnd(); // 先让窗口隐藏,规避可能的插件窗口滞后于浏览器消失问题
this.oWebControl.JS_Disconnect().then(function () {
// 断开与插件服务连接成功
},
function () {
// 断开与插件服务连接失败
}
);
}
}catch(e){console.log(e)}
if (this.$refs.playDiv) {
this.$refs.playDiv.removeAttribute("poster")
}
try {
if (this.hls) {
this.hls.destroy()
}
} catch (e) {
console.log(e);
}
try {
if (this.h5s) {
H5sPlayerWS.prototype.disconnect
this.h5s.disconnect()
}
} catch (e) {
console.log(e)
}
this.hls = new Hls()
},
initH5sPlay() {
let that = this
let host = window.location.protocol == "https:" ? "47.106.234.91:8443" :"47.106.234.91:8080"
axios.post(that.videoHost + "/mkl/api/h5sLogin", {}).then(res => {
let conf = {
videodom: that.$refs.playDiv,
protocol: window.location.protocol,
host: "h5s.makalu.cc",
rootpath: '/',
token: that.token,
hlsver: 'v1',
session: res.data
}
that.$refs.playDiv.setAttribute("autoplay", "autoplay")
that.h5s = H5sPlayerCreate(conf)
that.h5s.connect()
that.timeoutDetectionFun()
})
},
initHlsPlay() {
this.hlsvideo = this.$refs.playDiv;
this.hls.destroy()
this.hls = new Hls()
let that = this
axios.post(this.videoHost + "/ca/isc/info/getPlay", {
protocol: "hls",
playAdder: that.token
}).then(res => {
if (res.data.code != "200") {
that.exception = true
setTimeout(function () {
that.init()
}, 2000)
} else {
that.hls.loadSource(eval("(" + res.data.data + ")").url);
that.hls.attachMedia(that.hlsvideo);
that.hls.on(Hls.Events.MANIFEST_PARSED, function () {
that.hlsvideo.play();
})
}
that.timeoutDetectionFun()
}).catch(err => {
that.exception = true
})
},
initRtmpPlay() {
let that = this
let video = this.$refs.playDiv
axios.post(this.videoHost + "/ca/isc/info/getPlay", {
protocol: "rtmp",
playAdder: that.token
}).then(res => {
if (res.data.code != "200") {
that.exception = true
setTimeout(function () {
that.init()
}, 2000)
} else {
const videoParam = [{
type: "video/rtmp",
src: eval("(" + res.data.data + ")").url
}];
that.rtmpVideo = videojs(video)
that.rtmpVideo.ready(function () {
that.rtmpVideo.src(videoParam)
that.rtmpVideo.load()
that.rtmpVideo.play()
})
that.timeoutDetectionFun()
}
}).catch(err => {
that.exception = true
})
},
play() {
if (this.type === "h5s") {
if (this.isplay) {
this.h5s.disconnect()
} else {
this.h5s.connect();
}
this.isplay = !this.isplay
}
if (this.type === "hls") {
if (this.isplay) {
this.hlsvideo.stop()
} else {
this.hlsvideo.play()
}
this.isplay = !this.isplay
}
if (this.type === "rtmp") {
if (this.isplay) {
this.rtmpVideo.pause()
} else {
this.rtmpVideo.play()
}
this.isplay = !this.isplay
}
},
guid() {
function S4() {
return (((1 + Math.random()) * 0x10000) | 0).toString(16).substring(1);
}
return (S4() + S4() + S4() + S4() + S4() + S4() + S4() + S4());
},
settingVideoHost() {
this.videoHost = window.location.protocol + "//video.makalu.cc"
},
init() {
let that = this
this.exception = false
this.clearContext()
this.$nextTick(function () {
switch (that.type) {
case "h5s":
that.initH5sPlay()
break
case "hls":
that.initHlsPlay()
break
case "rtmp":
that.initRtmpPlay()
break
case "hk":
that.initPlugin("24476525","hrFzLaMbo60QDvwazqdH","8.129.144.255",1443);
that.windowInitFun();
break
case "hzhk":
that.initPlugin("21332599","772SPtFNM1BHMyKHq4xh","39.101.132.124",443);
that.windowInitFun();
break
}
})
},
tripodHandle(order) {
axios.post(this.videoHost + "/mkl/api/moveCamera", {
token: this.token,
action: this.type === "h5s" ? order.toLowerCase() : order,
h5s: this.type == "h5s"
})
console.log("按下")
},
stop() {
axios.post(this.videoHost + "/mkl/api/moveCamera", {
token: this.token,
action: "stop",
h5s: this.type == "h5s"
})
console.log("松开")
},
fullScreenCss() {
this.fullScreenWidth = (document.body.scrollWidth - 10) + "px"
this.fullScreenHeight = (document.body.scrollHeight - 10) + "px"
},
fullScreenFun() {
this.fullScreenShow = true
this.$emit("fullScreenFun")
},
fullScreenCloseFun() {
this.fullScreenShow = false
},
timeoutDetectionFun() {
let that = this
//超时时间检测是否正常获取到数据流默认为5秒
this.timeoutDetection = setTimeout(function () {
if (parseInt(that.hlsvideo.currentTime.toFixed(1)) == 0) {
that.hls.destroy()
that.exception = true
if (that.restart) {
that.timeoutDetectionInit = setTimeout(function () {
that.init()
}, 2000)
}
}
}, this.outTime * 1000)
},
//海康插件开始
// 创建播放实例
initPlugin(appkey,secret,ip,port) {
let that = this
that.oWebControl = new WebControl({
szPluginContainer: "uuid", // 指定容器id
iServicePortStart: 15900, // 指定起止端口号,建议使用该值
iServicePortEnd: 15909,
szClassId: "23BF3B0A-2C56-4D97-9C03-0CB103AA8F11", // 用于IE10使用ActiveX的clsid
cbConnectSuccess: function () { // 创建WebControl实例成功
that.oWebControl.JS_StartService("window", { // WebControl实例创建成功后需要启动服务
dllPath: "./VideoPluginConnect.dll" // 值"./VideoPluginConnect.dll"写死
}).then(function () { // 启动插件服务成功
that.oWebControl.JS_SetWindowControlCallback({ // 设置消息回调
cbIntegrationCallBack: that.cbIntegrationCallBack
});
that.oWebControl.JS_CreateWnd("HKPlayWindowControl", Number(that.width.replaceAll("px","")), Number(that.height.replaceAll("px",""))).then(function () { //JS_CreateWnd创建视频播放窗口宽高可设定
that.initHKPlay(appkey,secret,ip,port); // 创建播放实例成功后初始化
});
}, function () { // 启动插件服务失败
});
},
cbConnectError: function () { // 创建WebControl实例失败
this.oWebControl = null;
that.restartInit = true
WebControl.JS_WakeUp("VideoWebPlugin://"); // 程序未启动时执行error函数采用wakeup来启动程序
that.initCount++;
if (that.initCount < 3) {
setTimeout(function () {
that.initPlugin(appkey,secret,ip,port);
}, 3000)
} else {
that.restartInit = false
that.initError = true
that.initCount = 0
}
},
cbConnectClose: function (bNormalClose) {
// 异常断开bNormalClose = false
// JS_Disconnect正常断开bNormalClose = true
console.log("cbConnectClose");
this.oWebControl = null;
}
});
},
// 设置窗口控制回调
setCallbacks() {
let that = this
that.oWebControl.JS_SetWindowControlCallback({
cbIntegrationCallBack: that.cbIntegrationCallBack
});
},
// 推送消息
cbIntegrationCallBack(oData) {
console.log(JSON.stringify(oData.responseMsg));;
},
//初始化
initHKPlay(Appkey,Secret,Ip,Port) {
let that = this
this.getPubKey(function () {
////////////////////////////////// 请自行修改以下变量值 ////////////////////////////////////
let appkey = Appkey; //综合安防管理平台提供的appkey必填
let secret = that.setEncrypt(Secret); //综合安防管理平台提供的secret必填
let ip = Ip; //综合安防管理平台IP地址必填
let playMode = 0; //初始播放模式0-预览1-回放
let port = Port; //综合安防管理平台端口若启用HTTPS协议默认443
let snapDir = "D:\\SnapDir"; //抓图存储路径
let videoDir = "D:\\VideoDir"; //紧急录像或录像剪辑存储路径
let layout = "1x1"; //playMode指定模式的布局
let enableHTTPS = 1; //是否启用HTTPS协议与综合安防管理平台交互这里总是填1
let encryptedFields = 'secret'; //加密字段默认加密领域为secret
let showToolbar = 1; //是否显示工具栏0-不显示非0-显示
let showSmart = 1; //是否显示智能信息如配置移动侦测后画面上的线框0-不显示非0-显示
let buttonIDs = "0,16,256,257,258,259,260,512,513,514,515,516,517,768,769"; //自定义工具条按钮
let toolBarButtonIDs = "4098";
////////////////////////////////// 请自行修改以上变量值 ////////////////////////////////////
that.oWebControl.JS_RequestInterface({
funcName: "init",
argument: JSON.stringify({
appkey: appkey, //API网关提供的appkey
secret: secret, //API网关提供的secret
ip: ip, //API网关IP地址
playMode: playMode, //播放模式(决定显示预览还是回放界面)
port: port, //端口
snapDir: snapDir, //抓图存储路径
videoDir: videoDir, //紧急录像或录像剪辑存储路径
layout: layout, //布局
enableHTTPS: enableHTTPS, //是否启用HTTPS协议
encryptedFields: encryptedFields, //加密字段
showToolbar: showToolbar, //是否显示工具栏
showSmart: showSmart, //是否显示智能信息
buttonIDs: buttonIDs, //自定义工具条按钮
toolBarButtonIDs:toolBarButtonIDs
})
}).then(function (oData) {
that.oWebControl.JS_Resize(Number(that.width.replaceAll("px","")), Number(that.height.replaceAll("px",""))); // 初始化后resize一次规避firefox下首次显示窗口后插件窗口未与DIV窗口重合问题
that.startPreviewFun()
});
});
},
//获取公钥
getPubKey(callback) {
let that = this
that.oWebControl.JS_RequestInterface({
funcName: "getRSAPubKey",
argument: JSON.stringify({
keyLength: 1024
})
}).then(function (oData) {
console.log(oData);
if (oData.responseMsg.data) {
that.pubKey = oData.responseMsg.data;
callback()
}
})
},
//RSA加密
setEncrypt(value) {
let encrypt = new JSEncrypt();
encrypt.setPublicKey(this.pubKey);
return encrypt.encrypt(value);
},
// 设置窗口裁剪当因滚动条滚动导致窗口需要被遮住的情况下需要JS_CuttingPartWindow部分窗口
setWndCover() {
let that = this
let iWidth = $(window).width();
let iHeight = $(window).height();
let oDivRect = document.getElementById("HKPlayWindowControl").getBoundingClientRect();
let iCoverLeft = (oDivRect.left < 0) ? Math.abs(oDivRect.left) : 0;
let iCoverTop = (oDivRect.top < 0) ? Math.abs(oDivRect.top) : 0;
let iCoverRight = (oDivRect.right - iWidth > 0) ? Math.round(oDivRect.right - iWidth) : 0;
let iCoverBottom = (oDivRect.bottom - iHeight > 0) ? Math.round(oDivRect.bottom - iHeight) : 0;
iCoverLeft = (iCoverLeft > 1000) ? 1000 : iCoverLeft;
iCoverTop = (iCoverTop > 600) ? 600 : iCoverTop;
iCoverRight = (iCoverRight > 1000) ? 1000 : iCoverRight;
iCoverBottom = (iCoverBottom > 600) ? 600 : iCoverBottom;
that.oWebControl.JS_RepairPartWindow(0, 0, 1001, 600); // 多1个像素点防止还原后边界缺失一个像素条
if (iCoverLeft != 0) {
that.oWebControl.JS_CuttingPartWindow(0, 0, iCoverLeft, 600);
}
if (iCoverTop != 0) {
that.oWebControl.JS_CuttingPartWindow(0, 0, 1001, iCoverTop); // 多剪掉一个像素条,防止出现剪掉一部分窗口后出现一个像素条
}
if (iCoverRight != 0) {
that.oWebControl.JS_CuttingPartWindow(1000 - iCoverRight, 0, iCoverRight, 600);
}
if (iCoverBottom != 0) {
that.oWebControl.JS_CuttingPartWindow(0, 600 - iCoverBottom, 1000, iCoverBottom);
}
},
windowInitFun() {
let that = this
// 监听resize事件使插件窗口尺寸跟随DIV窗口变化
$(window).resize(function () {
if (that.oWebControl != null) {
that.oWebControl.JS_Resize(Number(that.width.replaceAll("px","")), Number(that.height.replaceAll("px","")));
that.setWndCover();
}
});
// 监听滚动条scroll事件使插件窗口跟随浏览器滚动而移动
$(window).scroll(function () {
if (that.oWebControl != null) {
that.oWebControl.JS_Resize(Number(that.width.replaceAll("px","")), Number(that.height.replaceAll("px","")));
that.setWndCover();
}
});
// 标签关闭
window.onunload = function () {
if (that.oWebControl != null) {
that.oWebControl.JS_HideWnd(); // 先让窗口隐藏,规避可能的插件窗口滞后于浏览器消失问题
that.oWebControl.JS_Disconnect().then(function () { // 断开与插件服务连接成功
},
function () { // 断开与插件服务连接失败
});
}
}
},
//视频预览功能
startPreviewFun() {
let that = this
let streamMode = 0; //主子码流标识0-主码流1-子码流
let transMode = 1; //传输协议0-UDP1-TCP
let gpuMode = 0; //是否启用GPU硬解0-不启用1-启用
let wndId = -1; //播放窗口序号在2x2以上布局下可指定播放窗口
let cameraIndexCode = this.token
cameraIndexCode = cameraIndexCode.replace(/(^\s*)/g, "");
cameraIndexCode = cameraIndexCode.replace(/(\s*$)/g, "");
that.oWebControl.JS_RequestInterface({
funcName: "startPreview",
argument: JSON.stringify({
cameraIndexCode: cameraIndexCode, //监控点编号
streamMode: streamMode, //主子码流标识
transMode: transMode, //传输协议
gpuMode: gpuMode, //是否开启GPU硬解
wndId: wndId //可指定播放窗口
})
})
},
//停止全部预览
stopAllPreviewFun() {
this.oWebControl.JS_RequestInterface({
funcName: "stopAllPreview"
});
},
closeHk(){
this.oWebControl.JS_HideWnd(); // 先让窗口隐藏,规避可能的插件窗口滞后于浏览器消失问题
this.oWebControl.JS_Disconnect().then(function(){}, function() {});
}
},
mounted() {
console.log(this.openOrClose)
},
computed: {
playDivCss() {
return {
width: (this.width + "").replace("px", "") + "px",
height: (this.height + "").replace("px", "") + "px",
position: "relative"
}
},
exStyle() {
return {
textAlign: "center",
width: (this.width + "").replace("px", "") + "px",
height: (this.height + "").replace("px", "") + "px"
}
},
PTZDiv() {
let W = parseInt((this.width + "").replace("px", ""))
let H = parseInt((this.height + "").replace("px", ""))
if (W < 400) {
W = "100px"
H = "100px"
} else {
W = "150px"
H = "150px"
}
return {
backgroundImage: "url('http://video.makalu.cc/img/jt.png')",
width: W,
height: H,
backgroundSize: "100%",
position: "relative"
}
},
PTZTop() {
return {
width: "33%",
height: "25%",
position: "absolute",
top: "0px",
left: "33%",
cursor: "pointer"
}
},
PTZBottom() {
return {
width: "33%",
height: "25%",
position: "absolute",
bottom: "0px",
left: "33%",
cursor: "pointer"
}
},
PTZLeft() {
return {
width: "25%",
height: "33%",
position: "absolute",
top: "33%",
left: "0px",
cursor: "pointer"
}
},
PTZRight() {
return {
width: "25%",
height: "33%",
position: "absolute",
top: "33%",
right: "0px",
cursor: "pointer"
}
},
VIBtnCss() {
return {
width: "30px",
height: "30px",
background: "#38314b",
border: "1px solid #38314b",
fontSize: "20px",
outline: "0",
color: "#FFFFFF"
}
},
zoomViewCss() {
return {
width: "75px",
height: "30px",
color: "#dddddd",
background: "rgba(65, 63, 70, 0.5)",
textAlign: "center",
border: "0px solid rgba(65, 63, 70, 0.5)",
outline: "0",
fontSize: "14px"
}
}
},
watch: {
token: function (now, old) {
console.log(now)
if (this.timeoutDetection) {
clearTimeout(this.timeoutDetection)
clearTimeout(this.timeoutDetectionInit)
}
if (!now) {
if (this.oWebControl != null) {
this.oWebControl.JS_HideWnd(); // 先让窗口隐藏,规避可能的插件窗口滞后于浏览器消失问题
this.oWebControl.JS_Disconnect().then(function () { // 断开与插件服务连接成功
},
function () { // 断开与插件服务连接失败
});
}
}else{
this.init()
}
},
openOrClose:function (n,o) {
console.log(n)
if(n == 'close'){
this.closeHk()
}else{
if (this.type != "hk") {
this.settingVideoHost()
this.init()
this.fullScreenCss()
} else {
this.initPlugin();
this.windowInitFun();
}
}
}
}
})