萤石云文档(web开发)
萤石云DEMO下载
参考博客:vue中实现视频直播(萤石云) - 简书
参考博客:海康威视&萤石摄像头直播/监控模式Vue开发 - 简书
萤石云web开发文档短小易懂,一定要看(文档变更有点乱,我看的时候api部分已被移除,故参考了简书博客)
前提了解
兼容性
- Chrome 55+
- Firefox 55+
- 最新IE
直播与视频监控开发区别
- 直播可使用第三方播放器如video标签等;而视频监控不可
- 直播可使用https开头链接;而视频监控不可,视频监控使用萤石云协议(ezopen://)
视频监控链接地址特征
- 预览:ezopen:// [验证码@] open.ys7.com/[deviceSerial]/[channelNo] [.hd].live(示例:ezopen://open.ys7.com/203751922/1.hd.live)
- 回放:ezopen:// [验证码@] open.ys7.com/[deviceSerial]/[channelNo] [.hd].rec[?begin= yyyyMMddhhmmss&end= yyyyMMddhhmmss](ezopen://验证码@open.ys7.com/203751922/1.rec?begin=20190317000000&begin=20190317235959)
tips:
回放地址不带时间参数时默认取当日0时0分0秒至23时59分59秒,缺省也同样会自动补充,比如begin=2019031709,系统会自动给补充为begin=20190317090000&end=20190317235959
回放时间点是否存在录像可以通过调用根据时间获取存储文件信息接口(链接)来查询验证
多窗口模式
- 从文档中只看到多窗口只针对监控
- 多窗口监控地址通过逗号分隔
- 窗口切割参数:splitBasis
//在监控模式中设置窗口切割参数(1*1,2*2,3*3) var player = new EZUIPlayer({id: 'myPlayer',url: {url0},{url1},{url2},{url3}, // ezopen播放地址逗号分隔autoplay: true,accessToken: "at.8o2k6dbpcvtr13reaa96hbnya6*************c",decoderPath: '{{location path}}',width: 1200, // 宽度高度为容器规格,将按照窗口数均分height: 800,splitBasis: 2 //设置窗口切割参数});
包引入区别
- js原生引入方式,示例:
<script src="../ezuikit.js"></script> <script src="../js/jquery.min.js"></script>
- node构建,示例
npm install ezuikit-js//当前使用的文件引入 import EZUIKit from 'ezuikit-js';
ezuikit-js源码了解(主要是播放器模板的区别)
- simple(极简版)
- standard(标准版)
- security(安防版(预览回放))
- voice(语音版)
1.其中simple最适合用来自定义,ezuikit-js中的大部分代码都是simple的,当给simple进行header,footer等配置时,不满意,可以在源码中进行更改,该源码只有js代码,html和css皆由js来生成,与其通过配置来对simple进行改变,不如对simple自定义(由参考博客1可知萤石云大部分api非常方便使用)
2.standard/security/voice,这是三种固定模板,无法进行配置(由源码可知:本地并无此三种模板的代码,代码在萤石云服务器上),若需对此三种模板进行样式等变更,则需要对不同源iframe进行操作(麻烦)
开发(只包含视频监控)
1.npm包引入 ezuikit-js
2.根据公司需求和对上述前提的了解,我选择了对simple进行自定义
代码:
//组件:萤石云视频监控simple自定义<template><div class="hello-ezuikit-js"><div id="video-container" style="width:100%;height:500px"><div class="mask" @click="togglePlay" :style="{ 'display': play ? 'none' : 'block' }"></div><div class="controll"><div class="left"><el-tooltip effect="dark" :content="play ? '正在播放' : '停止'"><i :class="play ? 'el-icon-video-pause' : 'el-icon-video-play'" @click="togglePlay"></i></el-tooltip><el-tooltip effect="dark" content="视频截图"><i class="el-icon-camera" @click="isCapturePicture"></i></el-tooltip><el-tooltip effect="dark" :content="enableZ ? '电子放大-已开启' : '电子放大-已关闭'"><i :class="enableZ ? 'el-icon-zoom-out' : 'el-icon-zoom-in'" @click="toggleZoom"></i></el-tooltip></div><div class="right"><el-tooltip effect="dark" content="全屏"><i class="el-icon-full-screen" @click="isFullScreen"></i></el-tooltip></div></div></div></div>
</template><script>
import EZUIKit from "ezuikit-js";
export default {name: "EZUIKitJs",data(){return {player: null,enableZ:false, //默认关闭电子放大play: false //默认停止播放}},mounted(){console.group("mounted 组件挂载完毕状态===============》");this.player = new EZUIKit.EZUIKitPlayer({autoplay: false,id: "video-container",accessToken:"xxx",url: "xxx",template: "simple", // simple - 极简版;standard-标准版;security - 安防版(预览回放);voice-语音版;audio: 0, // 是否默认开启声音 0 - 关闭 1 - 开启width: 600,height: 500});},beforeDestroy(){if(this.play)this.player.stop();},methods:{// 开启/关闭 电子放大toggleZoom(){if(!this.player || !this.play) return;switch (this.enableZ) {case true:this.player.closeZoom();this.enableZ = false;break;case false:this.player.enableZoom();this.enableZ = true;break; default:break;}},// 播放/停止 监控togglePlay(){if(!this.player) return;switch (this.play) {case true:this.player.stop();this.play = false;break;case false:this.player.play();this.play = true;break; default:break;}},// 视频截图isCapturePicture(){if(!this.player || !this.play) return;this.player.capturePicture();},// 全屏isFullScreen(){if(!this.player || !this.play) return;this.player.fullScreen();}}
};
</script>
<style lang="scss" scoped>
#video-container{position: relative;
}
::v-deep #video-container iframe{width: 100% !important;
}
.mask{position: absolute;top:0;left:0;width:100%;height:500px;background: rgba(255, 255, 255, .6) url('../../assets/images/play.png') no-repeat center;background-size: 100px;
}
.controll{display: flex;position: absolute;bottom: 0;left: 0;width: 100%;height: 48px;line-height: 48px;background: rgba(0, 0, 0, 0.65);padding: 0 15px;z-index: 2;opacity:0;transition: all 0.3s;.left{width: 50%;i{margin-right: 10px;}}.right{width: 50%;text-align: right;}i{vertical-align: middle;color: #fff;font-size: 30px;}
}#video-container:hover .controll{opacity: 0.65;
}
</style>
效果:
初始化参数
参数名 | 类型 | 描述 | 是否必选 |
---|---|---|---|
id | String | 播放器容器DOM的id | Y |
accessToken | String | 授权过程获取的access_token | Y |
url | String | 视频ezopen协议播放地址 | Y |
audio | int | 是否默认开启声音 1:打开(默认) 0:关闭 | N |
width | int | 视频宽度,默认值为容器容器DOM宽度 | N |
height | int | 视频高度,默认值为容器容器DOM高度 | N |
templete | string | 播放器模板,可以通过选定模板,使用内置的播放器样式,组件 simple:极简版;standard:标准版;security:安防版(预览回放);vioce:语音版 | N |
header | Array | 视频头部可选UI组件,可选值:capturePicture:截图,save:录像保存,zoom:电子放大 | N |
footer | Array | 视频底部部可选UI组件,可选值:talk:对讲,broadcast:语音播报,hd:高清标清切换,fullScreen:全屏 | N |
plugin | Array | 按需加载插件,可选值: talk:对讲 | N |
handleSuccess | function | 播放成功回调 | N |
handleError | function | 播放错误回调 | N |
openSoundCallBack | function | 开启声音回调 | N |
closeSoundCallBack | function | 关闭回调 | N |
startSaveCallBack | function | 开始录像回调 | N |
stopSaveCallBack | function | 结束录像回调 | N |
capturePictureCallBack | function | 截图回调 | N |
fullScreenCallBack | function | 全屏回调 | N |
fullScreenChangeCallBack | function | 全屏变化回调-全局(含ESC退出全屏等) | N |
getOSDTimeCallBack | function | 获取OSD时间回调 |
API方法集合
方法名 | 类型 | 描述 | 使用示例 |
---|---|---|---|
stop | function | 结束播放 | player.stop() |
openSound | String | 开启声音 | player.openSound() |
closeSound | String | 关闭声音 | player.closeSound() |
startSave | int | 开始录像 | player.startSave() |
stopSave | int | 结束录像 | player.stopSave() |
capturePicture | function | 视频截图 | player.capturePicture() |
fullScreen | function | 全屏(自动适配移动端pc端全屏) | player.fullScreen() |
cancelFullScreen | function | 取消全屏 | player.cancelFullScreen() |
getOSDTime | function | 获取播放时间回调 | player.getOSDTime() |
startTalk | function | 开始对讲 | player.startTalk() |
stopTalk | function | 结束对讲 | player.stopTalk() |