怎么把rtsp视频流转成webrtc接口

简介: 【8月更文挑战第8天】将RTSP视频流转换为WebRTC接口涉及多个步骤:首先使用工具如webrtc-streamer、ffmpeg等从RTSP源获取视频流;接着对流进行解码与编码至WebRTC兼容格式(如VP8、H.264);然后利用WebSocket建立客户端与服务器间的双向信令通道;再通过JavaScript创建WebRTC PeerConnection并交换SDP信息;最后添加Track传输视频数据,并在接收端解析显示。使用webrtc-streamer可简化这一过程,其API支持多种操作如添加ICE候选、创建Offer等。




将RTSP视频流转换为WebRTC接口需要进行以下步骤:


获取RTSP视频流:使用相应的库或工具,如webrtc-streamer、ffmpeg、GStreamer等,从RTSP服务器或摄像头获取视频流。


解码和编码:对于获取到的视频流,需要进行解码(将其转换成原始帧数据)和编码(将其转换成WebRTC支持的格式,如VP8、H.264)处理。可以使用FFmpeg或其他多媒体处理库来完成这些操作。


WebRTC信令传输:使用WebSocket或其他实时通信协议,在客户端和服务器之间建立双向通信的信道。这是用于传输音频/视频数据和控制消息的关键步骤。


建立PeerConnection:在客户端使用JavaScript代码创建WebRTC PeerConnection对象,并通过信令通道交换SDP(Session Description Protocol)信息。


传输视频流:在PeerConnection中添加Track以传输视频数据。可以通过调用getUserMedia()方法获取本地视频轨道,并将其添加到PeerConnection中。


接收端解析和显示:在接收端,使用WebRTC API解析接收到的音频/视频数据,并将其显示在浏览器上。



一、webrtc-streamer的API

webrtc-streamer的服务地址:192.168.1.8:8000

查询所有api:http://192.168.1.8:8000/api/help

[

"/api/addIceCandidate",

"/api/call",

"/api/createOffer",

"/api/getAudioDeviceList",

"/api/getIceCandidate",

"/api/getIceServers",

"/api/getMediaList",

"/api/getPeerConnectionList",

"/api/getStreamList",

"/api/getVideoDeviceList",

"/api/hangup",

"/api/help",

"/api/log",

"/api/setAnswer",

"/api/version"

]

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

进入解压目录 指定绑定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

image.png

2.windows版本部署

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

image.png


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

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

image.png

四、springboot整合webrtc-streamer

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


          1、前端部分:


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


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

<!DOCTYPE html>

<html lang="en">

<head>

   <meta charset="UTF-8">

   <title>Title</title>

   <script type="text/javascript" src="adapter.min.js"></script>

   <script type="text/javascript" src="webrtcstreamer.js"></script>

   <script type="text/javascript" src="jquery-1.7.1.min.js"></script>

   <style>

       video {

           width: 300px;

           height: 200px;

       }

   </style>

</head>

<body>

<p>视频播放</p>

<div>

   <video id="video1" muted autoplay loop controls>muted controls disablePictureInPicture</video>

   <video id="video2" muted autoplay loop controls>muted controls disablePictureInPicture</video>

</div>

<div>

   <video id="video7" muted autoplay loop controls>muted controls disablePictureInPicture</video>

   <video id="video8" muted autoplay loop controls>muted controls disablePictureInPicture</video>

 

</div>

<div>

   <video id="video13" muted autoplay loop controls>muted controls disablePictureInPicture</video>

   <video id="video14" muted autoplay loop controls>muted controls disablePictureInPicture</video>

 

</div>

<div>

   <video id="video19" muted autoplay loop controls>muted controls disablePictureInPicture</video>

   <video id="video20" muted autoplay loop controls>muted controls disablePictureInPicture</video>

 

</div>

<script>

   var cameralist = new Array();

   var camera64 = {type: "hik", ipaddr: "192.168.1.64", username: "admin", password: "hik12345", port: 554};

   window.onload = function () {

       // 初始化内容

       cameralist.push(camera64);

       console.log(cameralist);

   }

   let num = 0;

 

   function getCamera() {

       let obj = cameralist[num];

       console.log(obj);

       num++;

       if (num == 1) {

           num = 0;

       }

       return obj;

   }

 

   let webRtcServer = null;

   let videoMap = new Map();

   $('video').click(function (e) {

       let ID = e.target.id;//获取当前点击事件的元素

       console.log(ID);

       if (videoMap.get(ID) != null) {

           closeVideo(ID, videoMap.get(ID));

       } else {

           let camera = getCamera();

           console.log(camera);

           if (camera.type == "ys") {

               realViewYs("192.168.1.11", ID, camera.username, camera.password, camera.ipaddr, camera.port);

           } else if (camera.type == "dh") {

               realViewDh("192.168.1.11", ID, camera.username, camera.password, camera.ipaddr, camera.port);

           } else {

               realViewHik("112.98.126.2", ID, camera.username, camera.password, camera.ipaddr, camera.port);

           }

       }

   });

 

 

   //预览海康相机

   function realViewHik(serverip, elem, username, password, ipaddr, port) {

       webRtcServer = new WebRtcStreamer(elem, "http://" + serverip + ":28000");

       let rtspUrl = "rtsp://" + username + ":" + password + "@" + ipaddr + ":" + port + "/ch1/main/av_stream";

       let option = "rtptransport=tcp";

       console.log("rtsp地址:" + rtspUrl);

       webRtcServer.connect(rtspUrl, null, option, null);

       videoMap.set(elem, webRtcServer);

   }

 

   //预览大华相机

   function realViewDh(serverip, elem, username, password, ipaddr, port) {

       webRtcServer = new WebRtcStreamer(elem, "http://" + serverip + ":8000");

       let rtspUrl = "rtsp://" + username + ":" + password + "@" + ipaddr + ":" + port + "/cam/realmonitor?channel=1&subtype=0";

       let option = "rtptransport=tcp";

       console.log("rtsp地址:" + rtspUrl);

 

       webRtcServer.connect(rtspUrl, null, option, null);

       videoMap.set(elem, webRtcServer);

   }

 

   //预览宇视相机

   function realViewYs(serverip, elem, username, password, ipaddr, port) {

       webRtcServer = new WebRtcStreamer(elem, "http://" + serverip + ":8000");

       let rtspUrl = "rtsp://" + username + ":" + password + "@" + ipaddr + ":" + port + "/media/video1/multicast";

       console.log("rtsp地址:" + rtspUrl);

       let option = "rtptransport=tcp";

       webRtcServer.connect(rtspUrl, null, option, null);

       videoMap.set(elem, webRtcServer);

   }

 

   function closeVideo(id, webrtc) {

       webrtc.disconnect();

       videoMap.delete(id);

   }

 

   //页面退出时销毁

   // window.onbeforeunload = function () {

   //     alert("页面关闭");

   //     webRtcServer.disconnect();

   // }

   //页面离开或者浏览器关闭的时候触发

   window.onbeforeunload = function (event) {

       $.ajax({

           // url: "../getIp",

           url: "http://127.0.0.1:12344/ard/videocall",

           type: "post",

           contentType: "application/json",

           dataType: "json",

           data: JSON.stringify({"cmd": "close", "url": "https://anruida.app.zihai.shop/?id=zns&pass=ard"}),

           success: function (data) {

           }

       });

       webRtcServer.disconnect();

   };

 

</script>


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




目录
相关文章
|
2月前
|
iOS开发 开发者
iOS平台RTMP|RTSP播放器如何实时回调YUV数据
我们在做RTMP、RTSP播放器的时候,有开发者需要自己处理拉取到的YUV数据,做二次分析之用,为此,我们做了以下的设计:InitPlayer之后,再调用SmartPlayerStart()接口之前,设置yuv数据回调即可。
|
2月前
|
算法 数据处理 开发工具
Android平台RTSP|RTMP播放器如何回调YUV或RGB数据
在开发Android平台上的RTSP或RTMP播放器时,开发者不仅追求低延迟播放,还希望获取解码后的视频数据(如YUV或RGB格式),以便进行视觉算法分析。使用大牛直播SDK中的SmartPlayer,可在确保播放流畅的同时,通过设置外部渲染器(`SmartPlayerSetExternalRender`)来高效地回调原始视频数据。例如,对于RGBA数据,需实现`NTExternalRender`接口,并重写相关方法以处理数据和尺寸变化。同样地,对于I420(YUV)数据,也需要相应地实现接口以满足需求。这种方式使得开发者能在不影响常规播放功能的情况下,进行定制化的视频处理任务。
|
2月前
|
监控 开发工具 数据安全/隐私保护
Windows平台如何实现多路RTSP|RTMP流合成后录像或转发RTMP服务
本文介绍了在Windows平台上实现多路RTSP/RTMP视频流的合并技术。主要应用场景包括驾考、全景摄像头以及多路会议录制等。技术实现上,文章详细展示了如何使用特定的SDK来解码并回调YUV或RGB数据,再将这些数据按照图层形式进行合成。示例代码中给出了初始化参数、设置视频帧回调函数、以及如何配置不同图层的具体步骤。最终,合成后的视频可以推送到RTMP服务器、注入到本地RTSP服务,或是直接录制为MP4文件。此外,还提供了添加实时文字水印的方法,并展示了四路视频流合成后的“四宫格”效果。
|
编解码 开发工具 开发者
如何支持RTSP播放H.265(HEVC)流
随着H.265的普及,越来越多的开发者希望大牛直播SDK能支持低延迟的RTSP H.265播放,并分享相关经验: 实现思路: 对rtsp来说,要播放h265只要正确解析sdp和rtp包即可. 下面对这些相关内容做一些介绍.
405 1
|
vr&ar 开发工具 图形学
Windows平台Unity3d下如何同时播放多路RTSP或RTMP流
好多开发者在做AR、VR或者教育类产品时,苦于如何在windows平台构建一个稳定且低延迟的RTSP或者RTMP播放器,如果基于Unity3d完全重新开发一个播放器,代价大、而且周期长,不适合快速出产品,我们认为当前最好的方式就是集成现有Native平台上成熟稳定播放器,回调rgb/yuv数据到上层,上层做绘制即可。
130 1
|
存储 编解码 缓存
海康摄像头开发笔记(一):连接防爆摄像头、配置摄像头网段、设置rtsp码流、播放rtsp流、获取rtsp流、调优rtsp流播放延迟以及录像存储
Hik防爆摄像头录像,因为防爆摄像头会有对应的APP软件,与普通的网络摄像头和球机不一样,默认认为它不可以通过web网页配置,所以弄了个来实测确认。经测试实际上也是可以通过web网页配置(与网络摄像头基本是一致的,在码流方面可能会有些不一样),然后提取rtsp流的,界面与球机无异,只是没有球机的云台控制功能,但是界面上也是有的。
海康摄像头开发笔记(一):连接防爆摄像头、配置摄像头网段、设置rtsp码流、播放rtsp流、获取rtsp流、调优rtsp流播放延迟以及录像存储
|
开发工具 图形学 Android开发
如何在Unity3d平台下低延迟播放RTMP或RTSP流
随着VR类、工业仿真、智慧城市等场景的快速发展,开发者对Unity3d低延迟的直播需求量越来越大,前两年,大牛直播SDK发布了Windows平台、Android平台和iOS平台的Unity3d RTMP和RTSP的播放,好多公司用起来体验都非常好,以下介绍大概实现流程。
228 0
|
Linux 开发工具 图形学
Unity下如何实现RTMP或RTSP流播放和录制
在探讨Unity平台RTMP或RTSP直播流数据播放和录制之前,我们先简单回顾下RTSP或RTMP直播流数据在Unity平台的播放流程: 1. 通过Native RTSP或RTSP直播播放SDK回调RGB/YUV420/NV12等其中的一种未压缩的图像格式; 2. Unity下创建相应的RGB/YUV420等Shader; 1. Unity从各个平台获取图像数据来填充纹理即可。
290 0
|
编解码 Android开发 iOS开发
如何推送和播放RTMP H265流 (RTMP HEVC)
rtmp 播放h265 首先要扩展flv协议,国内常用扩展方式是给flv的videotag.codecid增加一个新类型(12)来表示h265(hevc),其他和h264规则差不多,另外和h264不同的地方是要解析HEVCDecoderConfigurationRecord,从HEVCDecoderConfigurationRecord中解析出vps, sps, pps. 有了vps, sps, pps, 就可以解码。
389 0
|
开发工具 Android开发 开发者
Android平台RTMP推流或轻量级RTSP服务(摄像头或同屏)编码前数据接入类型总结
很多开发者在做Android平台RTMP推流或轻量级RTSP服务(摄像头或同屏)时,总感觉接口不够用,以大牛直播SDK为例 (Github) 我们来总结下,我们常规需要支持的编码前音视频数据有哪些类型:
144 0