2

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

 11 months ago
source link: https://blog.p2hp.com/archives/11652
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

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

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

2.资料准备

官网:jsmpeg.com/

blog.csdn.net/a843334549/…

segmentfault.com/a/119000004…

juejin.cn/post/705740…

github.com/vCloudSail/…

studygolang.com/articles/25…

3.兼容性及适用性说明

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

4.jsmpeg架构

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

根据这个架构我们的想法是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框架写了,互联网和开源拯救了大家,直接参考一下:studygolang.com/articles/25…

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

  • 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())
    } 
81e0accac9134659a9c6a55450cd4f0a~tplv-k3u1fbpfcp-zoom-in-crop-mark:1512:0:0:0.awebp
  • 2.ffmpeg调用使用当前路径的ffmpeg,否则如果你设备上安装了ffmpeg的话可能路径会乱
util.Log().Debug("FFmpeg cmd: ./ffmpeg %v", strings.Join(params, " "))
cmd := exec.Command("./ffmpeg", params...)
c4f8be20a05d4fab9f93cc33960bc92f~tplv-k3u1fbpfcp-zoom-in-crop-mark:1512:0:0:0.awebp
  • 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即可看到效果了:

ea9223d5db264038b066390a3dfa43b3~tplv-k3u1fbpfcp-zoom-in-crop-mark:1512:0:0:0.awebp

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


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK