实现RTSP监控视频在浏览器播放--webrtc-streamer

2,070 阅读3分钟

由于目前浏览器不支持flash插件,使很多支持播放视频的插件, 如videojs等并不可使用

目前可以实现的RTSP的方法:

1.后端通过使用FFmpegRTSP视频转码。前端结合videojs插件等实现浏览器显示

2.通过webrtc-streamer实现RTSP视频在浏览器播放,但是此方法需要电脑后台启动8000端口号(查阅网上很多相关内容,端口和地址都是可以实现更改实现适配的)

  1. 。。。。(还有其他的就不列举了)

最近项目涉及大屏显示监控视频,刚开始接到这个任务以为通过videojs插件等可以完成任务,事实证明是我异想天开了。

在和后端对接时候发现,公司返回的监控视频是RTSP格式的监控视频,通过自己本地测试 + videojs插件的结合并没有实现此功能。

于是,我开始查阅网上各种相关的文章,同时结合最近比较火热的chatGPT来帮助我快速实现相关的功能,出乎意料看文章加实际操作大概花费一两天时间还是没有实现。

由于经常刷掘金沸点,所以通过在掘金沸点寻求帮助,JYM给了很多的解决方法,最多的就是让后端进行转码,前端根据后端转码的链接进行展示。我去找公司的后端,让他通过FFmpegRTSP视频转码。又经历一天的时间,后端把转码的视频链接发我测试,但是由于这样的方式太消耗服务器资源,公司的项目组老大不允许后端这样做,也就只能作罢。

真是经历千辛万苦最终决定试试webrtc-streamer实现此功能

具体实现步骤:

1.首先要去github下载 webrtc-streamer,我是使用Windows系统,要根据自己的想要实现的系统选择具体的压缩包

webrtc-streamer 版本0.7.0 (链接来自blog.csdn.net/m0_66509866…

2.将下载的压缩包解压,打开解压的文件夹执行以下步骤:

image.png

3.将html文件夹里面的webrtcstreamer.jslibs文件夹的adapter.min.js一起放在vue项目文件夹里面

4.需要下载videojs插件

5.将播放RTSP视频写成组件 webrtcSteamer.vue(注:需要引入webrtcstreamer.js

<!--
 * @Description: rtsp视频播放
-->

<template>
  <div class="webrtcSteamer s-fill s-flex">
      <video
        id="video"
        class="video-js"
        controls
        autoplay
        autobuffer
        muted
        preload="auto"
      ></video>
  </div>
</template>

<script>
import WebRtcStreamer from '../common/webrtcstreamer.js'
export default {
  props: {
    scale: {
      type: Number,
      required: true
    },
    videoUrl:{
      type: String,
      required: true
    },
  },
  data () {
    return {
      httpServer: '',
      rtspUrl: this.videoUrl,
      player: null,
      webRtcServer: null,
      videoSeting: {
        language: 'zh-CN',
        autoplay: true, // true/false 播放器准备好之后,是否自动播放 【默认false】
        controls: true, // /false 是否拥有控制条 【默认true】,如果设为false ,那么只能通过api进行控制了。也就是说界面上不会出现任何控制按钮
        loop: false, // /false 视频播放结束后,是否循环播放
        muted: true, // /false 是否静音
        poster: '', // 播放前显示的视频画面,播放开始之后自动移除。通常传入一个URL
        preload: 'auto', // 预加载   ‘auto‘ 自动   ’metadata‘ 元数据信息 ,比如视频长度,尺寸等 ‘none‘ 不预加载任何数据,直到用户开始播放才开始下载
        bigPlayButton: true,
      },
    }
  },

  mounted () {
    var a = `${window.location.href}`
    var b = a.split(':')
    this.httpServer = `${b[0]}:${b[1]}:8000/`
    console.log('httpServer', this.httpServer)
    // 初始化webrec服务
    this.webRtcServer = new WebRtcStreamer('video', this.httpServer)
    this.webRtcServer.connect(this.rtspUrl)
  },

  methods: {
    playVideo () {
      this.webRtcServer.connect(this.rtspUrl)
    },
  },
}
</script>

<style lang="less" scoped>
.webrtcSteamer {
  &-num {
    color: #06FBFC;
    font-weight: 500;
    font-family: 'PingFang SC';
  }
}
.video-js {
  width: 100%;
  height: 100%;
}
</style>


基本就完成功能的实现。

但是,这是基于本地测试可行,但是如果发到线上客户是没有启动webrtc-streamer.exe程序,监控视频是无法打开的。

目前公司处理方式是在页面显示webrtcstreamer的压缩包链接下载提示,检测客户是否开启8000端口,如果没有检测到8000端口则让客户自己下载webrtcstreamer的压缩包实现监控视频的显示。我觉得这样做的可视化并不强,但是目前没有想到更好的方式实现。

补充和解释

最近看了留言又回顾一下具体最终实现代码和开发中遇到的问题如何解决的做一些解释

  1. 实现过程就是webrtc-streamer启动的端口是8000,会在页面提供一个下载webrtc-streamer包的链接。(目前项目上线rtsp播放的实现过程:我的理解就是走本地,服务端部署的并未实现... 如果有大佬实现了服务端部署欢迎在评论区留言哦~ )
  2. 报错问题

image.png

    this.webRtcServer.connect(this.rtspUrl)

修改

   this.webRtcServer.connect(this.rtspUrl,null,'rtptransport=tcp&timeout=60')

第一个参数:this.rtspUrl

  • 含义:RTSP 协议的 实时视频流地址this 表示从当前上下文读取的变量)
  • 举例:实际值通常是类似 rtsp://admin:123456@192.168.1.100:554/stream1 的格式 ——包含设备账号(admin)、密码(123456)、设备 IP(192.168.1.100)、端口(554,RTSP 默认端口)、流通道(stream1)。
  • 作用:告诉 WebRTC 服务 “要连接哪个设备的哪个视频流”。

第二个参数:null

  • 含义:可选配置参数(预留参数位)。
  • 作用:通常用于传递额外连接配置(比如 WebRTC 的 ICE 服务器地址、媒体编码格式、认证信息等)。传 null 表示 “使用默认配置”,不需要自定义额外参数(简化开发,适合基础场景)。

第三个参数:'rtptransport=tcp&timeout=60'

  • 含义:RTSP 连接的 核心附加参数(键值对格式,用 & 分隔,类似 URL 查询参数)。
  • 拆解两个关键参数:
  • rtptransport=tcp:指定 RTP 数据的传输方式为 TCP(RTP 是实时传输协议,负责传输音视频数据)。

✅ 优势:TCP 传输可靠(不丢包),适合网络不稳定的场景(比如内网监控),能避免视频卡顿、花屏;

❌ 对比:如果写 rtptransport=udp,UDP 传输更快但易丢包,适合高速稳定网络。

  • timeout=60:指定 连接超时时间为 60 秒。作用:如果发起连接后,60 秒内没成功建立通信(比如设备离线、网络不通),会自动终止连接并触发 “超时失败” 回调(避免无限等待占用资源)。
  1. 如果用户第一次使用是需要手动下载webrtc-streamer包,并运行启动。所以代码 a = ${window.location.href} (获取当前页面 URL) 修改为 a = http://localhost:8009 (本地运行项目的localhost+端口号的URL)
mounted () {
    setTimeout(async () => {
      var a = `http://localhost:8009`
      // var a = `${window.location.href}`
      var b = a.split(':')
      this.httpServer = `${b[0]}:${b[1]}:8000/`
      // 初始化webrec服务
      this.webRtcServer = new WebRtcStreamer('video', this.httpServer)
      this.webRtcServer.connect(this.rtspUrl, null, 'rtptransport=tcp&timeout=60')
    }, 1000)
  },

欢迎大家指正不足之处,如果有更好的实现方可以评论,一起学习进步。

参考的博主链接:blog.csdn.net/m0_66509866…