WebRTC概述
WebRTC是一个Google开源的音视频处理+即时通讯的开源库,是一个跨平台的多媒体框架,能实现音视频的实时互动。
WebRTC架构
https://blog.csdn.net/xyphf/article/details/106606128
WebRTC源码目录结构
未完待续···
https://blog.csdn.net/xyphf/article/details/106629122
目录 | 功能描述 | 说明 |
---|---|---|
api | WebRTC接口层,浏览器都是通过该接口调用WebRTC | WebRTC的接口层,当我们想要增加接口或者调整接口时,需要在这里修改 |
call | 数据流的 管理层,Call代表同一个端点的所有数据的流入流出 | |
video | 与视频相关的逻辑 | |
audio | 与音频相关的逻辑 | |
common_audio | 音频算法相关 | |
common_video | 视频算法相关 | |
media | 与多媒体相关的逻辑处理,如编解码的逻辑处理 | |
logging | 日志相关 | |
module | 子模块(关键目录) | |
pc | Peer Connection,连接相关的逻辑层 | |
p2p | 端对端相关的代码,syun,turn | |
rtc_base | 基础代码 ,如线程、锁相关的统一接口代码 | |
rtc_tool | 音视频分析相关的工具代码 | |
tool_webrtc | WebRTC测试相关的工具,如网络模拟器 | |
system_wrappers | 与具体操作系统相关的代码。如CPU特性,原子操作等 | |
stats | 存放各种数据统计相关的类 | |
sdk | 存放Android和IOS层代码。如视频的采集,渲染等 |
WebRTC运行机制
轨(Track)、流(MedisStream)
首先要明确轨、流两个概念:
Track,采取了轨道的概念,音频是一路轨,视频也是一路轨,两个轨之间永远不会相交,所以视频和音频是单独存放的,两路音频或者两路视频也是不相交的,所以是两路轨。
MedisStream,借鉴了传统的媒体流的概念,流中包含了很多轨,包括音频轨、视频轨和字幕轨。
几个重要的类
MediaStream
RTCPeerConnection
WebRTC中最重要的一个类,
RTCDataChannel
非音视频的数据,都通过DataChannel进行传输(比如文本、文件、二进制数据等)
MediaRecorder
这个类用来实现媒体流的录制
var rec = new MediaRecorder(stream, [options]);
其中,参数stream是我们通过getUserMedia API获取到的stream,options是一个约束对象:
选项 | 对应值 | 说明 |
---|---|---|
mimeType | video/webm、audio/webm、video/webm;codescs=vp8、video/webm;codecs=h264、audio/webm;codecs=opus | 指定要录制的是视频还是音频,录制的格式是什么(最常见的视频是video/mp4;视频编码vp8,音频是audio/mp3;编码ac;) |
audioBitsPerSecond | 音频码率 | 每秒音频的码率 |
videoBitsPerSecond | 视频码率 | 视频的码率,设置的越多清晰度就越高 |
bitsPerSecond | 整体码率 | 总体的码率 |
MediaRecorder.start(timeslice)
开始录制媒体,timeslice是可选的,如果没填也就是它所有的数据都会存储到一个大的buffer里面去,如果设置了会按时间切片存储数据,比如10秒是一块数据再10秒是另外一块数据。
MediaRecorder.stop()
停止录制,此时会触发包括最终Blob数据的dataavilable事件
MediaRecorder.pause()
暂停录制
MediaRecorder.resume()
恢复录制
MediaRecorder.isTypeSupported()
检查支持录制的文件格式,如mp4、webp、mp3,这些都可以通过这个API检查一下是否支持
MediaRecorder.onerror
当有错误发生时,录制会自动的被停止
MediaRecorder.ondataavailable
当数据有效的时候会触发这个事件,每次记录一定时间的数据时(如果没有指定时间片,则记录整个数据时)会定期触发。
所以我们可以监听这个事件,当数据 有效了我们可以直接把这个数据存储到缓冲区里,在这个事件里面实际上会传过来一个event,在这个事件里面会有一个data,这个data就是真正录制后的数据,可以拿到这个数据之后进行存储。
getDisplayMedia
这个API用来捕获桌面内容
var promise = navigator.mediaDevices.getDisplayMedia(constraints);
参数constraints是可选的,具体内容与getUserMedia一致。
音视频设备的访问与管理
通过enumerateDevices API获取电脑中的音频和视频设备
var vPromise = navigator.mediaDevices.enumerateDevices()
这个API返回一个Promise,其中包含了一个对象叫做MediaDevicesInfo
,这个对象中包含了几个重要信息:
deviceId: 设备ID,是设个设备的唯一标识符
label:设备名称,人可读的名字,一般就是设备管理器中显示的名字
kind:设备的种类,一般分为视频输入设备、视频输出设备、音频输入设备等
groupId:如果两个设备的groupId相同,说明是同一个物理设备
音视频数据的采集
通过getUserMedia API进行音视频数据采集
var vPromise = navigator.mediaDevices.getUserMedia(constraints:MediaStreamConstraints)
这个方法有一个参数constraints,这是一个MediaStreamConstraints 类型的对象,这个对象中有两个元素:video和audio,这两个元素可以是布尔类型或者复杂媒体类型(MediaTrackConstraints)。
当这两个元素是布尔类型时,代表的含义是规定获取的媒体流中是否包含音频和视频。
当这两个元素是复杂媒体类型时,开发者可以在这里进行一些具体的控制,比如:设置视频的分辨率、设置帧率,设置音频的音量、延迟性、单声道双声道等,也可以通过deviceId指定具体的媒体设备。
dictionary MediaStreamConstraints {
(boolean or MediaTrackConstraints) video = false;
(boolean or MediaTrackConstraints) audio = false;
}
下面的demo中,在js中通过getUserMedia 获取到媒体流后,通过video组件在页面上进行显示:
<video autoplay playsinlin id="player"></video>
var videoplay = document.querySelector('video#player');
navigator.mediaDevices.getUserMedia({ video: true, audio: false})
.then((stream) => {
videoplay.srcObject = stream;
})
.catch((err) => {
console.log('Error!);
});
不同厂家的浏览器会有不同的getUserMedia API,因此有时候需要注意适配不同的浏览器