浏览器播放rtsp视频流:4jsmpeg+go实现局域网下的rtsp视频流web端播放

Posted xiaoyaoyou.xyz

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了浏览器播放rtsp视频流:4jsmpeg+go实现局域网下的rtsp视频流web端播放相关的知识,希望对你有一定的参考价值。

文章目录

1.前言

之前的rtsp转webrtc的方案存在如下缺陷:1.只支持h264;2.受限于webrtc的理解难度以及搭建turn/stun的p2p服务等问题,对于局域网下的业务需求来说有些杀猪用牛刀的意思;3.ios不支持webrtc。

基于以上原因,我又找到了一些其它的方案进行了测试,目前看jsmpeg的方案更加适合我们的需求,而且普通压缩大小为135kb,gzip方式压缩后仅仅42kb,在嵌入式场景下也可以使用。只是转码服务需要ffmpeg,在不进程裁剪开发的情况下,需要在设备或者PC或者局域网路由器设备等上安装的该插件服务会比较大。

2.资料准备

官网:https://jsmpeg.com/

https://blog.csdn.net/a843334549/article/details/120697574

https://segmentfault.com/a/1190000040622805

https://juejin.cn/post/7057406701565116452

https://github.com/vCloudSail/jsmpeg-player

https://studygolang.com/articles/25474

3.兼容性及适用性说明

  • 这种方案适合局域网使用,目前测试实时性也非常不错,就像jempeg官网说的最低可达50ms,我测试下来对实时性是很满意的。
  • 此外,这种方案的视频编码和浏览器的兼容性非常棒,支持h264/h265,支持目前市面上的很多浏览器,我测试过Chrome浏览器、QQ浏览器、360浏览器、搜狗浏览器、Firefox浏览器、UC浏览器、Opera浏览器、Microsoft Edge浏览器、Safari 浏览器等都是可以运行的。

4.jsmpeg架构

  • jsmpeg比较重要的两个技术点:webglwasm,只需大致了解即可,若不对这两个模块进行二次开发,则无需深究
  • jsmpeg.js采用软解码方式,仅支持mpeg1格式视频、mp2格式音频!!! ,将视频流解码成图片并渲染到canvas上,并且可在源码基础上二次开发

根据这个架构我们的想法是jsmpeg客户端使用前端开发,该客户端唯一比较大的就是jsmpeg.js,不压缩也就100k多一点,压缩后更小,这样就可以放到很多设备中了,甚至很多嵌入式设备都都可以,然后我们将http、websocket服务端使用后端语言来开发,比如node.js、Java、Go、c++等,ffmpeg转码这里快速开发可以直接用ffmpeg,要再裁剪的话可以自己用C再开发一下,我们只需要转H264/H265到mpeg1,AAC到mp2,然后将对应的音视频格式的流通过websocket分发到jsmpeg客户端就可以了。

5.基于以上架构的go方案可行性分析

本来想自己开发的,结果随便搜了一下,已经有人用go的gin框架写了,互联网和开源拯救了大家,直接参考一下:https://studygolang.com/articles/25474

代码我整体看了一下,也跑了一下,修改了三个部分:

  • 1.一分钟后就会自动断开,这里注释就可以了(这里过一分钟就发送q主动断开了);
case <-time.After( 60 * time.Second):
    _, _ = stdin.Write([] byte ( "q" ))
    err := cmd.Wait()
    if err != nil 
        util.Log().Error( "Run ffmpeg err %v" , err.Error())
     

  • 2.ffmpeg调用使用当前路径的ffmpeg,否则如果你设备上安装了ffmpeg的话可能路径会乱
util.Log().Debug("FFmpeg cmd: ./ffmpeg %v", strings.Join(params, " "))
cmd := exec.Command("./ffmpeg", params...)

  • 3.html的js中增加了主动发送http请求获取ws地址的response处理部分,方便测试
<!DOCTYPE html>
<html>
<head>
   <title>JSMpeg Stream Client</title>
   <style type="text/css">
      html, body 
         text-align: center;
      
   </style>

</head>
<body>
   <canvas id="video-canvas"></canvas>

   <canvas id="video-canvas1"></canvas>

   <script type="text/javascript" src="jsmpeg.min.js"></script>
   <script type="text/javascript">
      var request = new XMLHttpRequest();
      var url = "http://127.0.0.1:3000/stream/play"; //接口url
request.open("POST", url, true);
      request.setRequestHeader("Content-type", "application/json");
      request.send('"url": "rtsp://192.168.31.204/main_stream"'); //传入的数据,不同摄像头修改这里的rtsp地址即可
request.onreadystatechange = function()
         //若响应完成且请求成功
if(request.readyState === 4 && request.status === 200)
            //do something, e.g. request.responseText
console.log("response:"+request.responseText)
            const resObj = JSON.parse(request.responseText);
            if (resObj['data']) 
               if (resObj['data']['path']) 
                  console.log("ws path:"+resObj['data']['path'])

                  var canvas1 = document.getElementById('video-canvas1');
                  // var url = 'ws://127.0.0.1:3000/stream/live/test';
var wsUrl = 'ws://127.0.0.1:3000'+resObj['data']['path']
                        console.log("ws url:"+wsUrl)
                  var player = new JSMpeg.Player(wsUrl, canvas: canvas1);
               
            
         
      
   </script>
</body>
</html>

这里还有一个坑点,留给大家去探索吧:长时间运行后如果推流的rtsp服务存在断流的话就没有画面了,这个没有webrtc服务的容错机制,需要自行判断处理,否则长时间跑之后画面就没了。

此外,http接口还可以增加ptz、preset等接口,这个仍然可以使用onvif协议来处理。

6.编译和结果展示(编译坑点)

编译Go代码很方便,但是我这里建议使用go1.18,go1.19在Windows下使用“./”会报错,必须使用“.\\”,这个需要注意,然后就go build即可生成可执行程序了。

之后修改html中的request.send中的rtsp的地址后访问该html即可看到效果了:

7.最后

很多时候,共同讨论才能更快的进步,开源让Linux成长的很快,不管是家电还是汽车、手机等等,生活中很多东西都可以见到Linux,而固步自封的结果大家也已经看到不少了。

ffmpeg+jsmpeg+nginx实现多道h5视频直播

需求:华为、海康威视等的摄像头直播格式为rtsp://***,要求在web页面中展示大屏同时显示5个摄像头的视频直播,不能使用任何播放器。

尝试过ie安装vlc插件可以,其他的chrome等浏览器对vlc的支撑很弱。

https://wiki.videolan.org/Documentation:WebPlugin/

在插件的官网上,由于主流的浏览器版本不能支撑vlc的播放效果。所以希望能从服务器端通过配置的方式解决,前端直接调用url的方式处理。

解决问题的思路是:获取摄像头数据流 --> FFmpeg转码 --> Node.js(搭建webSocket服务器) --> 在服务器上运行jsmpeg程序

记录下具体的操作过程如下:

本机操作系统:win10,虚拟机centos7.

1.先安装好nodejs和ffmpeg.

可以参考之前的文章

--安装nodejs---https://blog.csdn.net/peaceoncemore/article/details/116458340?spm=1001.2014.3001.5501

--安装ffmpeg--https://blog.csdn.net/peaceoncemore/article/details/116461999?spm=1001.2014.3001.5501

2.下载jsmpeg库

https://codeload.github.com/phoboslab/jsmpeg/zip/master

下载jsmpeg-master.zip后解压。可以修改容易记忆的名称  

$ unzip jsmpeg-master.zip

$ mv jsmpeg-master jsmpeg

3.Node.js安装webSocket模块

$ npm install ws -g

4.运行jsmpeg文件夹里面的websocket-relay.js

进入jsmpeg文件夹,运行websocket模块

$ cd /soft/jsmpeg

指令格式:node websocket-relay.js 密码 ffmpeg推送端口 前端webSocket端口

$ node websocket-relay.js password123456 8083 8082

注:第一次使用8081端口,报端口被占用,换成了8083端口

5.运行ffmpeg进行视频转码并转发

指令示例:ffmpeg -i “rtsp地址” -q 0 -f mpegts -codec:v mpeg1video -s 1366x768 http://127.0.0.1:8081/password123456

ffmpeg -rtsp_transport tcp  -i rtsp://wowzaec2demo.streamlock.net/vod/mp4:BigBuckBunny_115k.mov -q 0 -f mpegts -codec:v mpeg1video -s 1366*768 http://127.0.0.1:8083/password123456

6.配置nginx,方便从浏览器端访问

安装nginx,下载稳定版本。

http://nginx.org/en/download.html

$ cd /soft

$ rz 

解压到对应的文件夹下

$ tar -zxvf  nginx-1.20.0.tar.gz

$ cd nginx-1.12.0

使用默认配置安装

$ ./configure

编译安装

make && make install

需要端口

为了避免端口重复,把默认的80端口修改成9098

启动

$ cd /usr/local/nginx/sbin

$ ./nginx

注:其他的相关命令

--停止--  ./nginx -s stop

--退出-- ./nginx -s quit

--重启-- ./nginx -s reload

注:在本机尝试,直接192.168.121.128:9098不能访问,但是ping 192.168.121.128是通的。后来查证发现是centos7的防火墙限制了端口,关闭防火墙ok了

关闭防火墙

$ systemctl status firewalld.service  #查看防火墙状态

$ systemctl stop firewalld.service            #停止firewall

$ systemctl disable firewalld.service    #禁止firewall开机启动

设置 iptables service

$ yum -y install iptables-services

如果要修改防火墙配置,如增加防火墙端口3306

$ vi /etc/sysconfig/iptables 

增加规则

-A INPUT -m state --state NEW -m tcp -p tcp --dport 3306 -j ACCEPT

保存退出后

$ systemctl restart iptables.service #重启防火墙使配置生效

$ systemctl enable iptables.service #设置防火墙开机启动

关闭防火墙之后可以正常启动了看到欢迎页面。

7.配置nginx.conf,访问只想ws对应的视频页面

$ cd /usr/local/nginx/conf

$ vim nginx.conf

配置root指向jsmpeg,index指向view-stream.html

打开http://192.168.121.128:9098

单个视频播放的ok了

8.配置多是视频同时播放

这里配置以配置2例做说明,多路照着写就可以了。

尝试配置多个端口发现2个视频都在一个页面显示了,视频不停闪烁,一会儿上个视频一会儿下个视频,如何把串在一起的视频分开呢,ws分别对应不同的端口是否ok?经过尝试ok,操作如下:

思路--jsmpeg下配置两个不同的ws对应的端口html----nginx配置不同的端口指向不同的ws对应的html--运行两路独立的视频播放

$ cd /soft/jsmpeg

$ vim view-stream.html

不太习惯命令行地编写代码,导出找个html到本地修改后再上传

$ sz view-stream.html

默认的端口是8082,修改端口为:8089,同时修改个容易记忆的名称为view-live2.html

上传对应的文件到/soft/jsmpeg下

修改/usr/local/nginx/conf/nginx.conf的配置,新增一个server

重启nginx

$ cd /usr/local/nginx/sbin

$ ./nginx -s reload

(1)关闭掉之前打开的ws和ffmpeg运行的终端,从新进入

(2)$cd /soft/jsmpeg

(3)保留这个终端不关闭,从新开一个终端

(4)这个ws8082端口,对应nginx的9098端口,在win10中输入http://192.168.121.128:9098可以看到之前的视频流demo

然后(1)-(4)的步骤

(5)新开一个终端,从新进入 $ cd /soft/jsmpeg

ws对应的端口是8089,视频的端口写一个没有的,8088

(6)保留这个终端不关闭,从新开一个终端

(4)这个ws8082端口,对应nginx的9099端口,在win10中输入http://192.168.121.128:9099可以看到这个摄像头的直播

至此,2路直播已经配置完毕,如果多道,再继续配置,思路一样的。听闻一个ws最多能支撑15路视频直播,再多会很卡,没有试过辣么多的。

踩坑了几天,终于ok了,留个印记,方便以后翻阅。

用到的相关的下载资源会统一放到上传的资源中,方便安装。

以上是关于浏览器播放rtsp视频流:4jsmpeg+go实现局域网下的rtsp视频流web端播放的主要内容,如果未能解决你的问题,请参考以下文章

在web端实现rtsp流的视频的播放

WebRTC实现rtsp流在浏览器中播放

记:rtmp,rtsp,http视频流播放

JavaCV音视频开发宝典:使用JavaCV和springBoot实现websocket-flv直播服务,无需流媒体服务,浏览器网页flv.js播放器直接播放rtsp,rtmp等实时视频

JavaCV音视频开发宝典:使用JavaCV和springBoot实现websocket-flv直播服务,无需流媒体服务,浏览器网页flv.js播放器直接播放rtsp,rtmp等实时视频

JavaCV音视频开发宝典:使用JavaCV和springBoot实现websocket-flv直播服务,无需流媒体服务,浏览器网页flv.js播放器直接播放rtsp,rtmp等实时视频