当前位置:   article > 正文

web播放rtsp流视频,使用webrtc毫秒级延迟_webrtc播放rtsp流

webrtc播放rtsp流

目录

一、zlmediakit环境搭建和编译

1)、下载zlmediakit

2)、安装依赖

3)、编译webrtc

4)、启动zlmediakit

二、播放webrtc视频

1)、动态添加拉流代理

2)、播放视频 

三、嵌入到自己的vue项目中。

1)、拷贝demo到自己的vue项目中

2)、mkcert生成证书


背景:需要在web应用中播放摄像头的rtsp流视频,并且延迟需要做到1秒以内。试过网上很多方法,都不能做到1秒内的延迟,可能有这种方案,只是我还没找到。所以我尝试了使用zlmediakit的webrtc功能进行播放。效果不错,视频画面很实时,目前只做了初步尝试,实际应用还需要研究。下面是我的步骤:

 系统:在ubuntu20.04和树莓派的raspberrypi系统都有尝试。

一、zlmediakit环境搭建和编译

1)、下载zlmediakit

  1. #下载代码
  2. git clone https://github.com/ZLMediaKit/ZLMediaKit.git
  3. cd ZLMediaKit
  4. #千万不要忘记执行这句命令
  5. git submodule update --init

2)、安装依赖

  • gcc
  1. #一般系统都会自带gcc,可以使用命令gcc -v 查看版本
  2. #如果没有的话使用以下命令安装
  3. sudo apt-get install build-essential
  • cmake
  1. #先查看系统有没有已经安装
  2. cmake --version
  3. #没安装就使用以下命令安装
  4. sudo apt-get install cmake
  • openssl
  1. #首先查看是否已经安装
  2. openssl version
  3. #没安装使用以下命令安装
  4. sudo apt-get install libssl-dev

3)、编译webrtc

  • 编译libsrtp
  1. #依次执行以下命令
  2. git clone https://gitee.com/mirrors/cisco-libsrtp.git
  3. cd cisco-libsrtp
  4. ./configure --enable-openssl
  5. make -j4
  6. sudo make install
  •  编译Zlmediakit

回到zlmediakit目录下 

  1. #依次执行以下命令
  2. mkdir build
  3. cd build
  4. cmake -DENABLE_WEBRTC=on ../
  5. cmake --build . --target MediaServer

 当进度变成100%就是编译完成了,可以看到目录下多了一个release目录。

4)、启动zlmediakit

  1. cd release/linux/Debug
  2. #通过-h可以了解启动参数
  3. ./MediaServer -h
  4. #以守护进程模式启动
  5. ./MediaServer -d &

  建议先使用sudo ./MediaServer 启动,可以方便查看日志

这时候zlmediakit已经启动了, 可以在浏览器输入虚拟机地址加上/webrtc访问webrtc播放demo

这时候还不能播放视频,需要将摄像头视频流注册到zlmediakit中,可以使用zlm的restful接口添加拉流代理,下面将有介绍。

二、播放webrtc视频

1)、动态添加拉流代理

在zlm官方文档中,有对restful接口的说明https://github.com/zlmediakit/ZLMediaKit/wiki/MediaServer%E6%94%AF%E6%8C%81%E7%9A%84HTTP-API

我们只需要使用这个动态添加拉流代理的接口即可

首先打开api工具,我这里使用的是apipost,当然还有其他的比如postman、apifox都是可以的。 

输入请求地址,发送的请求是post请求

根据文档中所需要填入的参数,我们这里将几个必选的参数加上,其中secret需要我们在配置文件中查看,打开/ZlmediaKit/release/linux/Debug目录,有一个config.ini文件,使用nano config.ini命令打开,可以看到secret的内容,我们将后面的字符串复制下来

在api工具中,我们在query里填入参数如下:

 secret就是我们刚刚获取的密钥。

vhost就填入运行zlm机器的ip就行。

app是流应用名,可以写live。

stream是流id,我们需要保证每个流id是唯一的,可以使用当前时间的时间戳,时间戳可以在ctool.dev中获取。

url为摄像头rtsp流地址,以海康摄像头为例,流地址组成格式为:rtsp://账号:密码@ip:554/h264/ch1/sub/av_stream,这里使用的是sub子码流,如果想用主码流换成main即可。

填写完成后点击发送,可以看到响应code为0,还响应了一个key,这个key就是我们拼接播放地址所需要的

2)、播放视频 

打开前面那个/webrtc/播放demo界面,将url中的ip和stream的值改成实际的值就可以点击开始播放了。

到此web中使用webrtc播放rtsp视频就结束了。下面我将介绍在自己的vue项目中播放的方法。

三、嵌入到自己的vue项目中。

1)、拷贝demo到自己的vue项目中

在release/linux/Debug目录下有一个www目录,进入后有一个webrtc目录,将里卖弄的index.html和ZLMRTCClient.js拷贝出来。

将ZLMRTCClient.js拷贝到自己的vue项目中,在文件的最下方加入

  1. export {
  2. ZLMRTCClient
  3. }

创建一个player.vue文件,将index.html文件中的内容拷贝到.vue文件下,根据自己的需求,将一些选项隐藏掉,将值改为固定的即可,文末我会给出我的player.vue完整代码。

因为webrtc是基于https协议的,我们还需要解决证书问题,这里我选用一个开源项目mckert来生成证书。

2)、mkcert生成证书

我这里使用windows本地开发的,所以直接在mkcert官网下载exe文件就可以。

https://github.com/FiloSottile/mkcert/releases

下载后将整个exe文件拖入终端命令行,加上-install,如下图

回车执行安装。

在工程下新建一个keys文件夹,进入到keys文件夹下,再次将exe拖入终端,执行如下命令

这时候keys文件夹下会生成两个文件

我使用的是vite搭建的vue项目,所以我在vite.config.js中配置以下内容

  1. server:{
  2. https:{
  3. key: 'keys/localhost+1-key.pem',
  4. cert: 'keys/localhost+1.pem',
  5. }
  6. }

重启系统便可以看到访问地址变成了https开头

这时候便可以在你的项目中播放摄像头rtsp视频流了。

下面是我的player.vue代码,写的比较粗糙,凑合用。我只保留了输入url和开始停止按钮。手动输入正确的url点击开始就可以播放了。

  1. <template>
  2. <div class="play-content">
  3. <div>
  4. <video id="video" controls autoplay style="text-align: left;width: 60%;">
  5. Your browser is too old which doesn't support HTML5 video.
  6. </video>
  7. </div>
  8. <div>
  9. <p>
  10. <label for="streamUrl">url:</label>
  11. <input
  12. type="text"
  13. style="co"
  14. v-model="PlayUrl"
  15. id="streamUrl"
  16. />
  17. </p>
  18. <button @click="start()">开始(start)</button>
  19. <button @click="stop()">停止(stop)</button>
  20. </div>
  21. </div>
  22. </template>
  23. <script setup>
  24. import {ZLMRTCClient} from '../../utils/ZLMRTCClient'
  25. import {ref}from 'vue'
  26. var player = null
  27. var recvOnly = false
  28. var resArr = []
  29. var ishttps = 'https:' == document.location.protocol ? true : false
  30. var isLocal = 'file:' == document.location.protocol ? true : false
  31. var url =
  32. document.location.protocol +
  33. '//' +
  34. window.location.host +
  35. '/index/api/webrtc?app=live&stream=test&type=play'
  36. if (!ishttps && !isLocal) {
  37. alert(
  38. '本demo需要在https的网站访问 ,如果你要推流的话(this demo must access in site of https if you want push stream)'
  39. )
  40. }
  41. if (isLocal) {
  42. url = 'http://127.0.0.1' + '/index/api/webrtc?app=live&stream=test&type=play'
  43. }
  44. // document.getElementById('streamUrl').value = url
  45. const PlayUrl = ref(url)
  46. const start_play = () => {
  47. let h = 720
  48. let w = 1280
  49. player = new ZLMRTCClient.Endpoint({
  50. element: document.getElementById('video'), // video 标签
  51. debug: true, // 是否打印日志
  52. zlmsdpUrl: document.getElementById('streamUrl').value, //流地址
  53. simulcast: false,
  54. useCamera: true,
  55. audioEnable: true,
  56. videoEnable: true,
  57. recvOnly: recvOnly,
  58. resolution: { w: w, h: h },
  59. usedatachannel: false
  60. })
  61. player.on(ZLMRTCClient.Events.WEBRTC_ICE_CANDIDATE_ERROR, function (e) {
  62. // ICE 协商出错
  63. console.log('ICE 协商出错')
  64. })
  65. player.on(ZLMRTCClient.Events.WEBRTC_ON_REMOTE_STREAMS, function (e) {
  66. //获取到了远端流,可以播放
  67. console.log('播放成功', e.streams)
  68. })
  69. player.on(ZLMRTCClient.Events.WEBRTC_OFFER_ANWSER_EXCHANGE_FAILED, function (e) {
  70. // offer anwser 交换失败
  71. console.log('offer anwser 交换失败', e)
  72. stop()
  73. })
  74. player.on(ZLMRTCClient.Events.CAPTURE_STREAM_FAILED, function (s) {
  75. // 获取本地流失败
  76. console.log('获取本地流失败')
  77. })
  78. player.on(ZLMRTCClient.Events.WEBRTC_ON_CONNECTION_STATE_CHANGE, function (state) {
  79. // RTC 状态变化 ,详情参考 https://developer.mozilla.org/en-US/docs/Web/API/RTCPeerConnection/connectionState
  80. console.log('当前状态==>', state)
  81. })
  82. player.on(ZLMRTCClient.Events.WEBRTC_ON_DATA_CHANNEL_OPEN, function (event) {
  83. console.log('rtc datachannel 打开 :', event)
  84. })
  85. // player.on(ZLMRTCClient.Events.WEBRTC_ON_DATA_CHANNEL_MSG, function (event) {
  86. // console.log('rtc datachannel 消息 :', event.data)
  87. // document.getElementById('msgrecv').value = event.data
  88. // })
  89. player.on(ZLMRTCClient.Events.WEBRTC_ON_DATA_CHANNEL_ERR, function (event) {
  90. console.log('rtc datachannel 错误 :', event)
  91. })
  92. player.on(ZLMRTCClient.Events.WEBRTC_ON_DATA_CHANNEL_CLOSE, function (event) {
  93. console.log('rtc datachannel 关闭 :', event)
  94. })
  95. }
  96. const start = () => {
  97. stop()
  98. let h = 720
  99. let w = 1280
  100. if (!recvOnly) {
  101. ZLMRTCClient.isSupportResolution(w, h)
  102. .then((e) => {
  103. start_play()
  104. })
  105. .catch((e) => {
  106. alert('not support resolution')
  107. })
  108. } else {
  109. start_play()
  110. }
  111. }
  112. const stop = () => {
  113. if (player) {
  114. player.close()
  115. player = null
  116. var remote = document.getElementById('video')
  117. if (remote) {
  118. remote.srcObject = null
  119. remote.load()
  120. }
  121. }
  122. }
  123. </script>
  124. <style scoped>
  125. .play-content{
  126. background-color: black;
  127. border: red 1px solid;
  128. width: 100%;
  129. height: 100%;
  130. color: white;
  131. }
  132. </style>

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/AllinToyou/article/detail/131963
推荐阅读
相关标签
  

闽ICP备14008679号