前言
目前做的项目,需要Web端显示实时视频数据。本次项目使用的是海康威视的摄像头进行实时监控。
硬件:海康威视的摄像头
软件:video.js、nginx、vlc
参考:https://blog.csdn.net/qq_36720088/article/details/82893924?utm_source=distribute.pc_relevant.none-task
一、实时视频
1、前期工作
海康摄像头支持四种取流协议,其中在web上能利用的为三种协议:rtsp、rtmp、hls。rtsp在web上显示起来比较复杂,这里我们主要介绍rtmp、hls。
RTMP协议是Real Time Message Protocol(实时信息传输协议)的缩写,它是由Adobe公司提出的一种应用层的协议,用来解决多媒体数据传输流的多路复用(Multiplexing)和分包(packetizing)的问题。随着VR技术的发展,视频直播等领域逐渐活跃起来,RTMP作为业内广泛使用的协议也重新被相关开发者重视起来。
HLS:HTTP Live Streaming,是由苹果公司提出的基于HTT的流媒体网络传输协议。他的工作原理是把整个流分成一个个小的基于HTTP的文件来下载,每次只下载一些。当媒体流正在播放时,客户端可以选择从愈多不同的备用源中以不同的速率下载同样的资源,允许流媒体绘画适应不同的数据速率。在开始一个流媒体会话时,客户端会下载一个包含源数据的extended M3U(m3u8)playlist文件,用于寻找可用的媒体流。
rtmp流属于flv格式只能用flash播放,故需要flash插件支持;但现在flash将被废除,在2020年底,chrome、FireFox等主流浏览器都不支持flash,虽然flash在中国有特供版,但终究不是长久之计。所以我们考虑用hls。其实各大视频现在都采用了hls,并且还使用了blob加密。事实证明,hls比flash安全稳定多了,果然抵不过苹果的真香定律。
2、具体实现
第一步:
1、先下载海康威视的设备网络SDK,根据自己的运行环境选择合适版本。
我下载的是CH-HCNetSDKV6.1.4.42_build20200527_win64,所以解压后是这样的。
可以参考demo示例,编写自己的程序。
2、修改HCNetSDK类中的HCNetSDK地址,改为自己项目的HCNetSDK.dll地址。可以用一个方法来获取项目的HCNetSDK.dll。
/*** 获取项目webapp目录* @return*/public static String getWebPath(){String path = (com.haikang.demo.hk.CommonKit.class.getResource("/").getPath()).replaceAll("%20", " ").substring(1).replace("bin", "SDK").replace("/","\\");System.out.println(path);try {String DLL_PATH = java.net.URLDecoder.decode(path, "utf-8");} catch (UnsupportedEncodingException e) {e.printStackTrace();}return DLL_PATH;}
参考了https://blog.csdn.net/qq_36720088/article/details/82893924?utm_source=distribute.pc_relevant.none-task的文章。
3、获取通道:
4、整体调用获取通道号:
int channelNumber = hcTools.getChannelNumber();就是获取到了通道号;
5、拼接rtsp地址
成功的rtsp地址如下:
rtsp://admin:admin123456@10.192.44.101:554/h264/ch1/main/av_stream
解释下
admin:设备登录账号;admin123456:设备登录密码;10.192.44.101:设备的内网IP地址:554:默认端口(注:不要变,这是取rtsp流的默认端口);h264:是视频流编码格式;ch1:通道号(注:下面会详细介绍通道号规则);
第二步:
1、下载vlc,可以去vlc官网(https://www.videolan.org/)去下载。对版本没有要求。
2、安装成功后,打开vlc。依次点击媒体->打开网络串流->网络,将得到的rtsp地址复制进去,点击播放。如果地址没有错误,那么你就可以看到海康威视摄像头的实时画面。
第三步:
下载已经集成nginx-rtmp插件的nginx,https://download.csdn.net/download/woyunhan123/13195494,解压到本地。在nginx安装目录下输入命令nginx -c conf/nginx-win-rtmp.conf 回车,nginx启动时不能关闭命令行窗口。
第四步:
1、选择static版本,下载安装FFmpeg。并配置环境变量。
将properties的FFmpeg地址换成本地的FFmpeg地址。
2、下载window可用的FFmpegCommandHandler,传送门:https://blog.csdn.net/eguid_1/article/details/52968220
这里是已经用java包装好的一个FFempg的工具
3、下载后打开压缩包
选择jar文件夹下有一个jar包:FFmpegCommandHandler.jar
4.将这个jar包安装到本地的maven仓库(maven项目):
将jar包解压之文件夹然后使用 maven 的 install:install-file命令mvn install:install-file -DgroupId=FFmpeg -DartifactId=FFmpeg -Dversion=1.0-Dpackaging=jar -Dfile=D:\XXX\FFmpegCommandHandler.jar;
5.进入自己的本地Maven仓库找ffempg\ffempg\1.0\ffempg-1.0.pom
6.项目中pom.xml引入
7、FFmpeg的使用
推流拉流命令
当然用户也可以用ffmpeg命令手动开启。
ffmpeg -rtsp_transport tcp -i rtsp://wowzaec2demo.streamlock.net/vod/mp4:BigBuckBunny_115k.mov -vcodec libx264 -vprofile baseline -acodec libmp3lame -ar 44100 -ac 1 -f flv -r 25 -s 1920x1080 -an rtmp://localhost:1935/hls/cctv1
效果是这样的:
第四步,将生成的hls地址,放在video.js上。video.js支持mp4,webm,ogg三种格式的文件的播放。
第五步,启动项目,播放。
如果正常,可以看到数据正在切片。
二、实时视频
- 由于HLS协议规定:
视频的封装格式是TS。 - 视频的编码格式为H264,音频编码格式为MP3、AAC或者AC-3。
- 除了TS视频文件本身,还定义了用来控制播放的m3u8文件(文本文件)
HLS协议说明
HLS的m3u8,是一个ts的列表,也就是告诉浏览器可以播放这些ts文件,譬如:
#EXTM3U
#EXT-X-VERSION:3
#EXT-X-MEDIA-SEQUENCE:285
#EXT-X-TARGETDURATION:2
#EXTINF:2.000,
cctv1-285.ts
#EXTINF:2.000,
cctv1-286.ts
#EXTINF:0.848,
cctv1-287.ts
-
EXTM3U
每个M3U文件第一行必须是这个tag,提供标示作用 -
EXT-X-VERSION
用以标示协议版本。这里是3, 那么这里用的就是HLS协议第三个版本,此标签只能有0或1个,不写代表使用版本1 -
EXT-X-TARGETDURATION
所有切片的最大时长,有些Apple设备这个参数不正确会无法播放。 -
EXT-X-MEDIA-SEQUENCE
切片的开始序号。每一个切片都有唯一的序号,相邻之间序号+1。这个编号会继续增长,保证流的连续性。 -
EXTINF
ts 切片的实际时长。duration : 媒体持续时间 -
EXT-X-ENDLIST
文件结束符号。表示不再向播放列表文件添加媒体文件。
所以回放功能的实现就是将指定时间内的切片拼接到m3u8文件,再将m3u8文件传给页面。