海康、大华等监控摄像头通过H5方式无插件低延时播放方案

前言

当前,视频监控应用在各种应用场景下已经大面积应用,并且经过多年日积月累的建设,所采用的厂商设备也是五花八门,比如有海康、大华、宇视、天地伟业等各种品牌的摄像头。
同时,随着各种数字化应用系统的建设,很多单位都需要开发自己的移动智能化应用,安防视频作为一项重要的数据元素需要在移动APP端、可视化远程指挥平台、GIS地理信息系统、领导驾驶舱等系统中调用。这些应用当前主要以H5方式通过浏览器进行业务呈现,因此需要一套无插件的低延时接入解决方案。

技术路线分析

为了实现监控视频的浏览器端无插件播放,并且适配多种播放终端,当前行业内普遍采用HLS协议这种技术路线。
通过将安防摄像头信号转换成HLS协议进行视频流发布的业务流程。
**加粗样式
**在这里插入图片描述
这是当前应用最为普遍的一种技术实现方式,它的优缺点如下:
优点:
1) 该方案具有通用性,因为经过流媒体服务器转换后输出的HLS协议视频流可以兼容Android和iOS两大移动端平台;
2) 可以兼容各个厂商的安防摄像头和NVR设备;
3) 移动端对接完全兼容HTML5技术标准,实现起来简单方便;
缺点:
转换后的直播流延时增大,画面的实时性差。端到端延时通常都在3秒以上;
这是由于Apple公司开发的HLS协议本身的缺陷导致的,并且无法优化。

技术优化方案
为了进一步降低播放延时,提高用户体验,我们研发了另外一项低延时通信技术对该方案进行的深度设计和改进。
系统架构图如下:
在这里插入图片描述
这套系统的主要构成如下:

  1. 低延时视频转码工作站
    用来实现前端各个厂商安防摄像头的统一接入,并实现统一的协议与编码格式转换,并以低延时模式推送给低延时直播发布服务器。
  2. 低延时直播发布服务器
    用来实现各种网络流的低延时转发,面向各种终端设备(PC、iOS设备、Android设备)以HTML5方式进行发布,支持一对多高并发应用。

该方案可以支持以下设备终端:
在这里插入图片描述
低延时技术指标:
该系统的端到端延时主要出现在以下几个环节:

  1. 视频采集和编码延时;
    这部分延时出现在摄像头端,延时在20~50ms范围;
  2. 视频接入和转码延时;
    这部分延时出现在低延时视频转码工作站端,在进行协议转换和视频编码格式转换时产品,延时在10~30ms范围;
  3. 直播发布服务延时;
    这部分延时出现在低延时直播发布服务器端,该服务器在接收低延时视频转码工作站推送过来的网络流时,需要在本地缓存2~3帧的数据,用于抵抗网络带宽抖动带来的影响,避免画面卡顿。
    根据不同的网络流格式,这部分延时在40~100ms范围;
  4. 客户端解码播放延时:
    客户端HTML5播放器在进行网络流播放时,需要等待把一帧完整的数据接收完成后才能解码输出,而且同样基于抗击网络抖动的影响需要缓存12帧的数据,因此这部分延时在2080ms范围;
    端到端整体延时指标:
    以下是实际测试结果:
    局域网/专网:端到端延时<300ms;
    公共互联网: 端到端延时<500ms;
    这个延时指标,与监控厂商的浏览器插件模式基本一致。
    该方案的优缺点:
    优点:
    1) 该方案支持多终端H5方式集成;
    2) 支持各种品牌的监控摄像头接入;
    3) 端到端延时极低,专网环境下端到端延时不超过300ms;
    4) 能够适配各种播放终端,包含Windows系统PC终端、Linux系统PC终端、国产化系统PC终端、Android系统终端、iOS系统终端、微信小程序;
    5) 多终端播放时,信号完全同步。
    缺点:
    建设成本相对较高。

该方案的实际效果测试

可以访问公网的在线测试系统直观地看到实际效果。
移动端访问地址:
http://www.shunjingtech.com/xmms/mobile.html
(可以在微信或者Chromium内核的移动端浏览器中直接访问)
PC端访问地址:
http://www.shunjingtech.com/xmms/base.html
(可以在Chrome、Firefox、Edge等chromium内核浏览器中直接访问)
自行测试体验:
如果需要自行测试,请打开上述两个播放测试页面,然后下拉窗口,按照页面中的方式和我们联络,可以提供全免费技术支持。

==========================================================

H5低延时播放器集成示例

<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta name="renderer" content="webkit">
<meta name="viewport" content="width=device-width,initial-scale=1, minimum-scale=1.0, maximum-scale=1.0, user-scalable=no">
<meta name="x5-fullscreen" content="true">
<meta name="full-screen" content="yes">
<meta name="apple-mobile-web-app-capable" content="yes" />
<meta name="apple-mobile-web-app-status-bar-style" content="black" />
<meta name="format-detection" content="telephone=no">
<title>播放器接口</title>
<link type='text/css' rel='stylesheet' href='css/xmplayer.css?v=2.91'>
<script type="text/javascript" src="js/xmplayer.js?v=2.94"></script>
<style>
html,body{
      
      width:100%; height:100%;margin:0;padding:0;}

.player-wrap {
      
      
	position:relative;
	padding:40px;
}

.vxplayer {
      
      
	width:1024px;
	height:576px;
	margin: 0 auto;
	background-color: #222;
}

.vxplayer-toolbar {
      
      
	height: 40px;
	border: 1px solid #c0c0c0;
    margin-top: 20px;
    width: 1024px;
    margin-left: auto;
    margin-right: auto;
    padding: 6px 20px;
    box-sizing: border-box;
}

.vxplayer-toolbar .btn{
      
      
	border: 1px solid #a0a0a0;
	border-radius: 5px;
	min-width: 60px;
	height: 26px;
	box-sizing: border-box;
	margin: 0 5px;
	float: left;
}

.vxplayer-toolbar .btn:hover {
      
      
	background: #b8e1ee;
	border-color: #89baf2;
	color: #003566;
}

.vxplayer-toolbar .btn:hover {
      
      
	background: #83aab7;
	color: #016789;
	border-color: #2c5c81;
}

.url-inputbox {
      
      
	height: 26px;
    display: inline-block;
    padding: 0px 10px;
    float: left;
    font-size: 14px;
}

.url-inputbox .label {
      
      
	display: inline-block;
    width: 60px;
    height: 26px;
    line-height: 26px;
    padding-right: 6px;
    text-align: right;
}

.url-inputbox input[type="text"] {
      
      
	height: 26px;
    width: 600px;
    border: 1px solid #ccc;
    border-radius: 3px;
    line-height: 22px;
    box-sizing: border-box;
    padding-left: 6px;
    padding-right: 6px;
}




</style>

<script language="javascript">

function onOpenUrl() {
      
      
	var urlbox = document.getElementById('url-box');
	
	var url = urlbox.value;
	
	if (!url) {
      
      
		alert('Please enter url.');
		urlbox.focus();
		return;
	}
	
	if (!window.xmplayer) {
      
      
		//var playerDom = document.querySelector('#player-holder');
		window.xmplayer = new XMPlayer({
      
      
		  url:url,
          playerElm:'#player-holder', //player 元素ID ,也可以直接的DOM对象 playerDom
		  videoElm:'#videoview',   //videoElm 元素
		  videostyle:"width:100%;height:100%;",
		  reconnect:true,
		  autoplay: true,
		  nativecontrols: false,
		  //logframe:true,
		  controlbar: true,
		  muted: true,
		  onready:function() {
      
      
			console.log("Player onready");
		  },
		  onfirstframe:function() {
      
      
			console.log("Player onfirstframe");
		  },
		  onnetclose:function() {
      
      
			console.log("Player onnetclose");
		  },
		  onneterror:function() {
      
      
			console.log("Player onneterror");
		  }
	  });
	}
	else {
      
      
		window.xmplayer.play(url);
	}
}

function onClose() {
      
      
	if (window.xmplayer) {
      
      
		window.xmplayer.stop();
	}
}

function ondestroy() {
      
      
	if (window.xmplayer) {
      
      
		window.xmplayer.destroy();
		delete window.xmplayer;
	}
}

</script>
</head>

<body>
	<div class="player-wrap">
		<div class="vxplayer" id="player-holder">
			<!-- video id="videoview"> </video //-->
		</div>
		<div class="vxplayer-toolbar" id="player-toolbar">
			<button class="btn" onclick="onOpenUrl();">Open</button>
			<button class="btn" onclick="onClose();">Close</button>
			<button class="btn" onclick="ondestroy();">Destroy</button>
			
			<div class="url-inputbox">
			<span class="label">URL:</span>
			<input type="text" id="url-box" value="http://192.168.1.138:1966/live/stream001.rtc">
			</div>
		</div>
	</div>
</body>

</html>

猜你喜欢

转载自blog.csdn.net/zhiboshequ/article/details/125214433