将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
2.windows版本部署
下载windows版本压缩包,解压后如下图
在当前目录下输入命令webrtc-streamer.exe -H 192.168.1.227:8000 -o
再次强调 -o 为了不转码,进而降低cpu负荷。
四、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>
局域网内访问相机视频就完成了。