Brian's Blog
Happy Coding

WebRTC_自制桌面监控

目录

  1. 前言
  2. webRTC设备管理及数据采集
  3. webRTC端对端音视频传输

前言

前一段时间在某宝,购入一台95新的iphone 4s,一是收藏之用,二是摆在桌子上当时钟使用,后来觉得只是当时钟使用太浪费了,想通前置摄像头,可以随时查看房间情况。在Google搜索的帮助下,了解到webRTC。

webRTC是Google在2010年开源夸平台用于浏览器实时传输音视频的引擎。是一个支持网页浏览器进行实时语音对话或视频对话的API。在直播和音视频通讯中应用较多。

webRTC设备管理及数据采集

开发环境:chrome浏览器+Javascript

  1. enumerateDevices(获取音视频设备)
1
2
3
4
5
navigator.mediaDevices.enumerateDevices().then((devices)=>{
devices.forEach(device => {
console.log(`设备的种类-${device.kind}设备的名称-${device.label}-设备ID-${device.deviceId}-groupId-${device.groupId}`)
});
})
  1. getUserMedia(获取音视频)
1
2
3
4
5
6
navigator.mediaDevices.getUserMedia({
video:true,
audio:true,
}).then((stream)=>{
document.getElementById('video').srcObject = stream;
})

注意:video标签一定要设置为muted,不然有回音和噪音

  1. 音视频数据约束

getUserMedia中的参数是对音视频进行采集约束,上面的两个参数代表收集视频和音频,里面还包含了对视频分辨率、画质等等约束。

例如:

1
2
3
4
5
6
7
navigator.mediaDevices.getUserMedia({
video:{
width:500,
height:500
},
audio:true,
})

其他参数可去MDN查询

  1. 浏览器适配问题

为了适配各种浏览器建议使用adapter.js

webRTC端对端音视频传输

webRTC不仅仅能获取音视频数据,还能把音视频数据进行端对端进行传输,共享远程桌面,录制,p2p网络加速文件传输等等。

连接过程:

1
2
3
4
5
6
7
8
A、B端同时创建RTCPeerConnection
A端调用addTrack,添加音视频流
A端创建offer(createOffer)生成SDP协议(A端媒体信息)
A端生成SDP之后,把自身的SDP添加到本地描述信息中去(setLocalDescription),会触发onicecandidate获取所有连接者信息
A端发送offer(A端媒体信息)到B端
B端添加A端媒体信息(setRemoteDescription),创建answer(createAnswer)生成SDP协议(B端媒体信息),把自身的SDP添加到本地描述信息中去(setLocalDescription),会触发onicecandidate获取所有连接者信息
B端发送answer(B端媒体信息)到A端,A端添加B端媒体信息(setRemoteDescription)
A、B两端媒体协商完成,B端通过ontrack就可以拿到A端的音视频流

实例代码:(模拟)

1
2
3
4
5
<video id="local" autoplay playsinline muted></video>
<video id="remote" autoplay playsinline></video>
<button id="start">开始</button>
<button id='call'>呼叫</button>
<button id="stop">结束</button>

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
const startBtn = document.querySelector("#start");
const callBtn = document.querySelector("#call");
const stopBtn = document.querySelector("#stop");
const localVideo = document.querySelector("#local");
const remoteVideo = document.querySelector("#remote");
var localStream = null;
var localPC = null;
var remotePC = null;
startBtn.onclick = function(){
if (navigator.mediaDevices || navigator.mediaDevices.getUserMedia) {
navigator.mediaDevices.getUserMedia({
video:true,
audio:false
}).then((stream)=>{
localVideo.srcObject = stream;
localStream = stream;
})
}
}
callBtn.onclick = function(){
localPC = new RTCPeerConnection();
remotePC = new RTCPeerConnection();
localPC.onicecandidate = (e) => {
remotePC.addIceCandidate(e.candidate)
}
remotePC.onicecandidate = e => {
localPC.addIceCandidate(e.candidate)
}
remotePC.ontrack = function(e){
remoteVideo.srcObject = e.streams[0];
}
localStream.getTracks().forEach(track => {
localPC.addTrack(track,localStream);
});

localPC.createOffer({
offerToReceiveAudio:1,
offerToReceiveVideo:1
}).then((desc)=>{
localPC.setLocalDescription(desc)
remotePC.setRemoteDescription(desc)
remotePC.createAnswer().then((descs)=>{
remotePC.setLocalDescription(descs)
localPC.setRemoteDescription(descs)
})
})
}
stopBtn.onclick = function(){
localPC.close();
remotePC.close();
localPC = null;
remotePC = null;
}

上面的代码只是一个简单本地传输的例子,要实现网络传输还需要用到websocket以及turn,在下篇文章中,我将详细介绍通过webrtc把4s的摄像头的画面传输到web端。