浏览器播放rtsp视频流:4、jsmpeg+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...)

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-cwQNq0I1-1667219726107)(https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/c4f8be20a05d4fab9f93cc33960bc92f~tplv-k3u1fbpfcp-zoom-1.image)]

  • 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,而固步自封的结果大家也已经看到不少了。

  • 0
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 5
    评论
要在Java后台中获取RTSP视频流,可以使用JavaCV这个开源库。它提供了一个名为FFmpeg的Java接口,可以让你直接在Java中使用FFmpeg的功能。 以下是获取RTSP视频流的示例代码: ```java import org.bytedeco.javacv.*; import javax.swing.*; public class RTSPTest { public static void main(String[] args) throws Exception { String rtspUrl = "rtsp://example.com/stream.mp4"; // RTSP流地址 FFmpegFrameGrabber grabber = new FFmpegFrameGrabber(rtspUrl); grabber.start(); CanvasFrame canvas = new CanvasFrame("RTSP Stream"); // 创建一个窗口用于显示视频流 canvas.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); while (true) { Frame frame = grabber.grab(); if (frame == null) { break; } canvas.showImage(frame); } grabber.stop(); canvas.dispose(); } } ``` 这个代码片段使用JavaCV的FFmpegFrameGrabber类从RTSP地址获取视频流,并将每一帧显示到一个Swing窗口上。 如果你想在浏览器中无插件播放RTSP视频流,可以使用WebRTC技术。WebRTC是一种基于Web的实时通信技术,它可以让你在浏览器中直接播放RTSP视频流,而不需要使用任何插件。 以下是使用WebRTC播放RTSP视频流的示例代码: ```html <!DOCTYPE html> <html> <head> <title>RTSP Stream</title> </head> <body> <video id="video" autoplay></video> <script> const video = document.getElementById('video'); const stream = new MediaStream(); // RTSP地址 const rtspUrl = 'rtsp://example.com/stream.mp4'; // 创建RTSP客户 const client = new rtsp.RTSPClient(); client.connect(rtspUrl); client.onMedia = ({ track, type }) => { // 将RTSP流添加到MediaStream中 stream.addTrack(track); // 如果是视频流,则将其绑定到video元素 if (type === 'video') { video.srcObject = stream; } }; client.start(); </script> </body> </html> ``` 这个代码片段使用了一个名为rtsp.js的开源库来实现WebRTC播放RTSP流。它创建了一个RTSP客户,并将获取到的视频流添加到一个MediaStream中,最终将视频流绑定到一个video元素上,从而在浏览器中无插件播放RTSP视频流
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

昵称系统有问题

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值