国标28181 国标视频平台
写文思路:
实现了视频播放,包括实时播放和视频回放。
首先展示效果图,介绍国标视频平台、国标视频平台的接口文档,介绍后端如何工作,前端如何工作,封装的核心代码以及完整代码。
效果展示:
实现思路:
左侧是树状图,包含摄像头列表,点击某一个摄像头,调取视频播放的接口,根据接口返回的数据,数据包括但不限于直播推流url等。根据这个url前端使用Jessibuca直播流播放器进行视频的播放。
一、国际28181
理论知识:
理论知识:
1.协议类型:GB28181,国标28181规范是什么?
国标28181平台【简写GB28181】的“视频监控设备接入系统”,是一个系统,一个能够
远程、跨区域、跨级别的访问网络中的监控设备(包括IPC、NVR等)。GB28181规定了视频监控系统中各种设备、系统、角色之间的互通互联的关系和连接规范。
2.国标平台的组成部分?
一个完整的GB28181平台,通常由管理平台、信令服务器、流媒体服务器、监控设备(IPC、NVR)、管理终端等几部分组成。
3.三种主流的国标28181平台,如下:
1.NTV GBS
2.华为IVS平台
3.WVP(WEB VIDEO PLATFORM)【开源平台】
NTV官网链接
华为IVS官网链接
开源平台WVP官网链接
参考博客:点击跳转
备注:视频监控工程,会通过标准协议接口纳入各地的监控资源,以实现平安和谐社会的建设。总体上是由各个单位建设平台,通过公网或专网将各地监控资源接入,这种监控设备对接到平台的协议,我们一般指的就是国标GB/T28181。
二、国标视频平台
公司后端可以拉取gitHub上的源码,进行本地部署。
平台信息:
国标视频平台的首页概览:
国标设备:
备注:
这是一个什么平台?用来做什么?
答:这是国标视频平台,通过登录一个可视化界面可以操作或者查看一些设备的状态,通过接口文档,后端写接口。写的接口要符合规范,进而前端调取接口【接口解决跨域】,实现具体的界面上的功能,包括:视频监控【实时监控】、视频回放【历史回放】。
三、国标视频接口文档
前端人员对接国标视频平台上的数据,需要按照此平台的接口文档进行传参、对接数据。
前端怎么使用?
答:如果后端接口写得详细,其实前端不用看。前端调取接口,传参,操作平台,进而控制摄像头的向上、向下、向左、向右、播放、停止、放大、缩小等功能。
三、jessibuca视频插件
目录:
- jessibuca简介
- 下载依赖文档
- 组件封装
(一)、jessibuca简介
官网链接:点击跳转
Jessibuca是一款开源的纯H5直播流播放器,通过Emscripten将音视频解码库编译成Js(ams.js/wasm)运行于浏览器之中。兼容几乎所有浏览器,可以运行在PC、手机、微信中,无需额外安装插件。
(二)、下载依赖:
去jessibuca官网下载,官网下载:点击跳转
从官网下载相关压缩包将文件引入项目中,放入Public文件夹下。
(三)、jessibuca插件使用:
vue2封装:
<template><div class="container" ref="container" style="width:100%;height:200px;"> </div>
</template><script>
export default {data() {return {jessibuca: '',videoUrl:'***********' // 后台推送过来的直播地址};},mounted() {this.play()},methods: {init() {const options = {};this.jessibuca = new window.Jessibuca(Object.assign({container: this.$refs.container, // 播放器容器,若为 string ,则底层调用的是 document.getElementById('id')videoBuffer: 0.2, // 设置最大缓冲时长,单位毫秒,播放器会自动消除延迟。forceNoOffscreen: true, // 是否不使用离屏模式(提升渲染能力)hasAudio: false, // 是否有音频rotate: 0, // 设置旋转角度,只支持,0(默认) ,180,270 三个值isResize: false, // 1.当为true的时候:视频画面做等比缩放后,高或宽对齐canvas区域,画面不被拉伸,但有黑边;2.当为false的时候:视频画面完全填充canvas区域,画面会被拉伸isFullSize: true, // 当为true的时候:视频画面做等比缩放后,完全填充canvas区域,画面不被拉伸,没有黑边,但画面显示不全debug: false, // 是否开启控制台调试打印timeout: 30, // 设置超时时长, 单位秒,在连接成功之前和播放中途,如果超过设定时长无数据返回,则回调timeout事件supportDblclickFullscreen: true, // 是否支持屏幕的双击事件,触发全屏,取消全屏事件。showBandwidth: false, // 是否显示网速operateBtns: {fullscreen: true,// 是否显示全屏按钮screenshot: true,// 是否显示截图按钮play: true,// 是否显示播放暂停按钮audio: true,// 是否显示声音按钮recorder: false},keepScreenOn: false, // 开启屏幕常亮,在手机浏览器上, canvas标签渲染视频并不会像video标签那样保持屏幕常亮。isNotMute: false, // 是否开启声音,默认是关闭声音播放的。loadingText: "加载中...", // 加载过程中文案。background: "", // 背景图片。decoder: '/public/jessibuca/decoder.js',// useMSE: false,isFlv: true,},options));},play() {const url = this.videoUrl;this.init();this.jessibuca.play(url);},destroy() {if (this.jessibuca) {this.jessibuca.destroy();}}}
};
</script><style scoped lang="scss"></style>
vue3封装:
<template><div ref="playerRef" class="player"></div>
</template><script setup lang="ts">
import { computed, nextTick, onBeforeUnmount, onMounted, ref, watch } from "vue";const playerRef = ref();
const jessibucaPlayer = ref(null);const props = defineProps({wsFlv: String,config: {type: Object,default: {isFlv: true, // 是否使用flv格式showBandwidth: true, // 是否显示带宽使用情况operateBtns: {// 配置按钮对象screenshot: true, // 是否启用截图功能fullscreen: true, // 是否启用全屏功能play: true, // 是否启用播放功能audio: true, // 是否启用音频功能record: true, // 是否启用录制功能},loadingText: "加载中...", // 设置播放器加载时显示的文本isResize: false,controlAutoHide: true, //底部控制台是否自动隐藏decoder: "decoder.js",hotKey: true, //是否开启键盘快捷键,目前支持的键盘快捷键有:esc -> 退出全屏;arrowUp -> 声音增加;arrowDown -> 声音减少;keepScreenOn: true, //开启屏幕常亮,在手机浏览器上, canvas标签渲染视频并不会像video标签那样保持屏幕常亮。videoBuffer: 0,},},
});
const url = computed(() => {return props.wsFlv
})watch(url, (newVal, oldVal) => {nextTick(() => {createJessibucaPlayer()})
}, { immediate: true })
// 创建播放器
const createJessibucaPlayer = () => {if (jessibucaPlayer.value) jessibucaPlayer.value.destroy();jessibucaPlayer.value = new Jessibuca({container: playerRef.value,...props.config,});jessibucaPlayer.value.on('load', () => {jessibucaPlayer.value.play(props.wsFlv);})
};
// 组件销毁前销毁播放器并停止视频流
onBeforeUnmount(() => {if (jessibucaPlayer.value) {jessibucaPlayer.value.destroy();jessibucaPlayer.value = null;}
});const updatePlayerDomSize = () => {const dom = playerRef.value;let width = dom.parentNode.clientWidth;let height = (9 / 16) * width;if (height > dom.clientHeight) {height = dom.clientHeight;width = (16 / 9) * height;}if (width > 0 && height > 0) {dom.style.width = width + "px";dom.style.height = height + "px";}
};
defineExpose({updatePlayerDomSize,
});
</script><style lang="scss" scoped></style>
调用封装的组件,组件使用传参:
//html部分
<JessibucaPlayer :config="stateVideo.jessibucaPlayerConfig" :wsFlv="stateVideo.flvUrl" style="width: 100%; height: 100%" />
//js部分
const stateVideo = reactive({
flvUrl: "",
jessibucaPlayerConfig: {
autoWasm: true, // 在使用MSE或者Webcodecs 播放H265的时候,是否自动降级到wasm模式。
background: "", //背景图片
controlAutoHide: false, //底部控制台是否自动隐藏
debug: false, //是否开启控制台调试打印
decoder: "/jessibuca/decoder.js",
hasAudio: false, // 是否有音频,如果设置false,则不对音频数据解码,提升性能。
hasVideo: true, // 是否开启控制台调试打印
heartTimeout: 5, //设置超时时长, 单位秒播放中途,如果超过设定时长无数据返回,则回调 timeout事件
heartTimeoutReplay: true, //是否开启心跳超时之后自动再播放
heartTimeoutReplayTimes: 3, //重试次数 heartTimeoutReplay 重试失败之后,不再重新播放视频地址。如果想无限次重试,可以设置为-1
hiddenAutoPause: false, //是否开启当页面的'visibilityState'变为'hidden'的时候,自动暂停播放。
hotKey: false, //是否开启键盘快捷键 esc -> 退出全屏;arrowUp -> 声音增加;arrowDown -> 声音减少;
isFlv: false, //当为true的时候:ws协议不检验是否以.flv为依据,进行协议解析。
isFullResize: false, //当为true的时候:视频画面做等比缩放后,完全填充canvas区域,画面不被拉伸,没有黑边,但画面显示不全
isNotMute: false, // 是否开启声音,默认是false关闭声音播放的。
isResize: false, //当为true的时候:视频画面做等比缩放后,高或宽对齐canvas区域,画面不被拉伸,但有黑边。 当为false的时候:视频画面完全填充canvas区域,画面会被拉伸。
keepScreenOn: false, //开启屏幕常亮,在手机浏览器上, canvas标签渲染视频并不会像video标签那样保持屏幕常亮。PC端不会生效,仅手机端生效
loadingText: "请稍等, 视频加载中......", // 视频加载转圈时的提示文字
loadingTimeout: 10, //当play()的时候,如果没有数据返回,则回调
loadingTimeoutReplay: true, ///是否开启loading超时之后自动再播放
loadingTimeoutReplayTimes: 3, //loadingTimeoutReplay 重试失败之后,不再重新播放视频地址。
operateBtns: {
// 配置操作按钮 其中
fullscreen: false, //全屏按钮
screenshot: false, //截图按钮
play: false, //播放暂停按钮
audio: false, //声音按钮
record: false, //录制按钮
},
recordType: "webm", //默认录制的视频格式
rotate: 0, //设置旋转角度
showBandwidth: false, // 显示网速
supportDblclickFullscreen: false, // 是否支持屏幕的双击事件,触发全屏,取消全屏事件。
timeout: 10, //设置超时时长, 单位秒在连接成功之前(loading)和播放中途(heart),如果超过设定时长无数据返回,则回调timeout事件
useMSE: location.hostname !== "localhost" && location.protocol !== "https:", //是否开启MediaSource硬解码
useWCS: location.hostname === "localhost" || location.protocol === "https", //是否开启Webcodecs硬解码
useWebFullScreen: false, //是否使用web全屏(旋转90度)(只会在移动端生效)。
videoBuffer: 0, // 设置最大缓冲时长,单位秒,播放器会自动消除延迟。
wasmDecodeErrorReplay: true, // 是否开启解码失败重新播放
wcsUseVideoRender: true, //webcodecs硬解码是否通过video标签渲染
},
});