信息时代万物互联、数据共享的发展趋势犹如冬春交替、万象更新一般不可阻挡,与此同时带来的网络及数据安全问题也油然而生,当前视频在线直播、实时安全监控、物联智慧感知在人们的生产和生活中随处可见,极大地体现了计算机硬件、软件和网络
等技术的飞速发展。
不得不承认的是,海康威视在国内视频监控领域无疑是行业翘楚,无论是走在大街上、马路边,还是在大型商超、学校、公园、文娱场所、小区、企业、交通路口,我们都可以看到无处不在的监控设备,如摄像头,那么问题来了,现在需要接入远端视频流,该如何去实现呢?
除了常见的文本、图片、音频之外,视频作为一种喜闻乐见的数据类型,深受广大用户的喜爱和好评,不但包含画面和声音,还支持同步进行播放或者循环回放,甚至可以远程呼叫和操控角度。视频文件格式多种多样(如avi、wmv、mpeg、mp4、m4v、mov、asf、flv、f4v、rmvb、rm、3gp、vob等),每类格式的诞生和发展都体现了时代和技术的进步,为了在Windows、Linux、Unix、macOS
等多种平台下将视频进行高效集成,需要设计和约定多种视频协议以提高兼容性和可用性,其中常见的视频协议包含rtsp、rtmp和hls
等。
实时流协议(RTSP
)是一种应用级网络协议,设计用于通过合适的传输协议复用和打包多媒体传输流(例如交互式媒体、视频和音频)。RTSP
在娱乐和通信系统中用于控制流媒体服务器。该协议用于建立和控制端点之间的媒体会话。媒体服务器的客户端发出诸如播放、录制和暂停之类的命令,以便于实时控制从服务器到客户端(视频点播)或从客户端到服务器(语音录制)的媒体流。此外,关于rtsp视频协议的内容,大家可以参考文章[MS-RTSP]: Real-Time Streaming Protocol (RTSP) Windows Media Extensions
实时消息传递协议(RTMP
)是一种通信技术,它支持通过互联网进行实时视频流传输。它基于传输控制协议(TCP
)技术,最初由Macromedia
为其Flash Player
开发,后来被Adobe
收购后成为Adobe Flash Player
。
最初,RTMP
主要用于在托管服务器和视频播放器之间传输内容。就最现代的直播设置而言,RTMP的主要作用是将内容从编码器传送到在线视频主机。这是一个被称为“摄取”的过程。在直播流媒体的新角色背景下,RTMP
能够进行低延迟流媒体,这对于实时直播重大事件的广播公司来说是一个重要的优势。它还以最小的缓冲而闻名,这确实增强了用户体验。RTMP
流媒体是传递低缓冲区流媒体内容的最佳方式之一,同时也在自适应比特率流和一些网络会议工具中发挥作用。此外,关于rtmp
视频协议的内容,大家可以参考文章What is RTMP? The Real-Time Messaging Protocol: What you Need to Know in 2022
HTTP Live Streaming
(简称HLS
) 是 Apple
实现的基于 HTTP 的自适应比特率流通信协议, 由于采用HTTP
协议和跨平台性而被广泛应用,需要根据网络状况播放当前可播放的具有最佳质量的音视频。关于hls
视频协议的内容,大家可以参考文章What is HLS (HTTP Live Streaming) and How Does It Work?和Apple
官网发布的文章Understanding the HTTP Live Streaming Architecture,个人觉得讲解得非常详细,有时间的小伙伴可以耐心品读和研究一下。
假设前提工作已经做好,采用海康威视
的智能监控设备,而且设备已经安装调试、部署成功,为了成功接入在线视频,需要进行以下三个步骤:(1)官网API查看;(2)监控视频取流接口调用;(3)页面展示实时视频。
首先打开海康开放平台,点击上方菜单栏中资源中心->智能应用平台(Infovision IoT
)->海康开放平台智能应用平台对接指南。
|
|
之后需要认真阅读指南中的一些术语,其中AppKey/AppSecret(简称ak/sk
)较为关键,一对AppKey/AppSecret用于标识一个调用方来进行安全认证,接口调用时需要用到这两个参数加以验证进而跳过casLogin
登录;可以看到,监控设备目前仅支持RTSP、RTMP和HLS三种视频协议;当前的接口只支持Java、C++、C#、C
这四种语言进行调用。
打开API列表下的监控资源信息页面,找到分页获取监控点资源接口,可以了解到该接口为POST
请求,需要传入页面编号
和每页条数
,返回结果中包含多个监控点组成的列表,每个监控点包含经度、纬度、高度和相机索引码
等属性,利用这些信息可以在地图中添加监控点位用以展示相机地址,同时利用相机索引码还可获取到相对应的视频流地址,进而弹出实时监控窗口。
打开API列表下的视频应用服务->视频能力,找到获取监控点预览取流URL接口,可以了解到该接口为POST
请求,需要传入相机索引码
,对于protocol参数,可以传入rtsp、rtmp和hls
三种协议字符串,然后返回结果中包含对应相机的取流地址。
在海康官方SDK下载地址页面可根据需要下载相关的插件为自己所用,点击开发指南可查看具体的API调用方法和操作步骤。
这里采用Java
代码调用需要依赖artemis-http-client.jar
包,由于安全认证库已上传公网仓库,所以可以直接新建Maven工程,在.pom文件中引入依赖;也可以在Maven库网站下载该jar包后,放至Java工程的依赖库中即可;当然更可以利用官网下载的插件OpenAPI安全认证库(Java)
。
调用示例代码如下:
import com.hikvision.artemis.sdk.ArtemisHttpUtil;
import com.hikvision.artemis.sdk.config.ArtemisConfig;
import java.util.HashMap;
import java.util.Map;
public class GetCameraPreviewURL {
public static String GetCameraPreviewURL() {
/**
* STEP1:设置平台参数,根据实际情况,设置host appkey appsecret 三个参数.
*/
ArtemisConfig.host = "127.0.0.1:443"; // 平台的ip端口
ArtemisConfig.appKey = "29180881"; // 密钥appkey
ArtemisConfig.appSecret = "XO0wCAYGi4KV70ybjznx";// 密钥appSecret
/**
* STEP2:设置OpenAPI接口的上下文
*/
final String ARTEMIS_PATH = "/artemis";
/**
* STEP3:设置接口的URI地址
*/
final String previewURLsApi = ARTEMIS_PATH + "/api/video/v1/cameras/previewURLs";
Map<String, String> path = new HashMap<String, String>(2) {
{
put("https://", previewURLsApi);//根据现场环境部署确认是http还是https
}
};
/**
* STEP4:设置参数提交方式
*/
String contentType = "application/json";
/**
* STEP5:组装请求参数
*/
JSONObject jsonBody = new JSONObject();
jsonBody.put("cameraIndexCode", "748d84750e3a4a5bbad3cd4af9ed5101");
jsonBody.put("streamType", 0);
jsonBody.put("protocol", "rtsp");
jsonBody.put("transmode", 1);
jsonBody.put("expand", "streamform=ps");
String body = jsonBody.toJSONString();
/**
* STEP6:调用接口
*/
String result = ArtemisHttpUtil.doPostStringArtemis(path, body, null, null, contentType , null);// post请求application/json类型参数
return result;
}
public static void main(String[] args) {
String result = GetCameraPreviewURL();
System.out.println("result结果示例: " + result);
}
}
#include "iostream"
#include "sstream"
#include "HttpUtillib.h"
#include "HttpHeader.h"
typedef struct Unit_query_s
{
string artemisIp; // 平台的ip地址(必填)
int artemisPort; // 平台的Port(必填)
string appKey; // 密钥的appKey(必填)
string appSecret; // 密钥的appSecret(必填)
}Unit_query_t;
/*示例1:(Post)获取当前AppKey的合作方对应监控点列表*/
string FindIndexCodesOfAppKey(Unit_query_t query)
{
std::stringstream ss;
ss << "http://" << query.artemisIp << ":" << query.artemisPort
<< "/artemis/api/resource/v1/camera/advance/cameraList";
map<string, string> headers;
//(必填的Http头)根据期望的Response内容类型设置
headers.insert(std::make_pair(HttpHeader::HTTP_HEADER_ACCEPT, "application/json"));
headers.insert(std::make_pair(HttpHeader::HTTP_HEADER_CONTENT_TYPE, "application/json;charset=UTF-8"));
list<string> signHeaderPrefixList;
char strBody[1024] = { 0 };
sprintf_s(strBody, 1024, "{\"pageNo\":%d,\"pageSize\":%d}", 1, 100);
return HttpPost(ss.str(), headers, strBody, query.appKey, query.appSecret, 30, signHeaderPrefixList);
}
int main()
{
Unit_query_t myQuery;
myQuery.appKey = "26018161";
myQuery.appSecret = "tdxjiS8bNXZTOf80ymWw";
myQuery.artemisIp = "x.x.x.x";
myQuery.artemisPort = 80;
//1 Post
std::string str1 = FindIndexCodesOfAppKey(myQuery);
std::cout << str1 << std::endl << std::endl;
system("pause");
return 0;
}
在Github搜索artemis-http-client
会出现一个nodejs
封装的HIKVISION artemis-http-client nodejs SDK,不过这个代码的时效性不够,可能不会随官网更新而改变,因此其中的功能有待验证,由于时间较紧,还是未能加以测试,有时间的小伙伴可以尝试着学习研究。
const co = require('co');
const {Client} = require('artemis-http-client');
//new Client(appKey, appSecret)
const client = new Client('23967750', 'BZcz3VlqL1DVhWeF1boE');
//GET
co(function* () {
var url = 'https://open8200.hikvision.com/artemis/api/artemis/v1/minus';
var result = yield client.get(url, {
query: {
'a': 1,
'b': 1
},
headers: {
accept: 'application/json',
'content-type':'text/plain;charset=UTF-8'
}
});
console.log(JSON.stringify(result));
}).catch((error)=>{
//请求错误信息
console.log(JSON.stringify(error.message));
});
//POST
co(function* () {
var url = 'https://open8200.hikvision.com/artemis/api/artemis/v1/plus';
var result = yield client.post(url, {
headers: {
'content-type': "application/x-www-form-urlencoded;charset=UTF-8"
},
data: {
'a': 1,
'b': 1
}
});
console.log(JSON.stringify(result));
}).catch((error)=>{
//请求错误信息
console.log(JSON.stringify(error.message));
});
对于rtsp
协议的视频流地址,建议采用官方插件,在客户端安装完成后使用。
对于rtmp
协议的视频流地址,可以参考vue-rtmp-cli3.0,但需要客户端的浏览器支持Flash
,依赖于Flash插件,有兴趣的小伙伴可以研究一下。
对于hls
协议的视频流地址,可以采用video.js
库进行实时播放。
video.js库是一个为HTML5
世界从头开始构建的网络视频播放器。它支持HTML5
视频和媒体源扩展,以及其他播放技术,如YouTube和Vimeo(通过插件)。它支持桌面和移动设备上的视频播放。该项目于2010年中期开始,目前该播放器在超过700000个网站上使用。具体使用教程可参考videojs快速开始。
利用video.js
库可在html静态网页中直接接入hls在线视频,这里分别以m3u8在线url1和m3u8在线url2两个在线实例来进行测试。
video.js
调用hls视频实例html
代码:
DOCTYPE html>
<html>
<head>
<meta charset=utf-8 />
<title>videojs-jjg-onlinetitle>
<link href="https://vjs.zencdn.net/8.0.4/video-js.css" rel="stylesheet">
<script src="https://vjs.zencdn.net/8.0.4/video.min.js">script>
head>
<body>
<h1 style="margin-left:25%;">在线视频(hls-m3ub格式)------<strong style="color:blue;">By jing_zhong 2023.2.16strong>h1>
<div style="width:100%;height:90%">
<video id="myVideo" class="video-js vjs-default-skin" controls preload="auto" height="770px" width="1720px" height="auto" data-setup='{}'>
<source src="https://v7.dious.cc/20220802/qyRQEXdQ/index.m3u8" type="application/x-mpegURL">
video>
div>
<script>
var myVideo = videojs('myVideo',{
autoplay: true, // 设置自动播放
controls: true, // 显示播放的控件
preload: "auto", // 预加载
muted: true, // 设置了它为true,才可实现自动播放,同时视频也被静音 (Chrome66及以上版本,禁止音视频的自动播放)
bigPlayButton : true,
textTrackDisplay : false,
posterImage: false,
errorDisplay : true,
controlBar: {
volumePanel:{
inline:false}},
// playbackRates: [0.5,1,1.25,1.5,2],
},function(){
this.on('error',function(){
myVideo.errorDisplay.close()
alert('抱歉,视频地址解析错误≥﹏≤ \n 请检查视频链接地址是否正确')
})
}
)
script>
body>
html>
交通、安防、视频直播、在线会议、网络带货
等领域都需要将视频流快速转发以便客户端接入,希望给用户带来极致的服务体验。当然,如果有条件的话,还是建议到海康官网下载视频插件,然后利用官方SDK解析RTSP和RTMP等协议的视频流,在客户端或浏览器安装好视频插件
,这样会比HLS
协议的视频流传输效果更加快速、响应时间更短。
注:本文旨在学习视频实时接入方法,分享个人学习心得,希望与广大开发者共同交流思想,切勿用于非法商业用途!!!