ZLMediaKit实现海康监控摄像头实时播放+RTSP流浏览器可播放转码方案调研+获取视频截图

您所在的位置:网站首页 海康视频流媒体服务器设置 ZLMediaKit实现海康监控摄像头实时播放+RTSP流浏览器可播放转码方案调研+获取视频截图

ZLMediaKit实现海康监控摄像头实时播放+RTSP流浏览器可播放转码方案调研+获取视频截图

2024-02-28 04:18| 来源: 网络整理| 查看: 265

这篇文章适合想要把海康的rtsp转码成浏览器可播放的格式,要求只是播放出来,有视频截图(可选),又不太了解音视频大坑的前端同学(服务自己部署就好了,不需要后端介入)。

支持通过接口访问,非常友好,也不需要在前端项目里写多余的东西,只需要有个rtsp原始流,接口推流->获取拉流参数->flv播放,结束。

需求背景

我司的合作公司采购了海康的摄像头做室内外监控,需要实现在内网大屏上播放海康视频流,因为不是直接采买,没有直接对接海康的技术人员,自己摸索了大半个月方案。

我的系统:MAC

播放端:Windows电视

服务器:Ubuntu

难点:

内网不方便调试 没有海康的技术对接,官方文档不清晰 音视频技术栈过多过杂,坑点巨多 内网因为种种原因不支持https(后来通过询问知道的) 需求不清晰明确 最终解决方案 ZLMediaKit

ZLMediaKit-gitHub

快速开始

安装启动过程

参考这一篇文章: blog.csdn.net/qq_53200007…

相关命令

以守护进程启动: ./MediaServer -d &

// 如果554端口被占用

查找554端口的使用进程 sudo lsof -i :554

// 杀死554端口的进程

sudo kill -9

配置文件

参见: 配置文件详解

要修改的项稍微有点多。

如果是通过docker安装的,配置文件在conf里,如果非docker,配置文件的路径在release/你的系统/Debug下。

RTSP转其他流需要修改的配置项

[rtc] externIP=改成你自己的服务器ip [rtsp] directProxy=0 跑通DEMO

重要: 按照API说明文档,先在ApiFox或者ApiPost等调试工具中访问通了,确保服务可用.

ZLM全面支持H265/H264/AAC/G711/OPUS,检查一下视频编码是否在其中。 确定流可用,可通过VLC播放器进行播放。(VLC->添加流->来自网络->rtsp流直接播放不需要改配置) 拿到秘钥secret,在配置文件前几行。 确保服务在运行中,随时监控日志。 stream需要是唯一的值,推荐时间戳。

主要的接口就是通过/index/api/addStreamProxy推流,成功之后可以通过webRTC拉取,也可以flv拉取。我们的服务器不支持https,所以使用flv拉取。

出现如下响应就是推流成功了,如果没成功,检查一下配置文件,看一下错误日志,多搜搜gitHub的issue,也可以评论区提问。

image.png

把下面的代码复制到HTML文件中就可以看到画面啦~

播放 if (flvjs.isSupported()) { var videoElement = document.getElementById('videoElement'); var flvPlayer = flvjs.createPlayer({ type: 'flv', url: 'http://这是服务的主机地址/这里写app的值/这里写stream的值.live.flv' }); flvPlayer.attachMediaElement(videoElement); flvPlayer.load(); document.querySelector('.btn').addEventListener('click', () => { flvPlayer.play(); }) } 可通用Hook(拿去就能用) 这里的stream是流的唯一标识,我选择了用dayJS产生的时间戳,也可以用其他标识。 这里的容器我写死了document.getElementById('videoElement'),也可以改成通过ref传进来的方式。 rtsp地址可能有特殊字符,所以我进行了编码。 import axios from 'axios'; import dayjs from 'dayjs'; const useFlvVideo = ( rtspUrl, serverConfig = { serverSecret: '', serverUrl: '', app: 'live' } ) => { const { serverSecret, serverUrl, app } = serverConfig; let flvPlayer = null; let stream = null; const checkParams = () => { if (!serverSecret) { throw new Error('serverSecret is required'); } if (!serverUrl) { throw new Error('serverUrl is required'); } if (!app) { throw new Error('app is required'); } if (!rtspUrl) { throw new Error('rtspUrl is required'); } }; checkParams(); const checkFlvIsSupported = () => { return window?.flvjs.isSupported(); }; const startPlay = async () => { stream = dayjs().valueOf(); await addStreamProxy(); await startVideoPlay(); return stream; }; const addStreamProxy = async () => { const url = `http://${serverUrl}/index/api/addStreamProxy`; const result = await axios.get(url, { params: { secret: serverSecret, vhost: serverUrl, app, url: encodeURI(rtspUrl?.value), stream: stream } }); console.log(result, 'result'); }; const startVideoPlay = () => { var videoElement = document.getElementById('videoElement'); flvPlayer = window?.flvjs.createPlayer({ type: 'flv', url: `http://${serverUrl}/${app}/${stream}.live.flv` }); console.log('videoElement', videoElement, flvPlayer, `http://${serverUrl}/${app}/${stream}.live.flv`); flvPlayer.attachMediaElement(videoElement); flvPlayer.load(); flvPlayer.play(); }; const stopPlay = async () => { const url = `http://${serverUrl}/index/api/close_streams`; const result = await axios.get(url, { params: { secret: serverSecret, vhost: serverUrl, app, stream, force: true } }); flvPlayer.stop(); console.log(result, 'result'); }; return { startPlay, stopPlay, flvIsSupported: checkFlvIsSupported() }; }; export default useFlvVideo; 坑n+1: 接口报错500问题

github.com/ZLMediaKit/…

发现偶现推流接口500问题,经过测试发现超过3个流就不行了,看到这个issue, 结!论!是!这个服务器只支持3路。

访问/index/api/getMediaList接口查看流列表。

那么

可以关闭不需要转码的协议避免浪费资源 因为每次打开都是新的推流,所以可以在不看的时候调用 /index/api/close_streams关闭流。 开启无人观看自动关闭配置。酌情修改配置时间(可以根据播放器超时时间)。 还可以不用时间戳去开启流,用视频的唯一标识,这样多个客户端可以拉同一个流。(不过这不解决根本问题)

image.png

坑n+2: ZLM视频实时截图

截图的API是这一个:视频截图

如果出现了截图返回默认图片的问题,解法如下

修改配置文件截图FFmpeg模板 加上-rtsp_transport tcp 核对配置文件里的FFmpeg 路径 MAC可以用命令 where FFmpeg来查找位置 只能使用已经被推送的流 我使用addStreamProxy返回结果的路径就可以,其他的没经过推送的流就不行(比如我的服务器只支持3路,那就只能截这3路。。) 外网调试解决方案 花生壳内网穿透

内网不方便调试,每次都需要把包丢上去看效果,这里用了花生壳,有1G试用流量限制,穿透设置TCP协议,554端口,穿透出来的流能通过VLC播放器播放就行。

和向日葵同一家厂商,远程调试必备。

我的思路

一开始,我接到的需求是,摄像头采集视频后会经过一台外网算法服务器计算之后再推出来,但是在VLC播放器太卡了,需要看看为什么卡顿。于是我去简单了解了音视频播放原理:

前端处理实时监控直播协议和流媒体服务器的调研记录

猜测可能是 1.带宽不够 2.传输过程损耗太大 3.经过算法服务器处理之后有损耗, 需求就变成了“春花同学,你开发一个流媒体服务器!我要一个流媒体服务器!”,尝试进一步沟通失败后,我的目标变成了流媒体服务器。

发现前端可用的流媒体服务器真的不多,基本只有media-soup和node-media-server,前任前段用node-media-serve写了一个简单的DEMO,就是把mp4推成rtsp(推流),再转成flv(拉流),面对摄像头的复杂场景真的没法用。但是我知道了ffmpeg是可以实现推流和转码的。我用media-soup也实现了一遍这个DEMO,资料非常少,跑是跑通了,还是一头雾水。

node-media-soup跑通过程记录

后来去了现场之后发现现场的视频播放延迟在正常范围,讨论之后决定把服务器布到现场去,需求就变成了“把这个RTSP在浏览器播放”。于是我研究了一番,尝试使用webrtc-stream,也是一番折腾,本地跑通了,但是局域网内跑不通,gitHub上也没有找到合适的解决办法。

这时候又得知短期内用的只有海康摄像头,询问海康智能客服得到对接指南,海康提供的SDK和DEMO只能在Windows上用,Linux上没什么能迅速跑通的方案,内嵌到VUE项目中的方案,文档较为复杂麻烦。Chrome的session禁止共享安全策略等等问题,尝试过了均不能内嵌。一般解决方案都是跳转到海康的预览页面。

最后尝试ZLM方案成功。

其他方案

image.png

image.png

尝试的其他解决方案 node-media-server media-soup

media-soup-demo 跑通过程记录

webrtc-stream(跑通本地) 海康的SDK FFmpeg 总结 应该找一个方案一直做下去到走通为止 环境要想办法提前了解(比如不能用https,比如所有摄像头都是海康的,比如可以使用插件) 想办法挖掘真正的需求,需求工期都过一半了,我才知道原来要在大屏上用,且只需要考虑海康的摄像头,且可以用插件。

后端Leader从 “它太卡了!我要它不卡!” 到 “我要一个流媒体服务器!我不管我就要!” 到 “不然你用原来的那个DEMO!” (那个DEMO非常简单根本完全不能用)再到 “你自己写一个推拉流逻辑吧”

最后使用ZLM方案部署出问题 “你看看,那咋没有呢”

就。

还是要有自己的节奏,很多时候你听到的需求并不是真正的需求,连提出需求的人也不知道真正的需求是什么,虽然走了很多弯路,也学到了很多东西,这是在不混乱的团队里得不到的体验。



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3