程序员最近都爱上了这个网站  程序员们快来瞅瞅吧!  it98k网:it98k.com

本站消息

站长简介/公众号

  出租广告位,需要合作请联系站长


+关注
已关注

分类  

暂无分类

标签  

暂无标签

日期归档  

史上最详细的webrtc-streamer访问摄像机视频流教程

发布于2023-05-20 16:23     阅读(1076)     评论(0)     点赞(30)     收藏(3)


目录

前言

一、webrtc-streamer的API

二、webrtc-streamer的启动命令介绍

1.原文

2.译文 

三、webrtc-streamer的安装部署

1.下载地址

    https://github.com/mpromonet/webrtc-streamer/releases

2.windows版本部署

3.Linux版本部署

四、springboot整合webrtc-streamer

五、公网使用webrtc-streamer访问相机视频


前言

最近公司在搞流媒体,我推荐了webrtc-streamer进行搭建,使用了一段时间后,出现新的需求,需要将内网的摄像机进行公网访问,我查询了几乎所有的帖子和github的问题回复,都没有给我一个准确的答案,经过不断尝试和摸索,我终于成功了,我希望将我的过程记录下来,让更多的中国开发者可以少走弯路,我对于webrtc不是很了解,但是这并不影响我使用开源的webrtc-streamer进行开发。

一、webrtc-streamer的API

  1. webrtc-streamer的服务地址:192.168.1.8:8000
  2. 查询所有api:http://192.168.1.8:8000/api/help
  3. [
  4. "/api/addIceCandidate",
  5. "/api/call",
  6. "/api/createOffer",
  7. "/api/getAudioDeviceList",
  8. "/api/getIceCandidate",
  9. "/api/getIceServers",
  10. "/api/getMediaList",
  11. "/api/getPeerConnectionList",
  12. "/api/getStreamList",
  13. "/api/getVideoDeviceList",
  14. "/api/hangup",
  15. "/api/help",
  16. "/api/log",
  17. "/api/setAnswer",
  18. "/api/version"
  19. ]

关键api:/api/getPeerConnectionList

我使用它来判断当前的webrtc-streamer正在连接的通道

2个通道:

ICE: 交互式连接建立(Interactive Connectivity Establishment)

ice_state:交互式连接状态(2:已连接/5:断开连接)

pc_state:客户端连接状态(2:正常/3:断开)

  • 已连接:

"ice_state": 2

"pc_state": 2

  • 正在断开:

"ice_state": 5

"pc_state": 3

  • 这种状态未知:

"ice_state": 0

"pc_state": 0

  • 断开:

无任何json数据

正常连接的json如下(sdp内容过多已删除):

[

  {

    "0.07123060004985127": {

      "ice_state": 2,

      "pc_state": 2,

      "sdp": "",

      "signaling_state": 0,

      "streams": {

        "15661718658374446496": {

          "15661718658374446496_video": {

            "kind": "video",

            "state": 1

          }

        }

      }

    }

  }

  ]

二、webrtc-streamer的启动命令介绍

1.原文

  1. ./webrtc-streamer [-H http port] [-S[embeded stun address]] -[v[v]] [url1]...[urln]
  2. ./webrtc-streamer [-H http port] [-s[external stun address]] -[v[v]] [url1]...[urln]
  3. ./webrtc-streamer -V
  4. -v[v[v]] : verbosity
  5. -V : print version
  6. -H [hostname:]port : HTTP server binding (default 0.0.0.0:8000)
  7. -w webroot : path to get files
  8. -c sslkeycert : path to private key and certificate for HTTPS
  9. -N nbthreads : number of threads for HTTP server
  10. -A passwd : password file for HTTP server access
  11. -D authDomain : authentication domain for HTTP server access (default:mydomain.com)
  12. -S[stun_address] : start embeded STUN server bind to address (default 0.0.0.0:3478)
  13. -s[stun_address] : use an external STUN server (default:stun.l.google.com:19302 , -:means no STUN)
  14. -t[username:password@]turn_address : use an external TURN relay server (default:disabled)
  15. -T[username:password@]turn_address : start embeded TURN server (default:disabled)
  16. -a[audio layer] : spefify audio capture layer to use (default:0)
  17. -q[filter] : spefify publish filter (default:.*)
  18. -o : use null codec (keep frame encoded)
  19. -C config.json : load urls from JSON config file
  20. -R [Udp port range min:max] : Set the webrtc udp port range (default 0:65535)
  21. -n name -u videourl -U audiourl : register a name for a video url and an audio url
  22. [url] : url to register in the source list

2.译文 

  1. ./webrtc-streamer [-H http port] [-S[embeded stun address]] -[v[v]] [url1]...[urln]
  2. ./webrtc-streamer [-H http port] [-s[external stun address]] -[v[v]] [url1]...[urln]
  3. ./webrtc-streamer -V
  4. -v[v[v]] : verbosity
  5. -V : 打印版本
  6. -H [hostname:]port : HTTPServer绑定 (default 0.0.0.0:8000)
  7. -w webroot : 获取文件的路径
  8. -c sslkeycert : HTTPS的私钥和证书路径
  9. -N nbthreads : HTTP服务器的线程数
  10. -A passwd : 用于HTTP服务器访问的密码文件
  11. -D authDomain : HTTP服务器访问的身份验证域(默认值:mydomain.com)
  12. -S[stun_address] : 使用嵌入的STUN服务器绑定到地址(默认值为0.0.0.0:3478
  13. -s[stun_address] : 使用外部的STUN服务器绑定到地址(默认值为0.0.0.0:3478
  14. -t[username:password@]turn_address : 使用外部TURN中继服务器(默认:禁用)
  15. -T[username:password@]turn_address : 使用嵌入式TURN中继服务器(默认:禁用)
  16. -a[audio layer] : 指定要使用的音频捕获层(默认值:0
  17. -q[filter] : 指定发布筛选器(默认值:.*)
  18. -o : 使用空编解码器(保持帧编码)
  19. -C config.json : 从JSON配置文件加载URL
  20. -R [Udp port range min:max] : 设置webrtc-udp端口范围(默认值为0:65535
  21. -n name -u videourl -U audiourl : 注册视频url和音频url的名称
  22. [url] : 要在源列表中注册的url

举例:

指定绑定ip端口:./webrtc-streamer -H 192.168.1.8:8123

注意几个细节:

1、-o 这个命令务必要加上,不加的话你会发现你的cpu预览几路马上飙升到100%。

2、 -s/-S/-t/-T这几个命令后面不要有空格。

3、只支持H264的视频码流,H265不支持。

三、webrtc-streamer的安装部署

1.下载地址

    https://github.com/mpromonet/webrtc-streamer/releases

     目前最新版本0.7.2版本

     

 红框内分别为windows版本和Linux版本

2.windows版本部署

下载windows版本压缩包,解压后如下图

 在当前目录下输入命令webrtc-streamer.exe -H 192.168.1.227:8000 -o

再次强调 -o  为了不转码,进而降低cpu负荷。

3.Linux版本部署

         系统环境都正常的情况安装步骤如下:

        1.webrtc-streamer包:webrtc-streamer-v0.7.2-Linux-x86_64-Release.tar.gz

        2.拷贝到root下,解压:tar -xvf webrtc-streamer-v0.7.2-Linux-x86_64-Release.tar.gz

        3.进入webrtc-streamer-v0.7.2-Linux-x86_64-Release:cd webrtc-streamer-v0.7.2-Linux-x86_64-Release

        

        4.执行 ./webrtc-streamer -H 192.168.1.10:8000 -o

        

         Linux大概率会报错缺少环境,这个自行搜索解决。如果实在解决不了,给我留言吧。

四、springboot整合webrtc-streamer

             这部分我就快速贴代码了。

           1、前端部分:

                   项目需要引入的js:webrtcstreamer.js、adapter.min.js、jquery-1.7.1.min.js

                   我这里配置了24个video用来测试,分别支持宇视、大华、海康的RTSP流。

  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head>
  4. <meta charset="UTF-8">
  5. <title>Title</title>
  6. <script type="text/javascript" src="adapter.min.js"></script>
  7. <script type="text/javascript" src="webrtcstreamer.js"></script>
  8. <script type="text/javascript" src="jquery-1.7.1.min.js"></script>
  9. <style>
  10. video {
  11. width: 300px;
  12. height: 200px;
  13. }
  14. </style>
  15. </head>
  16. <body>
  17. <p>视频播放</p>
  18. <div>
  19. <video id="video1" muted autoplay loop controls>muted controls disablePictureInPicture</video>
  20. <video id="video2" muted autoplay loop controls>muted controls disablePictureInPicture</video>
  21. <video id="video3" muted autoplay loop controls>muted controls disablePictureInPicture</video>
  22. <video id="video4" muted autoplay loop controls>muted controls disablePictureInPicture</video>
  23. <video id="video5" muted autoplay loop controls>muted controls disablePictureInPicture</video>
  24. <video id="video6" muted autoplay loop controls>muted controls disablePictureInPicture</video>
  25. </div>
  26. <div>
  27. <video id="video7" muted autoplay loop controls>muted controls disablePictureInPicture</video>
  28. <video id="video8" muted autoplay loop controls>muted controls disablePictureInPicture</video>
  29. <video id="video9" muted autoplay loop controls>muted controls disablePictureInPicture</video>
  30. <video id="video10" muted autoplay loop controls>muted controls disablePictureInPicture</video>
  31. <video id="video11" muted autoplay loop controls>muted controls disablePictureInPicture</video>
  32. <video id="video12" muted autoplay loop controls>muted controls disablePictureInPicture</video>
  33. </div>
  34. <div>
  35. <video id="video13" muted autoplay loop controls>muted controls disablePictureInPicture</video>
  36. <video id="video14" muted autoplay loop controls>muted controls disablePictureInPicture</video>
  37. <video id="video15" muted autoplay loop controls>muted controls disablePictureInPicture</video>
  38. <video id="video16" muted autoplay loop controls>muted controls disablePictureInPicture</video>
  39. <video id="video17" muted autoplay loop controls>muted controls disablePictureInPicture</video>
  40. <video id="video18" muted autoplay loop controls>muted controls disablePictureInPicture</video>
  41. </div>
  42. <div>
  43. <video id="video19" muted autoplay loop controls>muted controls disablePictureInPicture</video>
  44. <video id="video20" muted autoplay loop controls>muted controls disablePictureInPicture</video>
  45. <video id="video21" muted autoplay loop controls>muted controls disablePictureInPicture</video>
  46. <video id="video22" muted autoplay loop controls>muted controls disablePictureInPicture</video>
  47. <video id="video23" muted autoplay loop controls>muted controls disablePictureInPicture</video>
  48. <video id="video24" muted autoplay loop controls>muted controls disablePictureInPicture</video>
  49. </div>
  50. <script>
  51. var cameralist = new Array();
  52. var camera64 = {type: "hik", ipaddr: "192.168.1.64", username: "admin", password: "hik12345", port: 554};
  53. window.onload = function () {
  54. // 初始化内容
  55. cameralist.push(camera64);
  56. console.log(cameralist);
  57. }
  58. let num = 0;
  59. function getCamera() {
  60. let obj = cameralist[num];
  61. console.log(obj);
  62. num++;
  63. if (num == 1) {
  64. num = 0;
  65. }
  66. return obj;
  67. }
  68. let webRtcServer = null;
  69. let videoMap = new Map();
  70. $('video').click(function (e) {
  71. let ID = e.target.id;//获取当前点击事件的元素
  72. console.log(ID);
  73. if (videoMap.get(ID) != null) {
  74. closeVideo(ID, videoMap.get(ID));
  75. } else {
  76. let camera = getCamera();
  77. console.log(camera);
  78. if (camera.type == "ys") {
  79. realViewYs("192.168.1.11", ID, camera.username, camera.password, camera.ipaddr, camera.port);
  80. } else if (camera.type == "dh") {
  81. realViewDh("192.168.1.11", ID, camera.username, camera.password, camera.ipaddr, camera.port);
  82. } else {
  83. realViewHik("112.98.126.2", ID, camera.username, camera.password, camera.ipaddr, camera.port);
  84. }
  85. }
  86. });
  87. //预览海康相机
  88. function realViewHik(serverip, elem, username, password, ipaddr, port) {
  89. webRtcServer = new WebRtcStreamer(elem, "http://" + serverip + ":28000");
  90. let rtspUrl = "rtsp://" + username + ":" + password + "@" + ipaddr + ":" + port + "/ch1/main/av_stream";
  91. let option = "rtptransport=tcp";
  92. console.log("rtsp地址:" + rtspUrl);
  93. webRtcServer.connect(rtspUrl, null, option, null);
  94. videoMap.set(elem, webRtcServer);
  95. }
  96. //预览大华相机
  97. function realViewDh(serverip, elem, username, password, ipaddr, port) {
  98. webRtcServer = new WebRtcStreamer(elem, "http://" + serverip + ":8000");
  99. let rtspUrl = "rtsp://" + username + ":" + password + "@" + ipaddr + ":" + port + "/cam/realmonitor?channel=1&subtype=0";
  100. let option = "rtptransport=tcp";
  101. console.log("rtsp地址:" + rtspUrl);
  102. webRtcServer.connect(rtspUrl, null, option, null);
  103. videoMap.set(elem, webRtcServer);
  104. }
  105. //预览宇视相机
  106. function realViewYs(serverip, elem, username, password, ipaddr, port) {
  107. webRtcServer = new WebRtcStreamer(elem, "http://" + serverip + ":8000");
  108. let rtspUrl = "rtsp://" + username + ":" + password + "@" + ipaddr + ":" + port + "/media/video1/multicast";
  109. console.log("rtsp地址:" + rtspUrl);
  110. let option = "rtptransport=tcp";
  111. webRtcServer.connect(rtspUrl, null, option, null);
  112. videoMap.set(elem, webRtcServer);
  113. }
  114. function closeVideo(id, webrtc) {
  115. webrtc.disconnect();
  116. videoMap.delete(id);
  117. }
  118. //页面退出时销毁
  119. // window.onbeforeunload = function () {
  120. // alert("页面关闭");
  121. // webRtcServer.disconnect();
  122. // }
  123. //页面离开或者浏览器关闭的时候触发
  124. window.onbeforeunload = function (event) {
  125. $.ajax({
  126. // url: "../getIp",
  127. url: "http://127.0.0.1:12344/ard/videocall",
  128. type: "post",
  129. contentType: "application/json",
  130. dataType: "json",
  131. data: JSON.stringify({"cmd": "close", "url": "https://anruida.app.zihai.shop/?id=zns&pass=ard"}),
  132. success: function (data) {
  133. }
  134. });
  135. webRtcServer.disconnect();
  136. };
  137. </script>

        2、后端部分

        后端部分简单多了,初学者应该都会吧,直接配置个controller找这个html就行了。

  1. @GetMapping("/")
  2. String index() {
  3. return "view";
  4. }

启动项目打开127.0.0.1:8080

至此,局域网内访问相机视频就完成了。

五、公网使用webrtc-streamer访问相机视频

通过上面的步骤局域网内访问相机视频流已经可以实现了,但是如果你想把项目部署到公网中进行访问就不行了。

公网部署步骤:

1、配置webrtc-streamer所在服务器的内网穿透地址,例如内网192.168.1.8:8000 映射到公网为110.154.21.14:18000

2、部署一个本地coturn服务器,配置conturn服务器配置文件,同时将conturn服务器的3478的tcp和udp端口进行公网映射。

3、前端js页面使用公网地址也就是110.154.21.14:18000配置webrtc-streamer

4、启动命令增加turn和stun服务器:webrtc-streamer.exe -o -H 192.168.1.8:8000 -S110.154.21.14:3478 -Tadmin:123456@110.154.21.14:3478

正式开始:

第一步,使用路由器将webrtc内网映射到公网,这个我相信你玩这个肯定会,不同的交换机配置不同。

第二步,Linux下WebRTC搭建私有turn/stun服务,目前coturn只支持linux。

            coturn是一个免费的开源的TURN/STUN服务器。coturn 服务器完整的实现了STUN/TURN/ICE协议,支持P2P穿透防火墙。
            STUN 服务器用于获取设备的外部网络地址。
            TURN 服务器是在点对点失败后用于通信中继。
            WebRTC 建立连接的步骤大概是这样的:
            客户端(浏览器)直接尝试直连;
            如果如果直连则通过 STUN 服务器进行穿透;
            如果无法穿透则通过 TURN 服务器进行中转。

  1. 1. 安装前准备
  2. http://libevent.org/ 下载 libevent-2.1.12-stable.tar.gz
  3. wget https://github.com/coturn/coturn/archive/4.5.1.1.tar.gz 下载 conturn-4.5.1.1.tar.gz (稳定版本)
  4. (如果undefined reference to `SSL_CTX_up_ref'的错误换用稳定版本就好了。)
  5. 2. 安装gcc
  6. yum install gcc-c++
  7. 3. 安装openssl-devel
  8. yum -y install openssl-devel
  9. 4. 安装libevent2
  10. 在http://libevent.org/下载libevent-2.1.8-stable.tar.gz
  11. tar -zxvf libevent-2.1.8-stable.tar.gz
  12. cd libevent-2.1.8-stable
  13. ./configure --prefix=/usr --libdir=/usr/lib64 (如果报错试试这个方式:./configure --prefix=/usr/local/coturn)
  14. make
  15. make install
  16. 成功没有出现报错信息
  17. 5. 安装conturn-4.5.1.1
  18. tar -zxvf 4.5.1.1.tar.gz
  19. cd coturn-4.5.1.1
  20. ./configure
  21. make
  22. make install
  23. 可以通过which turnserver验证。如果出现路径即为成功
  24. 6. 配置文件和签名,然后进入文件夹:
  25. cd /usr/local/etc/ 会看到一个叫做 turnserver.conf.default的配置文件。将它备份:
  26. cp turnserver.conf.default turnserver.conf
  27. 7. 在当前文件夹生成签名(自行输入):
  28. openssl req -x509 -newkey rsa:2048 -keyout /usr/local/etc/turn_server_pkey.pem -out /usr/local/etc/turn_server_cert.pem -days 99999 -nodes
  29. 8. 修改配置文件
  30. Vim turnserver.conf 参考如下
  31. relay-device=eth0
  32. listening-ip=#内网IP
  33. listening-port=3478
  34. tls-listening-port=5349
  35. relay-ip=#内网IP
  36. external-ip=#公网IP
  37. relay-threads=50
  38. lt-cred-mech
  39. min-port=49152
  40. max-port=65535
  41. cert=/usr/local/etc/turn_server_cert.pem
  42. pkey=/usr/local/etc/turn_server_pkey.pem
  43. pidfile=”/var/run/turnserver.pid”
  44. user=admin:123456
  45. cli-password=123456
  46. 将配置文件更新如上。
  47. 请一定要设置cli-password这一项,不设置会报错。
  48. 注意检查cert和pkey的路径和名称。检查内网ip和公网ip是否填写准确。
  49. 注意文本格式准确。
  50. 9. 启动turnserver
  51. turnserver -o -a -f -user=admin:123456 -c /usr/local/etc/turnserver.conf -r xiamen
  52. -o 是让程序在后台启动
  53. -r 后面填个地区就行。
  54. -user 一定要和配置文件中一样。
  55. ps -ef|grep turnserver 指令查看是否启动服务,如果有
  56. 10. 验证
  57. Trickle ICE:https://webrtc.github.io/samples/src/content/peerconnection/trickle-ice/
  58. 1、stun:+公网IP+端口,测试出现公网IP则代表部署成功
  59. 2、turn:+公网IP+端口,测试出现公网IP则代表部署成功

    可能出现的问题:

1、libevent configure: error: OpenSSL could not be found. You should add the directory解决办法

        直接在线安装:yum -y install openssl-devel

2、yum 安装软件报错 : There are no enabled repos.

        可能是相关yum源被删除了:

        wget -O /etc/yum.repos.d/CentOS-Base.repo http://mirrors.aliyun.com/repo/Centos-7.repo

        yum clean all && yum makecache


 只需要做webrtc-streamer服务器的tcp:8000端口、coturn服务器的tcp/udp:3478端口的映射即可。

相机的地址不需要映射。

至此公网访问视频流完成!有问题请留言。

原文链接:https://blog.csdn.net/qq_20937557/article/details/129879697



所属网站分类: 技术文章 > 博客

作者:我是一个射手

链接:http://www.javaheidong.com/blog/article/673667/c4ca9a7b93f91707da33/

来源:java黑洞网

任何形式的转载都请注明出处,如有侵权 一经发现 必将追究其法律责任

30 0
收藏该文
已收藏

评论内容:(最多支持255个字符)