播放h265流解决方案
文中代码:https://github.com/moxiefxj/video_vue
1. 视频WEB插件
- 视频WEB插件,下载的压缩包中含有播放监控所需要的插件、开发的demo等。
- 在项目中具体的实现(以vue组件实现为例)
<template><!--视频窗口展示--><div :id="id"></div>
</template>
<script>
export default {name: "hkVideo",data() {return {// 视频播放initCount: 0, // 初始化重试次数,3次失败则报错oWebControl: null, // 页面控制对象pubKey: "",cameraIp: "xxx.xxx.xx.xx", // 综合安防管理平台IP地址};},props: ["code", "id"], // 接收父页面传来的摄像头 codemethods: {// 创建播放实例initPlugin() {// 初始化播放插件const _this = this;_this.oWebControl = new WebControl({szPluginContainer: _this.id, // 指定容器idiServicePortStart: 15900, // 指定起止端口号,建议使用该值iServicePortEnd: 15909,szClassId: "23BF3B0A-2C56-4D97-9C03-0CB103AA8F11", // 用于IE10使用ActiveX的clsidcbConnectSuccess: function () {// 创建WebControl实例成功console.log("创建WebControl实例成功");_this.oWebControl.JS_StartService("window", {// WebControl实例创建成功后需要启动服务dllPath: "./VideoPluginConnect.dll", // 值"./VideoPluginConnect.dll"写死}).then(function () {// 启动插件服务成功console.log("启动插件服务成功");_this.oWebControl.JS_SetWindowControlCallback({// 设置消息回调cbIntegrationCallBack: _this.cbIntegrationCallBack,});let divWidth = document.getElementById(_this.id).scrollWidth;let divHeight = document.getElementById(_this.id).scrollHeight;_this.oWebControl.JS_CreateWnd(_this.id, divWidth, divHeight).then(function () {//JS_CreateWnd创建视频播放窗口,宽高可设定_this.init(); // 创建播放实例成功后初始化});},function () {// 启动插件服务失败});},cbConnectError: function () {// 创建WebControl实例失败_this.oWebControl = null;console.log("warn,插件未启动,正在尝试启动,请稍候...");WebControl.JS_WakeUp("VideoWebPlugin://"); // 程序未启动时执行error函数,采用wakeup来启动程序initCount++;if (initCount < 3) {setTimeout(function () {_this.initPlugin();}, 3000);} else {console.log("error, 插件启动失败,请检查插件是否安装!");}},cbConnectClose: function (bNormalClose) {// 异常断开:bNormalClose = false// JS_Disconnect正常断开:bNormalClose = trueif (!bNormalClose) {console.log("error, 视屏链接异常中断!");}_this.oWebControl = null;},});},//初始化, 主要改这里init() {const _this = this;this.getPubKey(function () {// 请自行修改以下变量值let appkey = "xxxxxxx"; //综合安防管理平台提供的appkey,必填let secret = _this.setEncrypt("xxxxxxxxxx"); //综合安防管理平台提供的secret,必填let ip = _this.cameraIp; //综合安防管理平台IP地址,必填let playMode = 0; //初始播放模式:0-预览,1-回放let port = 8443; //综合安防管理平台端口,若启用HTTPS协议,默认443let snapDir = "D:\\SnapDir"; //抓图存储路径let videoDir = "D:\\VideoDir"; //紧急录像或录像剪辑存储路径let layout = "1x1"; //playMode指定模式的布局let enableHTTPS = 1; //是否启用HTTPS协议与综合安防管理平台交互,这里总是填1let encryptedFields = "secret"; //加密字段,默认加密领域为secretlet showToolbar = 0; //是否显示工具栏,0-不显示,非0-显示let showSmart = 1; //是否显示智能信息(如配置移动侦测后画面上的线框),0-不显示,非0-显示let buttonIDs = ""; //自定义工具条按钮// 请自行修改以上变量值_this.oWebControl.JS_RequestInterface({funcName: "init",argument: JSON.stringify({appkey: appkey, //API网关提供的appkeysecret: secret, //API网关提供的secretip: ip, //API网关IP地址playMode: playMode, //播放模式(决定显示预览还是回放界面)port: port, //端口snapDir: snapDir, //抓图存储路径videoDir: videoDir, //紧急录像或录像剪辑存储路径layout: layout, //布局enableHTTPS: enableHTTPS, //是否启用HTTPS协议encryptedFields: encryptedFields, //加密字段showToolbar: showToolbar, //是否显示工具栏showSmart: showSmart, //是否显示智能信息buttonIDs: buttonIDs, //自定义工具条按钮}),}).then((oData) => {let divWidth = document.getElementById(_this.id).scrollWidth;let divHeight = document.getElementById(_this.id).scrollHeight;_this.oWebControl.JS_Resize(divWidth, divHeight); // 初始化后resize一次,规避firefox下首次显示窗口后插件窗口未与DIV窗口重合问题_this.startPreview();});});},//获取公钥, 不用改getPubKey(callback) {this.oWebControl.JS_RequestInterface({funcName: "getRSAPubKey",argument: JSON.stringify({keyLength: 1024,}),}).then((oData) => {if (oData.responseMsg.data) {this.pubKey = oData.responseMsg.data;callback();}});},//RSA加密, 不用改setEncrypt(value) {let encrypt = new JSEncrypt();encrypt.setPublicKey(this.pubKey);return encrypt.encrypt(value);},//视频预览功能, 就设置 cameraIndexCode 就行了startPreview() {let _this = this;let cameraIndexCode = _this.code; //获取输入的监控点编号值,必填let streamMode = 0; //主子码流标识:0-主码流,1-子码流let transMode = 1; //传输协议:0-UDP,1-TCPlet gpuMode = 0; //是否启用GPU硬解,0-不启用,1-启用let wndId = -1; //播放窗口序号(在2x2以上布局下可指定播放窗口)cameraIndexCode = cameraIndexCode.replace(/(^\s*)/g, "");cameraIndexCode = cameraIndexCode.replace(/(\s*$)/g, "");_this.oWebControl.JS_RequestInterface({funcName: "startPreview",argument: JSON.stringify({cameraIndexCode: cameraIndexCode, //监控点编号streamMode: streamMode, //主子码流标识transMode: transMode, //传输协议gpuMode: gpuMode, //是否开启GPU硬解wndId: wndId, //可指定播放窗口}),});},//停止全部预览stopAlldwPreview() {this.oWebControl.JS_RequestInterface({funcName: "stopAllPreview",});},destroyedView() {if (this.oWebControl != null) {this.stopAlldwPreview();this.oWebControl.JS_HideWnd(); // 先让窗口隐藏,规避可能的插件窗口滞后于浏览器消失问题this.oWebControl.JS_Disconnect().then(function () {// 断开与插件服务连接成功},function () {// 断开与插件服务连接失败});}},},mounted() {// 有摄像头 code, 才加载, 另外因为我每次只显示一个, 所以显示之前要把之前显示的摄像头销毁, 所以加了 this.oWebControl == null 的判断.if (this.cameraIndexCode && this.oWebControl == null) {this.initPlugin();} else {// 如果 code 不为空, 则先销毁现有摄像头, 再去加载新的摄像头this.destroyedView();setTimeout(this.initPlugin(), 1000);}},destroyed() {this.destroyedView();},
};
</script>
2. h5player播放
- H5视频播放器开发包,开发包中含有demo和开发文档
- 需要先将开发包中的js导入到项目根目录中
- 相关组件代码示例:
<template><div :id="id"></div>
</template>
<script>
export default {data() {return {oPlugin: null,iWind: 0,curIndex: 0,};},props: ["id", "code"],mounted() {this.init();},methods: {init() {this.oPlugin = new JSPlugin({szId: this.id,szBasePath: "./",oStyle: {border: "#343434",borderSelect: "#FFCC00",background: "#000",},openDebug: true,});this.initPlugin();},initPlugin() {this.oPlugin.JS_SetWindowControlCallback({windowEventSelect: function (iWndIndex) {//插件选中窗口回调this.iWind = iWndIndex;console.log(iWndIndex);},pluginErrorHandler: function (iWndIndex, iErrorCode, oError) {//插件错误回调console.error(`window-${iWndIndex}, errorCode: ${iErrorCode}`,oError);},windowEventOver: function (iWndIndex) {//鼠标移过回调//console.log(iWndIndex);},windowEventOut: function (iWndIndex) {//鼠标移出回调//console.log(iWndIndex);},windowEventUp: function (iWndIndex) {//鼠标mouseup事件回调//console.log(iWndIndex);},windowFullCcreenChange: function (bFull) {//全屏切换回调console.log(bFull);},firstFrameDisplay: function (iWndIndex, iWidth, iHeight) {//首帧显示回调console.log(iWndIndex, iWidth, iHeight);},performanceLack: function () {//性能不足回调console.log("ddiwduw");},});this.oPlugin.JS_SetOptions({// bSupportSound: false //是否支持音频,默认支持// bSupporDoubleClickFull: false //是否双击窗口全屏,默认支持// bOnlySupportMSE: true //只支持MSE// bOnlySupportJSDecoder: true //只支持JSDecoder}).then(() => {// 这里需要请求后端地址 最好为ws流.this.realplay();});},realplay() {let url = "ws://xxxxxxxxxxxxxxx";this.oPlugin.JS_Play(url,{playURL: url,mode: 1,},this.curIndex).then(function () {console.log("realplay success");},function () {console.log("realplay failed");});},resizePlay(index) {this.oPlugin.JS_Resize(500, 300).then(() => {console.info("JS_Resize success");// do you want...},(err) => {console.info("JS_Resize failed");// do you want...});},},
};
</script>