百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 技术文章 > 正文

WebRTC原理与web端实战开发(webrtc技术详解)

zhezhongyun 2025-03-30 23:09 48 浏览

什么是WebRTC

webRtc(web real-time Communication) ,旨在建立一个浏览器间实时通信的平台

  • 谷歌开源
  • 跨平台(android,IOS,windows,Linux)
  • 实时传输(提供强大的音视频引擎)

RTC涉及的流程及内容

采集->编码->传输->解码->渲染

采集:捕获摄像头、麦克风设备数据(yuv,pcm)

编码:将yuv、pcm格式数据编码(h264、vp8、opus、aac)

传输:将编码后的桢数据打包传输,应对弱网环境(QOS),RTP/RTCP协议传输数据

解码:将编码后的数据解码成yuv/pcm数据

渲染:将解码后的数据展示到渲染窗口

WebRTC架构

架构说明:

your web app:是你的应用程序通过Web Api方式实现的音视频程序。

Web Api: 在C++的API层封装了一次WebAPI 的WEBRTC接口给上层应用调用。

WEBRTC C++ API:暴露C++封装的WEBRTC真实实现。

Session Manager:会话层,用于接收会话信息和结束会话信息。

Voice Engine:音频引擎编解码。

Video Engine:视频引擎编解码

Transport:数据传输引擎。

WebRTC通信流程图

描述:

1.客户端A要与客户端B通信,需要连接信令服务。

2.客户端A要与客户端B通信,需要连接STUN/TURN服务器做NAT转发IP转换。

3.客户端A要与客户端B通信,需要通过信令服务将两者NAT转发IP做交换。

4.两者媒体协商成功,就可以音视频通信。

WebRTC API 枚举音视频设备

//功能说明:枚举音视频设备
//返回说明:描述设备的MediaDeviceInfo数组
var promise= navigator.mediaDevices.enumerateDevices();
//示例文档:https://developer.mozilla.org/zh-CN/docs/Web/API/MediaDevices
//注意事项:
// 1.如果需要获取音视频枚举必须给浏览器设备允许获取音频或视频设备信息。
// 2.如果项目发布到互联网中需要使用HTTPS协议

WebRTC API 采集音视频设备数据

//功能说明:采集音视频设备数据
//参数说明:paramters
var promise = navigator.mediaDevices.getUserMedia(constaints);
//示例文档:https://developer.mozilla.org/zh-CN/docs/Web/API/MediaDevices/getUserMedia
//注意事项:获取音视频数据需要用标签播放

WebRTC API 采集桌面窗口数据

//功能说明:采集桌面数据
//参数说明:paramters
var promise= navigator.mediaDevices.getDisplayMedia(constaints);
//示例文档:https://developer.mozilla.org/zh-CN/docs/Web/API/MediaDevices/getDisplayMedia

WebRTC API 适配

  • WebRTC标准推出之前,各大浏览器厂商使用自己对WebRTC规范支持API不一致
  • 例如:
    • 谷歌:webkitGetUserMedia
    • 火狐:mozGetUserMedia
  • 如果用户自行编写适配不同浏览器的应用层程序,如下所示
    • var getUserMedia = navigator.getUserMedia || navigator.webkitGetUserMedia || navigator.mozGetUserMedia;
  • 兼容不同浏览器API的适配程序
  • <script src="https://webrtc.github.io/adapter/adapter-latest.js"></script>

本文福利, 免费领取C++音视频学习资料包+学习路线大纲、技术视频/代码,内容包括(音视频开发,面试题,FFmpeg ,webRTC ,rtmp ,hls ,rtsp ,ffplay ,编解码,推拉流,srs),有需要的可以进企鹅裙927239107领取哦~

MediaStream

播放音视频返回的是MediaStream对象,MediaStream用于表示媒体内容,它包含了一系列音视频轨道(MediaStream API)

构造方式:getUserMedia / getDisplayMedia / new MediaStream();

主要方法:

MediaStream.addTrack();

MediaStream.getTrack() / MediaStream.getAudioTracks() / MediaStream.getVideoTracks()

MediaStreamTrack

MediaStreamTrack表示一个具体的音视频轨道,例如音频轨道,适配轨道

重要数据:

MediaStreamTrack.id

MediaStreamTrack.kind

MediaStreamTrack.label

重要方法:


MediaStreamTrack.getConstraints() 获取轨道约束


MediaStreamTrack.getSettings() 获取轨道当前设置属性


RTCPeerConnection

概念:RTCPeerConnection 用于表示一个与远程的对等连接

构造方式:var pc = new RTCPeerConnection([configuration])

媒体协商的主要方式:

AddTrack:将音视频轨道添加到RTCPeerConnection,这些轨道将发送到对端

createOffer / createAnswer: 生成offer /answer SDP信息


setLocalDescription/setRemoteDescription :将SDP描述信息设置RTCPeerConnection 的本地/远程描述信息

媒体协商

问题:什么是媒体协商,为什么要进行媒体协商?媒体协商包含了哪些信息?

Amy和Bob要进行音视频通话

Amy采集摄像头/麦克风数据,进行编码,打包,然后通过网络输出Bob

Bob接收媒体包数据后需要组桢,解码,渲染

双方需要协商使用的编解码器,编解码器的具体参数,通过包含了哪些媒体信息,媒体怎么区分等

媒体协商流程

WebRTC 网络穿越

思考:两个WebRTC客户端怎么实现端到端通讯?

  • 场景1:客户端A和客户端B都处于公网
  • 场景2:客户端A和客户端B有一方处于公网,另外一方处于内外(NAT之后)
  • 场景3:客户端A和客户端B处于内外
    • A:同一内部网络
    • B:不同内部网络

NAT(NETWORK Address Translator)

什么是NAT?

网络地址转换,负责将内外地址转换公网地址的互相转换

为什么需要NAT?

IPV4地址不够

网络安全考虑

NAT类型

P2P穿越

使用coturn搭建STUN/TURN服务器

sudo apt-get update
sudo apt-get install coturn

#修改/etc/turnserver.conf文件的配置,如下
listening-port=3478
external-ip=公网服务器外网ip
lt-cred-mech
user=username1:password1
realm=mycompany.org

#启动
turnserver-c /etc/turnserver.conf

https://webrtc.github.io/samples/src/content/peerconnection/trickle-ice/

ICE

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

1.收集候选地址

2.交互候选项

3.STUN 连接检查

4.选定地址并启动媒体

5.KeepAlive

收集候选地址既收集本端或许可用于接收媒体以建立起对等连接的IP地址和端口



候选地址分类:

1.主机候选者(host):网卡的实际地址

2.服务器反射候选者(srflx):STUN服务器恢复STUN binding success response 中的反射地址,最后外层NAT的地址

3.中续候选者(relay):请求turn服务器的中续地址

4.对端反射候选者(prflx):从对端发送的STUN binding request中获取传输地址,本端无法收集到该类型候选地址。

RTCPeerConnection收集并交换候选者

RTCPeerConnection收集并交换候选者
事件: icecandidate
发生时机: RTCPeerConnection调用setLocalDescription之后
处理方式: rtcPeerConnection.onicecandidate =(event)=>{
if(event.candidate){
//将本地候选者发送给对端
}else {
//表示在本地协商中没有更多的候选者了

}

https://developer.mozilla.org/en-US/docs/Web/API/RTCPeerConnection/icecandidate_event

RTCPeerConnection收集并交换候选者


接收到对端候选者后的处理方式addlcecandidate
语法: addlceCandidate(candidate)
参数: candidate 类型是RTCIceCandidatelnit,包含 candidate, sdpMid, sdpMLinelndex, usernameFragment 成
https://developer.mozillaorg/en-US/docs/Web/API/RTCIceCandidate/RTCIceCandidate

RTCPeerConnection ontrack

事件:ontrack
发生时机:收到对端的媒体轨道
处理方式:将MediaStreamTrack添加到MediaStream,将MediaStream赋值给

RTCPeerConnection构造参数说明明

构造方式: 
var pc= new RTCPeerConnection([configuration]);
interface RTCConfiguration {
bundlePolicy?:RTCBundlePolicy;
certificates?:RTCCertificatell;
iceCandidatePoolSize?:number;
iceServers?:RTCIceServerl];
iceTransportPolicy?:RTCIceTransportPolicy;rtcpMuxPolicy?:RTCRtcpMuxPolicy;

https://developer.mozilla.org/en-US/docs/Web/API/RTCPeerConnection/RTCPeerConnection

信令服务器

相关推荐

Python入门学习记录之一:变量_python怎么用变量

写这个,主要是对自己学习python知识的一个总结,也是加深自己的印象。变量(英文:variable),也叫标识符。在python中,变量的命名规则有以下三点:>变量名只能包含字母、数字和下划线...

python变量命名规则——来自小白的总结

python是一个动态编译类编程语言,所以程序在运行前不需要如C语言的先行编译动作,因此也只有在程序运行过程中才能发现程序的问题。基于此,python的变量就有一定的命名规范。python作为当前热门...

Python入门学习教程:第 2 章 变量与数据类型

2.1什么是变量?在编程中,变量就像一个存放数据的容器,它可以存储各种信息,并且这些信息可以被读取和修改。想象一下,变量就如同我们生活中的盒子,你可以把东西放进去,也可以随时拿出来看看,甚至可以换成...

绘制学术论文中的“三线表”具体指导

在科研过程中,大家用到最多的可能就是“三线表”。“三线表”,一般主要由三条横线构成,当然在变量名栏里也可以拆分单元格,出现更多的线。更重要的是,“三线表”也是一种数据记录规范,以“三线表”形式记录的数...

Python基础语法知识--变量和数据类型

学习Python中的变量和数据类型至关重要,因为它们构成了Python编程的基石。以下是帮助您了解Python中的变量和数据类型的分步指南:1.变量:变量在Python中用于存储数据值。它们充...

一文搞懂 Python 中的所有标点符号

反引号`无任何作用。传说Python3中它被移除是因为和单引号字符'太相似。波浪号~(按位取反符号)~被称为取反或补码运算符。它放在我们想要取反的对象前面。如果放在一个整数n...

Python变量类型和运算符_python中变量的含义

别再被小名词坑哭了:Python新手常犯的那些隐蔽错误,我用同事的真实bug拆给你看我记得有一次和同事张姐一起追查一个看似随机崩溃的脚本,最后发现罪魁祸首竟然是她把变量命名成了list。说实话...

从零开始:深入剖析 Spring Boot3 中配置文件的加载顺序

在当今的互联网软件开发领域,SpringBoot无疑是最为热门和广泛应用的框架之一。它以其强大的功能、便捷的开发体验,极大地提升了开发效率,成为众多开发者构建Web应用程序的首选。而在Spr...

Python中下划线 ‘_’ 的用法,你知道几种

Python中下划线()是一个有特殊含义和用途的符号,它可以用来表示以下几种情况:1在解释器中,下划线(_)表示上一个表达式的值,可以用来进行快速计算或测试。例如:>>>2+...

解锁Shell编程:变量_shell $变量

引言:开启Shell编程大门Shell作为用户与Linux内核之间的桥梁,为我们提供了强大的命令行交互方式。它不仅能执行简单的文件操作、进程管理,还能通过编写脚本实现复杂的自动化任务。无论是...

一文学会Python的变量命名规则!_python的变量命名有哪些要求

目录1.变量的命名原则3.内置函数尽量不要做变量4.删除变量和垃圾回收机制5.结语1.变量的命名原则①由英文字母、_(下划线)、或中文开头②变量名称只能由英文字母、数字、下画线或中文字所组成。③英文字...

更可靠的Rust-语法篇-区分语句/表达式,略览if/loop/while/for

src/main.rs://函数定义fnadd(a:i32,b:i32)->i32{a+b//末尾表达式}fnmain(){leta:i3...

C++第五课:变量的命名规则_c++中变量的命名规则

变量的命名不是想怎么起就怎么起的,而是有一套固定的规则的。具体规则:1.名字要合法:变量名必须是由字母、数字或下划线组成。例如:a,a1,a_1。2.开头不能是数字。例如:可以a1,但不能起1a。3....

Rust编程-核心篇-不安全编程_rust安全性

Unsafe的必要性Rust的所有权系统和类型系统为我们提供了强大的安全保障,但在某些情况下,我们需要突破这些限制来:与C代码交互实现底层系统编程优化性能关键代码实现某些编译器无法验证的安全操作Rus...

探秘 Python 内存管理:背后的神奇机制

在编程的世界里,内存管理就如同幕后的精密操控者,确保程序的高效运行。Python作为一种广泛使用的编程语言,其内存管理机制既巧妙又复杂,为开发者们提供了便利的同时,也展现了强大的底层控制能力。一、P...