关于webrtc:WebRTC-真实IP泄露防范

WebRTC 实在IP泄露防备1.1. 前言很多人可能误以为应用代理就能够齐全暗藏咱们的实在IP地址,但理论并不总是这样。事实上,有大量文章指出,WebRTC存在平安危险,而WebRTC平安危险的可怕之处在于,即便你应用VPN代理上网,依然可能会裸露本人的实在IP地址。 尽管这听起来有点让人担心,但咱们不应该失去对代理技术的信念。代理仍然是一种十分有用的工具,能够爱护咱们的在线隐衷和平安。只是咱们须要意识到代理并不是百分之百牢靠的,因而咱们须要采取其余额定的措施来爱护本人的隐衷和平安。 1.2. 获取实在IP地址演示有如下3个网站举荐应用: https://ip8.com/webrtc-testhttps://www.hackjie.com/trackinghttps://dnsleaktest.org/dns-leak-test我平时比拟喜爱应用FireFox和Chrome,通过对这俩的测试,发现应用Firefox默认不会获取到实在IP,但Chrome就算挂了代理,依然能获取到实在IP地址。 1.3. WebRTC介绍WebRTC(Web Real-Time Communications)是一项实时通信技术,它容许网络应用或者站点,在不借助两头媒介的状况下,建设浏览器之间点对点(Peer-to-Peer)的连贯,实现视频流和(或)音频流或者其余任意数据的传输。WebRTC 蕴含的这些规范使用户在无需装置任何插件或者第三方的软件的状况下,创立点对点(Peer-to-Peer)的数据分享和电话会议成为可能。 1.4. WebRTC 透露实在IP原理WebRTC 容许浏览器之间间接建设点对点连贯,从而实现实时通信,例如视频、语音和数据传输。在建设 WebRTC 连贯时,浏览器会向对方发送本人的 IP 地址,以便单方建设连贯。攻击者能够通过 JavaScript 或其余技术来拜访 WebRTC 中的 API,以获取用户的 IP 地址,从而进行跟踪、监督或攻打。 具体来说,攻击者能够利用浏览器的 WebRTC API,通过申请媒体设施的权限,获取用户的 IP 地址。攻击者能够通过编写歹意 JavaScript 代码来执行这些申请,这些代码可能会被插入到网站中,以执行跨站点脚本攻打(XSS)等攻打。 此外,WebRTC 的 STUN/TURN 服务器也能够透露用户的 IP 地址。STUN/TURN 服务器是 WebRTC 中用于 NAT 穿透和中继的要害组件。如果这些服务器存在破绽或者未正确配置,攻击者能够通过它们来获取用户的实在 IP 地址,从而进行攻打。 1.5. 防范措施装置WebRTC Leak Shield扩大 ChromeFireFox1.6. 溯源利用<!DOCTYPE html><html> <head> <meta charset="utf-8"> <title>WebRTC泄露检测</title> </head> <body> <script> function findIP(onNewIP) { var myPeerConnection = window.RTCPeerConnection || window.mozRTCPeerConnection || window.webkitRTCPeerConnection; var pc = new myPeerConnection({iceServers: [{urls: "stun:stun.l.google.com:19302"}]}), noop = function() {}, localIPs = {}, ipRegex = /([0-9]{1,3}(\.[0-9]{1,3}){3}|[a-f0-9]{1,4}(:[a-f0-9]{1,4}){7})/g, key; function ipIterate(ip) { if (!localIPs[ip]) onNewIP(ip); localIPs[ip] = true; } pc.createDataChannel(""); pc.createOffer(function(sdp) { sdp.sdp.split('\n').forEach(function(line) { if (line.indexOf('candidate') < 0) return; line.match(ipRegex).forEach(ipIterate); }); pc.setLocalDescription(sdp, noop, noop); }, noop); pc.onicecandidate = function(ice) { if (!ice || !ice.candidate || !ice.candidate.candidate || !ice.candidate.candidate.match(ipRegex)) return; ice.candidate.candidate.match(ipRegex).forEach(ipIterate); }; } function show(ip) { alert(ip); } findIP(show);</script> </body></html>上述的代码拜访后间接弹出IP,可对其进行定向二次开发,达到溯源反制的目标。 ...

May 11, 2023 · 1 min · jiezi

关于webrtc:WebRTC中的NAT穿透

NAT简介咱们晓得,WebRTC会依照内网、P2P、直达的程序来尝试连贯。在大部分的状况下,理论是应用P2P或者直达的。这里P2P的场景次要应用的技术就是NAT穿透。 咱们先简略理解下NAT。NAT在实在网络中是常见的,它的呈现一是为了解决ipv4地址不够用的问题,二是为了网络安全思考的。 首先,让同一个内网中的多台主机共用一个公网ip,能够大大缓解ipv4向ipv6适度期间,ipv4地址不够用的问题。另外,NAT将主机暗藏在内网中,也就使得黑客想拜访起来并没有那么容易了。NAT的标准在RFC 3022中定义,其次要作用就是做网络地址转换。NAT设施(路由器)会在内网地址和外网地址之间建设起映射关系。当内网主机向外网主机发送信息时,NAT会将内网地址替换为映射的外网地址。绝对应的,当外网主机向内网主机产生信息时,NAT会将外网地址替换为映射的内网地址。 因为NAT设施的存在,外网主机通常无奈间接与内网主机通信。所以在建设P2P连贯之前,须要做的就是NAT穿透,也就是俗称的“打洞”。 NAT类型RFC3489和RFC5389是对于NAT穿透的协定,其中RFC3489中把NAT分成了4个类型。它们对NAT穿透的限度呈递进趋势。 齐全锥型齐全锥型NAT的标准是,只有内网主机A通过端口p1收回数据包,在NAT上生成了相应的映射表(这个表就是所谓的“洞”)。接管数据包的外网主机能从这个数据包的报文中失去这个映射关系。它能够将这个映射关系通知其余外网主机,这样任意外网主机发送到这个NAT上端口p1的数据包就都会被转发到内网主机A上。齐全锥型NAT的特点就是只有“打洞”胜利,所有晓得这个“洞”的主机都能通过它和内网主机进行通信。IP限度锥型IP限度锥型NAT的标准相比于齐全锥型NAT,限度了外网来的IP。也就是说,只有从内网主机发送数据包的目标IP,发送到这个NAT上端口p1的数据包才会被转发到内网主机A上。IP限度锥型NAT的特点就是“打洞胜利”后,只有胜利“打洞”的外网主机能力通过这个“洞”和内网主机进行通信。其余外网主机即便晓得这个“洞”,发来的数据包也回被NAT抛弃。端口限度锥型端口限度锥型NAT的标准相比于IP限度锥型NAT,除了限度外网来的IP,还要限度端口。也就是说只有从内网主机发送数据包的目标IP和端口,发送到这个NAT上端口p1的数据包才会被转发到内网主机A上。端口限度锥型NAT的特点就是,除了限度了“洞”的外网ip,还限度了“洞”的外网端口。对称型对称型NAT的标准相比于端口限度锥型NAT,还减少了一条规定。从内网主机A上发到不同的外网主机的数据包通过NAT时,NAT都会为之调配不同的外网端口。对称型NAT的特点就是,内网主机每次发送数据包给不同的外网主机时,都会产生一个新的“洞”。NAT类型检测要进行NAT穿透,内网主机首先要晓得本人连贯的NAT的类型。在RFC3489中给出了规范的检测流程。这个过程须要2台领有2个网卡的STUN服务器。具体流程如下图所示。 主机向1号服务器的某个IP和端口发送一条申请,如果超过超时工夫没有收到响应,则阐明主机与服务器之间UDP不通。如果收到服务端的响应,则比照本地IP和接管到的响应包中的主机的公网IP。如果这两个IP统一,则阐明主机在公网上,没有NAT防护。如果不统一,则须要进一步的NAT类型检测,稍后详述。接下来,主机再次向1号服务器雷同的IP和端口发送一条申请,1号服务器在收到申请后,会应用第二个网卡返回响应。如果主机收到了这个响应,则阐明它在一个凋谢的网络上,是一台公网主机。如果主机没有收到这个响应,则阐明它在对称型防火墙(能够认为与对称型NAT相似)前面。回到下面进一步的NAT类型检测流程。主机也是向1号服务器雷同的IP和端口发送一条申请,1号服务器也会应用第二个网卡返回响应。如果主机收到了这个响应,则阐明它在齐全锥型NAT前面。如果主机没有收到这个响应,则向2号服务器发送一条申请。主机收到2号服务器的响应后,比照1号服务器返回的响应包中的主机的公网IP和2号服务器返回的响应包中的主机的公网IP,如果不统一,则阐明它在一个对称型NAT的前面。如果统一,则须要进一步的检测。主机再次向1号服务器发送一条申请,1号服务器应用雷同的IP(即接管申请的IP)和不同的端口返回响应。如果主机收到了这个响应,则阐明它在IP限制型NAT前面,如果主机没有收到这个响应,则阐明它在端口限制型NAT前面。NAT穿透流程在确认完主机所在网络中的NAT类型后,就能够判断是否能进行NAT穿透,以及确认NAT穿透的办法。 一般而言,齐全锥型NAT以及IP限制型NAT能够与任何其余类型的NAT互通;两边都是端口限制型NAT的也能够互通;一边是端口限制型NAT,另一边是对称型NAT,或者两边都是对称型NAT的状况下想实现穿透很难,所以这种状况个别会通过TRUN协定进行数据直达。 在WebRTC中通信的单方通过ICE替换了下面获取到的一些网络信息,之后就能够尝试NAT穿透,建设P2P连贯了。 假如须要建设P2P通信的单方为主机A和主机B。 如果主机A在齐全锥型NAT或者IP限制型NAT后,只有主机先往主机B发送一个数据,就会在该NAT上留下“洞”,即便发送的数据被对方的NAT抛弃。后续主机B发往主机A的数据也能通过主机A这边的NAT上的“洞”实现穿透了。总的来说,这种状况下,只有单方不停的发送数据包,且没有某一方的数据包被全副抛弃,就能胜利穿透。如果主机A在端口限制型NAT后,而主机B也在端口限制型NAT后,只有单方相互发送数据包则和后面状况一样,能够利用NAT上的“洞”来穿透。主机A在端口限制型NAT后,主机B在对称型NAT后,或者两边都在对称型NAT后,就只能通过服务器直达来通信了。服务器直达的TURN协定在RFC5766中进行了具体的标准。

March 10, 2023 · 1 min · jiezi

关于webrtc:Ubuntu1804编译ZLMediakit支持webrtc

背景最近在做流媒体相干的一些货色, 比拟了一些开源的流媒体服务, 目前 srs 和 ZlmediaKit 我的项目是评估比拟高的, 明天次要在 Ubuntu18.04 上编译 ZlmediaKit, 并反对 webrtc 协定. 筹备源码筹备下载 zlmediakit 源码及其依赖组件源码. git clone --depth 1 https://github.com/ZLMediaKit/ZLMediaKit.git# 下载依赖组件源码git submodule update --init装置或编译依赖查问是否曾经装置 openssl 1.1.1 及以上版本, 个别 ubuntu18.04 应该曾经有了. # 查看 openssl 的版本openssl version -a下载 libsrtp 源码, 用于编译 webrtc 时所依赖. wget 'https://codeload.github.com/cisco/libsrtp/tar.gz/refs/tags/v2.3.0'tar -xvzf libsrtp-2.3.0.tar.gzcd libsrtp-2.3.0./configure --enable-opensslmake -j8sudo make install应用 apt-get 装置其它相干依赖. sudo apt-get install libssl-devsudo apt-get install libsdl-devsudo apt-get install libavcodec-devsudo apt-get install libavutil-devsudo apt-get install ffmpeg编译cd ./ZLMediaKitmkdir buildcd buildcmake .. -DENABLE_WEBRTC=truecmake --build . --target MediaServer编译门路在我的项目 release 目录. ...

February 18, 2023 · 1 min · jiezi

关于webrtc:WebRTC中的ICE

ICE简介ICE是用于UDP媒体传输的NAT穿透协定(适当扩大也能够反对TCP),它须要利用STUN和TURN协定来实现工作。 STUN协定提供了获取一个内网地址对应的公网地址映射关系(NAT Binding)的机制,并且提供了它们之间的保活机制。 TURN协定是STUN协定的一个扩大,容许一个peer只应用一个转发地址就能够和多个peer实现通信。其本质是一个中继协定。 在WebRTC中,ICE会在SDP中减少传输地址信息,利用这个信息进行NAT穿透及确定媒体流传输地址。 ICE CandidateWebRTC中的ICE Candidate是用来形容能够连贯的远端的根本信息,它至多包含(address,port,protocol)三元组,还有Candidate类型、用户名等。 WebRTC将Candidate分成四种类型,且类型间存在优先级秩序,从高到低别离为host、srflx、prflx和relay。 host:从本机网卡上获取到的地址,一般来说,一个网卡对应一个地址。srflx(server reflexive):从STUN服务器获取到的地址。relay:从TRUN服务器获取到的地址。prflx(peer reflexive):在联通测试中从对端数据报文中获取到的地址。其中,srflx和prflx地址可能是一样的,但获取的路径不一样。 ICE的根本流程ICE的根本流程有三步:收集Candidate,替换Candidate,按优先级尝试连贯。 收集CandidateWebRTC在进行NAT穿透时(也就是俗称的打洞),首先会收集Candidate。客户端会按程序先获取本地的host地址,而后从STUN服务器获取srflx地址,再从TRUN服务器获取relay地址。 替换Candidate客户端收集到的这些地址会写到SDP报文中,之后通过信令零碎将它们发送给对端。对端收到这些Candidate后,会与本地的Candidate组成CandidatePair。当然,这种组合也是有规定的,比方传输协定雷同的Candidate能力组成CandidatePair。 须要阐明的是WebRTC中的Candidate替换是应用的trickle形式,也就是边收集边替换。 按优先级尝试连贯WebRTC会将CandidatePair按优先级排序,而后依照这个程序去进行连通性测试。如果有能够连通的CandidatePair就进行尝试,将它作为数据传输地址。后续开始建设连贯,胜利后就能够利用这个通道传输音视频数据了。 总结WebRTC的ICE会抉择出最好的连贯通道来传输音视频数据。WebRTC的连通率简直是100%,因为即便无奈实现P2P的连贯,最终也能通过中继(relay)的形式来实现端到端的连贯。那么WebRTC具体是怎么利用ICE协定来实现P2P的NAT穿透的呢?请关注后续文章。

February 11, 2023 · 1 min · jiezi

关于webrtc:ubuntu1804编译webrtcandroid库

webrtc 是谷歌提供的音视频通信计划, 可能很好的解决音视频互联互通的场景. 本文基于 Ubuntu 18.04 编译 android 版本的过程, 其它平台也能够参考, 根本都大同小异. 编译环境要求磁盘预留空间不小于 30GB.编译过程须要确保你能失常拜访 google 相干服务, 如有条件能够在命令行应用代理拜访. export http_proxy=http://ip:portexport https_proxy=http://ip:portexport all_proxy=http://ip:port因为我的项目太大, 倡议应用固态硬盘的电脑, 放慢同步工夫, 缩小超时等出错几率.以下过程是基于 Ubuntu 18.04 编译.Python3 >= 3.7 版本编译webrtc android装置 depot_tools 工具depot_tools 工具包蕴含了谷歌 gclient, gcl, git-cl, repo 等工具, 用于治理我的项目源码, 散发及编译等. 装置形式如下: # 应用 git clone 到本地git clone https://chromium.googlesource.com/chromium/tools/depot_tools.git在环境变量PATH 中退出门路, 以便方便使用命令. 依据本人应用的 shell 加到不同的启动文件中. ( .bashrc 或 .zshrc) # 指定本人 depot_tools 的具体门路export PATH=/path/to/depot_tools:$PATH同步代码同步代码咱们次要应用的是 gclient 工具, 这是一个 python 脚本文件, 能够对于多模块依赖的我的项目源码进行治理, 能够依据不同零碎同步所有所依赖模块的代码版本. ...

December 14, 2022 · 2 min · jiezi

关于webrtc:WebRTC客户端主要流程分析

通信过程因为WebRTC标准里没有蕴含信令协定,所以像OWT、mediasoup等反对WebRTC的开源我的项目,其通信两端建设连贯的过程中的信令逻辑各不相同。然而,总体上来说,其通信过程必然会包含以下过程。 发动端创立本地的PeerConnection,并且创立Offer。发动端通过信令服务器将Offer发送给应答端。应答端创立本地的PeerConnection,把发动端的Offer设置到PeerConnection中,并且获取到Answer。应答端通过信令服务器将Answer发送给发动端。发动端把应答段的Answer设置到PeerConnection中。两端都收集本地PeerConnection的ICE Candidate,通过信令服务器发送给对方,对方收到ICE Candidate后设置给本地的PeerConnection。两端胜利建设音视频通道,开始收发音视频数据。这个过程如果是在局域网中,能够通过某种形式与对端间接建设好信令通道,则能够不须要信令服务器,间接建设P2P的音视频通道。 这个过程中有些概念能够理解一下。 PeerConnection:WebRTC最后设计师用于浏览器的P2P媒体通信,所以其外围接口类就是PeerConnection,简称PC。Offer、Answer:都属于SDP。SDP是一种形容会话协定,用于形容一次会话的多媒体数据格式等配置信息。通信单方替换SDP就是为了协商一个单方都反对的会话配置。ICE:一种NAT穿透协定,利用STUN、TURN协定实现工作。ICE会在SDP中减少传输地址信息,而后对其进行连通性测试,测试胜利后就能够用于传输媒体数据了。ICE Candidate:即ICE的传输地址信息,包含host、srflx、relayed和prflx。外围流程WebRTC反对的客户端零碎有iOS、Mac、Android、Windows和Linux。各端的代码各不相同,然而,其外围API的调用过程是相似的。所以,只有把握了总体的调用过程就能顺藤摸瓜的去查看各端的具体代码。这里总结下调用的关键步骤: 全局初始化。创立PeerConnectionFactory。通过PeerConnectionFactory接口创立PeerConnection。创立Capturer。通过PeerConnectionFactory接口创立Source、Track。通过PeerConnection接口创立Transceiver。创立Offer、Answer,设置给PeerConnection,并相互交换。相互交换ICE Candidate,通过ICE Candidate回调承受对端ICE Candidate,设置给PeerConnection。P2P连贯的状态能够通过监听PeerConnection的状态回调函数(Windows端是OnIceConnectionChange)。其中,几个重要的WebRTC中的概念能够理解一下: Capturer:视频数据采集,包含相机、屏幕、视频文件等。Source:数据源,数据来自Capturer或其余,而后将数据传给Track。Track:媒体数据交换的载体。Sink:Track数据的消费者,本地预览和渲染远端视频都是Sink。Transceiver:负责收发媒体数据。以视频数据收发为例,发送端的Capturer采集到视频数据,交给Source,再由Source交给本地的Track,而后本地Track中数据分为2路,一路给本地Sink做预览,一路由Transceiver发送给接收端。接收端的Track收到数据后交给接收端的Sink进行渲染。

October 7, 2022 · 1 min · jiezi

关于webrtc:WebRTC源码级深度解析进阶大厂高级音视频开发者含资料

download:WebRTC源码级深度解析,进阶大厂高级音视频开发者应用SpringBoot配置文件的具体阐明1.创立一个SpringBoot我的项目二。配置文件的类型从上一节的图中能够看出,src/main/resources目录中的application.properties文件是创立的默认全局配置文件。 这是一种以。属性后缀。 还有一种以结尾的YAML文件类型。yml suffix-application.yml/application.yaml. YAML是一种比属性格局年老得多的配置格局,属性格局在云原生中应用。三。配置文件#的语法格局3.1利用类型.属性#Properties是java中常见的配置文件类型,其语法格局为key=valve。复制 ` key=value '复制代码应用示例:复制 ` server.port = 80server.ip = 127.0.0.1 app.property.key = pronameapp.property.name = tomapp.list = 1,2,3 还有这个语法?增加启动命令:- spring.profiles.active=devspring . profiles . active = $ { spring . profiles . active } #读取启动命令参数 属性占位符:应用${var}语法来援用已定义属性的值。app.desc =您的姓名是${ app . property . name } `复制代码3.2 application.yml类型#将上述属性格局更改为yml格局:复制 `服务器:端口:80ip: 127.0.0.1 应用程序:属性:关键字:proname姓名:汤姆列表:[1,2,3]desc:你的名字是${app.property.name} 春天:个人资料:active:$ { spring . profiles . active } ` 0复制代码例如,对于一个数组,能够这样写:复制 `人:喜好:篮球跑步吗?-浏览复制代码你也能够这样写:复制 `人:喜好:[篮球、跑步、浏览]复制代码 YAML反对以下数据类型: 对象:键值对的汇合,也称为映射)/散列)/字典。数组:按顺序排列的一组值,也叫序列)/列表。标量:繁多的、不可分割的值。 3.3配置随机值SpringBoot外部提供了一个随机的。*属性,专门用于生成随机值。 属性random.int随机生成正负整数random.int(max)随机生成整数random.int(min[0,max]随机生成整数random.long随机生成正负长整数random.long(max)随机生成[0,长整数random区间的long(min,max)随机生成长整数random。[min,max]区间的UUID随机生成一个uuid字符串(包含'-'字符)。' '示意除上述字符之外的其余字符,用于随机生成32位字符串。配置示例:复制 ` int-val=${random.int}int-range-val=${random.int(2)}uuid-val=${random.uuid} `复制代码四。配置文件的加载程序#当SpringBoot启动时,以下地位的application.properties或application.yml将作为默认配置文件加载。 ...

September 17, 2022 · 1 min · jiezi

关于webrtc:WebRTC实时互动直播技术入门与实战-5G时代必备技能完结无密

download:WebRTC实时互动直播技术入门与实战 5G时代必备技能完结无密如果咱们做时光机回到 Go 1.18 以至一路追溯到 Go 1.4 版本,你会发现 atomic 包诚然提供了很多函数,但只有一个 Type,那就是 atomic.Value。这一节咱们回顾一下 atomic.Value 提供的能力。 A Value provides an atomic load and store of a consistently typed value. The zero value for a Value returns nil from Load. Once Store has been called, a Value must not be copied.A Value must not be copied after first use. 回顾一下咱们的此前的原子操作解读,所谓 atomic.Value 就是一个容器,可能被用来“原子地”存储和加载任意的值,并且是开箱即用的。使用场景atomic.Value 的两个经典使用场景: 周期性更新配置,并提供应多个协程 package main import ( "sync/atomic""time") func loadConfig() map[string]string { return make(map[string]string)} ...

August 18, 2022 · 2 min · jiezi

关于webrtc:百万级高并发WebRTC流媒体服务器设计与开发内附文档源码

百万级高并发WebRTC流媒体服务器设计与开发内附文档源码下载地址:百度网盘Java 诊断工具 Arthas-实操案例实操案例排查函数调用异样通过curl 请求接口只能看到返回异样,然而看不到具体的请求参数和堆栈信息。shell@Alicloud:~$ curl{"timestamp":1655435063042,"status":500,"error":"Internal Server Error","exception":"java.lang.IllegalArgumentException","message":"id < 1","path":"/user/0"}复制代码查看UserController的 参数/异样在Arthas里执行:watch com.example.demo.arthas.user.UserController * '{params, throwExp}'复制代码 第一个参数是类名,反对通配第二个参数是函数名,反对通配 拜访watch命令会打印调用的参数和异样再次通过curl 调用可能在arthas外面查看到具体的异样信息。把获取到的后果开展,可能用-x参数:watch com.example.demo.arthas.user.UserController * '{params, throwExp}' -x 2复制代码返回值表达式在下面的例子里,第三个参数是返回值表达式,它实际上是一个ognl表达式,它反对一些内置对象: loaderclazzmethodtargetparamsreturnObjthrowExpisBeforeisThrowisReturn 比如返回一个数组:watch com.example.demo.arthas.user.UserController * '{params[0], target, returnObj}'复制代码条件表达式watch命令反对在第4个参数里写条件表达式,比如:当拜访 user/1 时,watch命令没有输入当拜访 user/101 时,watch会打印出后果。 当异样时捕捉watch命令反对-e选项,示意只捕捉抛出异样时的请求:watch com.example.demo.arthas.user.UserController * "{params[0],throwExp}" -e复制代码按照耗时进行过滤watch命令反对按请求耗时进行过滤,比如:watch com.example.demo.arthas.user.UserController * '{params, returnObj}' '#cost>200'复制代码热更新代码这个也是真的秀。 拜访 http://localhost:61000/user/0 ,会返回500异样:shell@Alicloud:~$ curl http://localhost:61000/user/0{"timestamp":1655436218020,"status":500,"error":"Internal Server Error","exception":"java.lang.IllegalArgumentException","message":"id < 1","path":"/user/0"}复制代码通过热更新代码,修改这个逻辑。jad反编译UserControllerjad --source-only com.example.demo.arthas.user.UserController > /tmp/UserController.java复制代码jad反编译的后果保存在 /tmp/UserController.java文件里了。再打开一个Terminal 窗口,而后用vim来编辑/tmp/UserController.java:vim /tmp/UserController.java

August 16, 2022 · 1 min · jiezi

关于webrtc:WebRTC目录结构

咱们下载完WebRTC源码后想深入分析其源码的话,首先就须要理解WebRTC的目录构造。因为WebRTC的分层工作做的很好,其代码的目录构造也比拟清晰,在理解这个构造后,就能依据想剖析的性能去对应目录寻找须要的源码了。 WebRTC目录分类WebRTC的源码目录次要能够分为4大类——接口层、业务解决层、音视频解决层和根底反对层。上面咱们先简要意识下各层所蕴含的目录和次要性能。 接口层。蕴含api目录。WebRTC对外的所有接口都在该目录下,所以如果要新增接口,也应该放在这里。业务解决层。蕴含pc、call、media目录。pc目录中包含PeerConnection座的媒体协商、收集Candidate、音视频数据传输等逻辑解决。call目录次要是“呼叫”相干的逻辑。media目录中包含媒体引擎相干逻辑解决。音视频解决层。蕴含common_audio、common_video、audio、video目录。common_audio、common_video目录中别离是音频和视频算法相干代码。audio、video目录别离是音频和视频流相干代码。根底反对层。其余目录都属于这层。次要都是一些根底模块代码以及编译工具等。另外还有一个很重要的目录就是modules,这个目录中内容将在后文介绍。 WebRTC目录构造上面这个表格就是WebRTC中蕴含的所有目录及其性能介绍。 ps:以下目录构造次要是基于Windows平台下的WebRTC的m84版本,其余平台下的其余版本会略有差异,总体大同小异。 目录性能api接口层,提供对外接口。audio音频流相干。baseChromium根底代码,包含线程,零碎信息等。build编译脚本和BUILD.gn等文件,不同平台下会有不同。build_overrides提供一些可配置化的参数,能够定制化编译。buildtoolsgn等编译工具,不同平台下载不同的gn。call数据流管理层,每一个call都代表同一个端的所有数据的流入流出。common_audio音频算法相干,包含环形队列、FIR滤波器等。common_video视频算法相干,包含libyuv、sps/pps分析器等。data测试数据。docs文档,包含faq等。examples示例代码,各种demo。logging日志。media媒体引擎层,包含音频、视频引擎等,次要用于音视频的管制。modulesWebRTC子模块,包含音视频采集、解决、编解码等。p2pNAT穿透实现,turn、stun等。pcPeer Connection连贯相干的业务逻辑。resources测试数据和资源。rtc_baseWebRTC根底代码,包含线程、锁、网络等。rtc_tools网络监测、音视频剖析等脚本sdk挪动端音视频采集、渲染等代码,蕴含Android和iOSstats数据统计相干。style-guide编码标准system_wrappers零碎相干封装,包含cpu个性、读写锁、时钟等test单元测试testinggmock、gtest等测试工具代码third_party第三方依赖库,不同平台下依赖库会有不同。toolsChromium工具汇合tools_webrtcWebRTC工具汇合video视频流相干。modules目录modules目录是WebRTC源码中最重要的一个目录。该目录中寄存的都是一些性能比拟独立的模块。包含音视频的采集,解决,编解码器,混音、回声打消、降噪等性能的实现。 上面这个表格就是modules目录蕴含的子目录及其性能介绍。 子目录性能audio_coding音频编解码audio_device与设施无关的音频采集、播放等audio_mixer混音audio_processing音频前后解决congestion_controller拥塞管制,Transport-CC等desktop_capture桌面采集includemodule头文件pacing码率探测和平滑解决remote_bitrate_estimator远端带宽评估rtp_rtcprtp/rtcp协定third_party第三方依赖,fft、g711等utility线程相干工具video_capture视频采集video_coding视频编解码video_processing视频前后解决须要留神的是remote_bitrate_estimator中的Goog-REMB算法是接收端的拥塞控制算法,曾经被淘汰了,只是为了兼容老版本还保留着。新的拥塞控制算法Transport-CC(GCC)是在发送端评估的,其体现要比接收端的评估算法更优良。

July 31, 2022 · 1 min · jiezi

关于webrtc:5G时代必备-音视频WebRTC实时互动直播技术入门与实战

5G时代必备 音视频WebRTC实时互动直播技术入门与实战百度网盘链接 Java 基础常见学识点&面试题总结面向对象基础面向对象和面向过程的区别两者的次要区别在于解决问题的形式不同: 面向过程把解决问题的过程拆成一个个方法,通过一个个方法的执行解决问题。面向对象会先抽象出对象,而后用对象执行方法的形式解决问题。 另外,面向对象开发的程序一般更易保护、易复用、易扩大。相干 issue : 面向过程 :面向过程性能比面向对象高??成员变量与局部变量的区别 语法形式 :从语法形式上看,成员变量是属于类的,而局部变量是在代码块或方法中定义的变量或是方法的参数;成员变量可能被 public,private,static 等修饰符所润饰,而局部变量不能被访问控制修饰符及 static 所润饰;然而,成员变量和局部变量都能被 final 所润饰。存储形式 :从变量在内存中的存储形式来看,如果成员变量是使用 static 润饰的,那么这个成员变量是属于类的,如果没有使用 static 润饰,这个成员变量是属于实例的。而对象存在于堆内存,局部变量则存在于栈内存。生存工夫 :从变量在内存中的生存工夫上看,成员变量是对象的一部分,它随着对象的创建而存在,而局部变量随着方法的调用而主动生成,随着方法的调用结束而沦亡。默认值 :从变量是否有默认值来看,成员变量如果没有被赋初始值,则会主动以类型的默认值而赋值(一种情况例外:被 final 润饰的成员变量也必须显式地赋值),而局部变量则不会主动赋值。 创建一个对象用什么运算符?对象实体与对象引用有何不同?new 运算符,new 创建对象实例(对象实例在堆内存中),对象引用指向对象实例(对象引用存放在栈内存中)。一个对象引用可能指向 0 个或 1 个对象(一根绳子可能不系气球,也可能系一个气球);一个对象可能有 n 个引用指向它(可能用 n 条绳子系住一个气球)。对象的相等和引用相等的区别 对象的相等一般比较的是内存中存放的内容是否相等。引用相等一般比较的是他们指向的内存地址是否相等。 类的构造方法的作用是什么?构造方法是一种非凡的方法,次要作用是实现对象的初始化工作。如果一个类没有申明构造方法,该程序能正确执行吗?如果一个类没有申明构造方法,也可能执行!因为一个类即使没有申明构造方法也会有默认的不带参数的构造方法。如果咱们自己增加了类的构造方法(无论是否有参),Java 就不会再增加默认的无参数的构造方法了,咱们一直在人不知;鬼不觉地使用构造方法,这也是为什么咱们在创建对象的时候前面要加一个括号(因为要调用无参的构造方法)。如果咱们重载了有参的构造方法,记得都要把无参的构造方法也写进去(无论是否用到),因为这可能帮助咱们在创建对象的时候少踩坑。构造方法有哪些个性?是否可被 override?构造方法个性如下: 名字与类名雷同。没有返回值,但不能用 void 申明结构函数。生成类的对象时主动执行,无需调用。 构造方法不能被 override(重写),然而可能 overload(重载),所以你可能看到一个类中有多个结构函数的情况。面向对象三大特色封装封装是指把一个对象的状态信息(也就是属性)躲藏在对象外部,不容许内部对象间接拜访对象的外部信息。然而可能提供一些可能被外界拜访的方法来操作属性。就好像咱们看不到挂在墙上的空调的外部的整机信息(也就是属性),然而可能通过遥控器(方法)来管制空调。如果属性不想被外界拜访,咱们大可不必提供方法给外界拜访。然而如果一个类没有提供应外界拜访的方法,那么这个类也没有什么意义了。就好像如果没有空调遥控器,那么咱们就无奈操控空凋制冷,空调本身就没有意义了(当然现在还有很多其余方法 ,这里只是为了举例子)。public class Student { private int id;//id属性私有化private String name;//name属性私有化//获取id的方法public int getId() { return id;}//设置id的方法public void setId(int id) { this.id = id;}//获取name的方法public String getName() { return name;}//设置name的方法public void setName(String name) { this.name = name;}}复制代码继承不同类型的对象,相互之间常常有肯定数量的共同点。例如,小明同学、小红同学、小李同学,都共享学生的个性(班级、学号等)。同时,每一个对象还定义了额定的个性使得他们不同凡响。例如小明的数学比较好,小红的性情惹人喜爱;小李的力量比较大。继承是使用已存在的类的定义作为基础建立新类的技术,新类的定义可能减少新的数据或新的功能,也可能用父类的功能,但不能选择性地继承父类。通过使用继承,可能疾速地创建新的类,可能提高代码的重用,程序的可维护性,俭约大量创建新类的工夫 ,提高咱们的开发效率。对于继承如下 3 点请记住: ...

June 15, 2022 · 2 min · jiezi

关于webrtc:WebGL-及其在-WebRTC-中的应用

摘要:理解 WebGL 的根底概念并进行实际,更好的了解不同框架带来的便捷及劣势。 文|Web SDK 开发团队 前言1、什么是 WebGL ? WebGL 的全称是 Web Graphics Library,是一种 3D 绘图协定。 WebGL 容许把 JavaScript 和 OpenGL ES 2.0 联合在一起,通过减少 OpenGL ES 2.0 的一个 JavaScript 绑定,WebGL 能够为 HTML5 Canvas 提供硬件 3D 减速渲染。Web 开发人员就能够借助零碎显卡来在浏览器里更流畅地展现 3D 场景和模型,还能创立简单的导航和数据视觉化。 2、OpenGL 与 GLSL 在理解 WebGL 之前,咱们需理解下什么是 OpenGL 与 GLSL。 OpenGL(英语:Open Graphics Library,译名为凋谢图形库或者 “开放式图形库”)是用于渲染 2D、3D 矢量图形的跨语言、跨平台的应用程序编程接口(API), GLSL 则是用来在 OpenGL 中着色编程的语言。 从上文中能够看到 WebGL 实际上是 JavaScript 操作一些 OpenGL 接口,也就意味着,可能会编写一部分 GLSL ES 2.0 的代码,没错你猜对了,WebGL 只是绑定了一层,外部的一些核心内容,例如着色器、材质、灯光等都是须要借助 GLSL ES 语法来操作的。 ...

June 8, 2022 · 3 min · jiezi

关于webrtc:开源不易安全慎行中国软件如何走向文明丨RTE-技术环境月报-202205

各位开发者小伙伴: 这里是 2022 年第 5 期的 RTE《技术环境月报》——致力于成为对大家“有用”的 Highlight 看板——每月初通过 RTC 开发者社区(https://rtcdeveloper.agora.io/)和声网微信服务号(AgoraIO)公布, 恳请大伙儿多转发、多反馈。因为文中内容蕴含较多信源超链接、倡议大家返回 RTC 开发者社区或应用咱们的邮件订阅服务,喜爱用邮件的小伙伴请点击浏览原文进行订阅。 对于任何反馈(包含但不限于内容上、模式上)咱们不胜感激、并有小惊喜回馈,例如你心愿从“技术环境月报”中看到哪些内容;本人举荐的信源、话题、会议等;或者列举几个你喜爱看、平时常看的内容渠道;内容排版或出现模式上有哪些能够改良的中央等。咱们欢送更多的小伙伴参加“月刊”内容的共创,感兴趣的敌人请通过开发者论坛或微信服务号分割,记得报暗号“共创”。 感激 Tina 对本期内容的奉献。 月刊中的点评仅代表集体,如有不同观点,欢送大家各种留言跟帖探讨。心愿尔后的日子里,《技术环境月报》能与各位如期相见、偶然启发。以下为月报注释: 00 本月好文举荐: 《中国软件,从凋敝走向文化**》这篇文章点出了中国软件行业的一些现状:比方中国企业管理者对软件价值链的无知和短视、过于后果导向;中国软件开发者的工程能力降落,即便是基于二次开发也难保开发效率和品质,不足工匠精力。同时,本文还有一个独到之处,就是提出企业和集体也须要关注“个体责任”和“家庭责任”。中国的传统教育通常是要求“超过他人家的孩子“,要比他人过得好,反而都极其漠视集体和家庭感触,最终是“为他人眼中的本人而活”。 这篇对中国软件的评估,跟前段时间的《是什么造成了中国软件产业的喜剧》有殊途同归之感,都从企业和开发者角度指出了一些问题,如中国软件行业不足外围竞争力,销售导向,“魔改”开源软件等等。作者认为中国“没有真正意义上的软件巨头型企业,大量根底软件被外国垄断”。尽管现状不是久而久之能扭转的,然而庆幸有人能开始指出问题所在。 [](https://en.wikipedia.org/wiki...) 站在“脱钩”的大背景下,咱们应该有筚路蓝缕的眼光和气魄,从根底软件的问题和现状中发现时机,施展本身的劣势、在下一个浪潮中实现自我的价值。 01 【音视频】从编解码器到架构再到场景,翻新无处不在 在过来的一年里,H.264、VP9、HEVC、AV1、VVC、LCEVC 和 EVC 等视频编解码器的一些重要变动及其现状的汇总和介绍。FFmpeg 近日合并了对 JPEG-XL 图像格式的反对。 JPEG-XL 是一个免版税的位图文件格局,反对有损和无损压缩──应用了 rANS(range Asymmetric Numeral System) 技术。但微软最近取得的 rANS 数据压缩相干专利引发了人们的担心。WebRTC 架构格局正在发生变化,在基于 WebRTC 的利用开发中,架构抉择须要衡量多种因素如须要的性能、领有的估算、开发人员技术水平等;大多数状况下, CPaaS 或开源媒体服务器选项依然是最好的选项。但在多数状况下抉择自建零碎或者应用 Unbundled WebRTC 也是一个不错的抉择。谷歌发表将在 GSuite 中集成 Google Meet 性能,不晓得搜寻伟人是受了微软的启发还是忽然顿悟了。国内方面,金山办公和飞书也都集成了相干性能。播客录制平台 Riverside 最近取得了 3500 万美元的 B 轮融资,该轮融资由 Oren Zeev 领投,目前该平台的总资金达到 4700 万美元。Riverside 目前有大概 90 名员工,现有客户包含纽约时报、福克斯体育、漫威、iHeartMedia 和微软。俄罗斯用 Youtube 代替 Rutube,其实俄罗斯多年前就已推出 YouTube 和 Facebook 的外国代替平台 RuTube 和 VKontakte ,去年又推出俄版 Instagram 平台 Fiesta。其中 VKontakte 曾经胜利攀升至俄月度用户第二多的社交平台,3月用户月活超过1亿。02 【大前端】RTC 和元宇宙,你更看好哪个?在通过一段时间的预热之后,Epic Games 正式公布了“空幻引擎5”,新引擎的技术包含“全动静全局光照解决方案”Lumen、“虚拟化多边形几何体零碎”Nanite,同时在性能和 UI 层面进行了大量降级,可实现更加真切的视觉效果。Moor Insights & Strategy 首席分析师 Anshel Sag 示意:“我认为空幻引擎5是向元宇宙和 AR/VR 迈进的一大步。”抉择 Rust进行 WebRTC 跨平台开发的起因:要在所有平台上提供统一的外围业务逻辑,对每个平台提供近乎原生的 API,同时最大限度地缩小跨平台之间的差别。《常识图谱可视化技术在美团的实际与摸索》以美团大脑为例,介绍了常识图谱可视化技术在美团多个业务场景中的利用,成果十分酷炫。近期 Video.js(一个专门为 HTML5 构建的网络视频播放器)我的项目发表减少了对 WebRTC 的反对。Video.js 我的项目始于 2010 年中期,目前曾经诞生了数百个皮肤和插件。03 【网络】eBPF 和网络减速安全监控是企业上云非常重视的一环、并越来越受到云服务商和企业的关注,Kindling 是一款基于 eBPF 技术的云原生可观测性我的项目,这两篇博客介绍了 Kindling 的探针架构和 HTTP 协定解析的原理。咱们看到,越来越多的企业开始在基础设施中采纳 eBPF 技术来代替 iptables 等,但 eBPF 在解决很多技术难题的同时,也被更多非法的组织和机构歹意利用,美团技术团队本月也分享了一篇《Linux 中基于 eBPF 的歹意利用与检测机制》。出名 SSL 证书破绽查看服务 SSLPing 因长期积攒的技术债、运维艰难及零碎环境的问题、以及入不敷出的困境导致无奈维持经营,最终被迫发表敞开。谷歌近期推出了 Media CDN 服务──构建在谷歌现有的 Cloud CDN (用于 Web 和 API 减速)产品之上,并整合了沉迷式媒体体验的能力。除此之外,Media CDN 反对 QUIC (HTTP/3)、TLS 1.3 和 BBR 的开箱即用、针对 Last-mile 进行了优化。04 【开发】编程语言的进化本月许式伟写了2篇文章总结了 Go+ 的设计理念和公布两年来踩过的坑:《Go、Go+ 与 Rust 主动类型推导的比照》《那些咱们踩过的坑》。十分值得一读。在谷歌这样的代码规模下,如何优化 C++ 编译器中的std::sort ?这项工作曾经进行了一年多,尽管底层排序算法曾经倒退得很成熟,然而继续的优化也是十分必要的,能够很好的改善效率,文章中有一个例子能阐明:与 libcxx 排序相比,libstdcxx 做了很多“非必要”的工作,但这些优化工作在实践中很重要,让运行速度快了 4.5 倍。新开发语言。最近Hare语言在国内外激发不少探讨,这个新开发的语言由软件工程师 Drew DeVault 和其余约30位我的项目贡献者共同完成,目标是“摸索 C 语言能不能做得更好”。C 语言倒退到当初,在操作系统、编译器等畛域失去了广泛应用,故 Hare 取代 C 的可能性简直是零,因而作者在介绍 Hare 时也应用了一个十分有意思的词:“to play with(玩)”。正当利用软件开发中的二八准则,可无效升高开发成本:软件中 80% 的谬误来自 20% 的性能;给定应用程序中 80% 的复杂性来自 20% 的代码库;对于 80% 的用户来说,应用程序中只有 20% 的给定功能集是重要的;80% 的用户可能不关怀应用程序中 80% 的性能(他们只关怀 20%);工程团队将 80% 的工夫花在 20% 的应用程序上......因而能够采取一些针对性伎俩,比方在沟通上,如果让客户来决定额定老本是否值得,能够用更少的钱来更快地开发软件;在治理上,让客户帮忙工程师理解“80%”性能,那么工程师将成为软件开发过程中价值和老本的更好管家;另外,优良的经理也须要理解工程师会在何时陷入“自我陷阱”,防止工程师“适度爱上本人的代码”,从而导致额定的老本和时间延迟。索尼为 exFAT 的 Linux 驱动提供了 73% 以上的性能改良。另有开箱测试表明 Valve 新发售的 Steam Deck 在存储速度的体现上也令人惊艳。05 【平安、开源&其余】开源不易、平安慎行因无心中把一个 Repo 设为公有,出名开源我的项目 HTTPie 十余年来积攒的 54万 Star 一夜归零。问题出在 GitHub 推出的“个人主页”性能上,激活此性能须要新建一个与本人 ID 同名的仓库,这个新仓库的 README.md 的内容便会显示在集体首页,但要想自定义 GitHub 组织的主页,须要新建的仓库名称是 name/.github,而不是 name/name。HTTPie 在官网博客中示意 GitHub 给出的揭示也存在肯定的误导或者说混同,从而酿成了这个喜剧;并且当他们向 GitHub 官网提出复原申请时受到了回绝。Fedora 我的项目领导人 Matthew Miller 承受采访议论了 Linux 的风行和开源的重要性。他认为 Linux 和自在开源软件静止并不是天经地义的,其中最值得警觉的一件事是 Chrome 操作系统的风行,Chrome 的上游我的项目 Chromium 是开源的,但它自身并不是作为一个开源社区我的项目运行的。他心愿真正的开源我的项目如 Firefox 能重获新生。国内出名平安专家余弦(@evilcos)及其慢雾团队公布的《区块链光明森林自救手册》堪称史上最硬核全面的 Crypto 平安手册。Check Point 的平安研究员发现了一个容许攻击者管制数百万 Android 设施的高危破绽,该破绽存在于 ALAC(Apple Lossless Audio Codec)编解码器中,利用该破绽可强制解码器执行恶意代码。ALAC 是苹果在 2004 年推出的音频格式,苹果多年来始终保护本人的公有版本,而高通和联发科则应用了一个自 2011 年以来就没再更新过的开源版本。高通和联发科去年就释出了补丁,如果您手中安卓设施的最新补丁是在 2021 年 12 月之后,则该破绽已修复。美最高法院判处抓取领英数据非法。这个官司的意义能够媲美“甲骨文诉谷歌 Java 侵权案”。在大数据时代,一些互联网平台积攒了大量用户数据,并以此建设本身资源优势:在和其余互联网企业与平台的竞争中,用户数据越多利用得越好,就越容易吸引更多用户,从而处于更无利的位置。这种滚雪球式的效应使得互联网企业往往将用户公共数据视为本人的外围资产,禁止外界爬取。在本案中,法官断定爬取领英公共数据不属于“未经受权拜访受保护计算机”行为,并且还禁止领英用技术手段烦扰数据爬取工作。一旦“未经受权”概念不适用于公共网站,那么包含 Ticketmaster、Amazon 等在线零售商,乃至 Twitter 等社交网络平台——都将裸露在批量部署的侵入性爬虫程序的背后。(另外须要留神的是中美法律不同,爬取中文网站法律危险更大。)Kubernetes 1.24 版本公布,该版本有一个重要变动,就是为了进步供应链平安,K8s 将在生产中采纳 Sigstore 来签订工件和验证签名,可能为二进制文件、源代码包和容器镜像等主动进行数字签名和查看软件工件,使软件具备更平安的监管链,能够追溯到源头。06 近期值得关注的会议会议名称会议工夫会议地址主办方【收费】2022年中国云计算和大数据技术与利用大会2022年5月12日北京新世纪日航饭店中国电子学会【免费】第二届中国数据中心建设与运维峰会2022年6月7-8日线上会议ICT-Event【收费】2022云原生产业大会2022年6月15日北京国宾酒店中国信通院【收费】2022软件与零碎稳定性大会2022年6月16日北京国宾酒店中国信通院【免费】QCon 2022 北京站2022年6月22-24日北京国际会议中心InfoQ【免费】LVS 2022 上海站2022年6月24-25日上海海神诺富特大酒店LVS社区07【开源我的项目举荐】TiFlash开源了 - 这是 TiDB 中提供 HTAP 能力的重要组成部分,偏重于事务性数据的剖析。Framework 笔记本电脑主板我的项目 - 是一个可 DIY 的笔记本电脑我的项目。Lexical - 是 Facebook 开源的一个可扩大文本编辑器库。Textualize – 针对终端(命令行窗口)的面向 Web 的 TUI(Text User Interface)开源框架。BinAbsInspector - 是腾讯科恩实验室最近开源的二进制文件自动化动态破绽检测工具。目前国内上较为胜利的商业化剖析工具有 Coverity、 CodeSonar、 VeraCode等,在开源社区中也涌现出一批出名的二进制剖析工具如 angr、BAP、cwe_、checker等。

May 10, 2022 · 2 min · jiezi

关于webrtc:资讯|WebRTC-M99-更新

WebRTC M99 目前在 Chrome 的稳定版中可用,蕴含 3个新个性以及超过27个谬误修复、性能加强和稳定性/性能方面的改良。欢送关注网易云信公众号,咱们将定期翻译 WebRTC 相干内容,帮忙开发者取得最新资讯,走在行业前沿。 性能及问题修复可登陆:Monorail - webrtc - Web-based real-time communication - Monorail 输出问题 ID 即可查问 Bug 详情。 No.1 类型:Bug 问题 ID:1122844 形容:启用 bugprone-use-after-move clang-tidy 查看 组件:Internals>Core No.2 类型:Feature 问题 ID:1251096 形容:YUV444 反对 H.264 WebRTC 流 组件:Blink>WebRTC>Video,Internals>Media No.3 类型:Bug 问题 ID:11121 形容:将默认 SdpSemantics 更改为 kUnifiedPlan 并制订打算 B [已弃用] 组件:PeerConnection No.4 类型:Bug 问题 ID:12222 形容:默认启用音频的发送端带宽预计 组件:Audio,BWE No.5 类型:Bug 问题 ID:12269 形容:探索重构 InterArrivalDelta 的 AB-Test后果 组件:BWE No.6 类型:Bug ...

April 27, 2022 · 2 min · jiezi

关于webrtc:WebRTC-中如何自定义-RTCP-信息并使用

简介 笔者目前在做一个基于 WebRTC 的 Android 端 P2P 视频流传输我的项目,现有需要:Sender(视频发送方)在向 Receiver(视频接管方)传输肯定数量的帧之后,进行向 Receiver 传输视频数据。因为 Sender 无奈预知接管方何时能力接管完这些帧,进而无奈预知本人何时能力进行传输视频数据,因而须要 Receiver 在接管完这些帧之后向 Sender 反馈,告诉 Sender 进行发送视频数据。 WebRTC 应用 RTP 和 RTCP 协定进行媒体通信。简略地说,RTP(实时传输协定 / Real-time Transport Protocol)用于传输音视频数据,RTCP(RTP 控制协议 / RTP Control Protocol)用于传输通信过程中的元数据(如丢包率、关键帧申请)。前述 Receiver 向 Sender 反馈能够应用 RTCP 实现,具体能够参考申请关键帧的过程。 准备常识RTCP RFC 3550 中对于 RTCP 的定义为:RTCP 应用与传输数据分组(packet)雷同的散发(distribution)机制,对会话中的所有参与者进行周期性的管制分组传输。该文件同时定义了几种 RTCP 分组类型,包含 SR、RR、SDES、BYE 和 APP。RFC 4585 扩大了 RTCP 协定,容许接管方向发送方提供更立刻的反馈,进而能够实现短时间内自适应的、基于反馈的高效的修复机制。该文件定义了一种新的 RTCP 分组类型,即反馈(FB)信息,对 FB 信息进一步分类并定义了几种 FB 信息,包含通用 NACK、PLI、SLI、RPSI 等。 RTCP 分组不能独自应用,必须要将多个 RTCP 分组连结造成一个复合(compound)RTCP 分组,之后再通过低层协定(如 UDP)发送进来。复合 RTCP 分组内的各个 RTCP 分组之间不须要分隔符,这是因为对于 RTCP 分组的对齐要求以及每个分组的长度域曾经足够保障所有分组都能够被正确地宰割。上图展现了一个 RTCP 复合分组的例子,其中蕴含加密前缀、SR 分组、SDES 分组以及一个 BYE 分组。RFC 3550 规定一个 RTCP 复合分组中必须至多蕴含一个 SR/RR 分组和一个 SDES 分组。 ...

April 14, 2022 · 7 min · jiezi

关于webrtc:互联网通信安全之-WebRTC-传输安全机制

全社会数字化转型减速叠加实时通信技术的蓬勃发展,实时通信曾经曾经渗透到各行各业,成为了人们现代化生存中不可或缺的重要交换伎俩。关注【融云寰球互联网通信云】理解更多 其中,WebRTC 的呈现更是使实时通信技术得以广泛应用,它提供了一套简直所有支流浏览器都反对的规范 API,让浏览器之间无插件化的音视频互通成为可能,大大降低了音视频开发的门槛。视频会议、视频招聘、近程医疗等等须要实时互动的场景中,都能够看到 WebRTC 的身影。 在 WebRTC 中,为了保障媒体传输的安全性,引入了 DTLS 和 SRTP 来对通信过程进行加密。DTLS 的作用、原理与 SSL/TLS 相似,都是为了使通信过程变得更平安。 本文作为互联网通信安全系列文的第二篇,次要分享 WebRTC 传输平安机制:DTLS 和 SRTP。 罕用加密办法加密技术对称加密对称加密(Symmetric Cryptography),又称私钥加密,是最疾速、最简略的一种加密形式,加密(encryption)与解密(decryption)用的是同样的密钥(secret key)。 对称加密有很多种算法,因为它效率很高,所以被宽泛应用在很多加密协议中。对称加密通常应用的是绝对较小的密钥,个别小于 256 bit。密钥越大,加密越强,但加密与解密的过程也就越慢。密钥的大小既要关照到安全性,也要关照到效率。 非对称加密非对称加密(Asymmetric Cryptography),又称公钥加密。它应用了一对密钥,公钥(public key)和私钥(private key),为数据的加密与解密提供了一个十分平安的办法。 私钥只能由一方平安保存,不能外泄,而公钥则能够发给任何申请它的人。非对称加密应用这对密钥中的一个进行加密,而解密则须要另一个密钥。比方,你向银行申请公钥,银行将公钥发给你,你应用公钥对音讯加密,那么只有私钥的持有人——银行能力对你的音讯解密。与对称加密不同的是,银行不须要通过网络发送私钥,安全性大大提高。 对称加密和非对称加密的区别,总结如下: (1)对称加密的加密与解密应用的是同样的密钥,所以速度快,但因为须要将密钥在网络传输,所以安全性不高。 (2)非对称加密应用了一对密钥,公钥与私钥,所以安全性高,但加密与解密速度慢。 (3)解决方案是将对称加密的密钥应用非对称加密的公钥进行加密,而后发送进来,接管方应用私钥进行解密失去对称加密的密钥,而后单方能够应用对称加密来进行沟通。 数字签名数字签名是附加在报文上的非凡加密校验码,即所谓的校验和,利用了非对称加密密钥加密技术。 数字签名的次要作用是避免报文被篡改,一旦报文被攻击者篡改,通过将其与校验和进行匹配,能够立即被接收者发现。数字签名的过程如下图所示: (数字签名的过程) 发送者 A 将报文摘要(报文通过 SHA-1 等哈希算法生成摘要)通过公有密钥加密生成签名,与明文报文一起发给接收者 B,接收者 B 通过对收到的信息进行计算后失去两份报文摘要,比拟这两份报文摘要是否相等能够验证报文是否被篡改,即: (1)明文报文通过应用与发送端雷同的哈希算法生成摘要 1; (2)签名通过公开密钥解密后生成摘要 2。(数字签名的过程) 数字签名数字证书是由一些公认可信的证书颁发机构签发的,不易伪造。包含如下内容: 证书序列号证书签名算法证书颁发者有效期公开密钥证书签发机构的数字签名数字证书能够用于接收者验证对端的身份。接收者(例如浏览器)收到某个对端(例如 Web 服务器)的证书时,会对签名颁发机构的数字签名进行查看,一般来说,接收者当时就会事后装置很多罕用的签名颁发机构的证书(含有公开密钥),利用事后的公开密钥能够对签名进行验证。 DTLS 协定DTLS(Datagram Transport Level Security,数据报平安协定),基于 UDP 场景下数据包可能失落或从新排序的现实情况,为 UDP 定制和改良的 TLS 协定。DTLS 提供了 UDP 传输场景下的平安解决方案,能避免音讯被窃听、篡改、身份假冒等问题。在 WebRTC 中应用 DTLS 的中央包含两局部:协商和治理 [SRTP]() 密钥和为 [DataChannel]() 提供加密通道。 ...

April 13, 2022 · 3 min · jiezi

关于webrtc:一文详解-WebRTC-基础

前言刚开始接触 WebRTC 的时候,容易被一些生僻的概念绕得团团转,在经验一段时间的查阅文章和实际后,本文就具体梳理下无关 WebRTC 入门的基础知识。 本文同步发在我的Github RTCRTC(Real-time Communications)实时通信,是实时音视频的一个简称。 WebRTC 是什么WebRTC (Web Real-Time Communications) 是 RTC 的一部分,是一项实时通信技术,它容许网络应用或者站点,在不借助两头媒介的状况下,建设浏览器之间点对点(Peer-to-Peer)的连贯,实现视频流/音频流或者其余任意数据的传输。 WebRTC 的优缺点长处跨平台(Web、Windows、MacOS、Linux、iOS、Android)收费、免插件、免装置,失去支流浏览器反对弱小的打洞能力,蕴含 STUN、ICE、TURN 的要害 NAT 和防火墙穿透技术毛病不足服务器计划的设计和部署音频的设施适配问题利用场景音视频通话视频/电话会议近程拜访主机在线教育(直播连麦,屏幕录制,共享远程桌面)采集音视频数据该办法会提醒用户给予应用媒体输出的许可,容许后会拜访到电脑摄像头和麦克风,并拿到一个 MediaStream 对象,把该媒体流赋值给页面的 video 标签,就能看到和听到本人的音视频了,由此也拿到音视频流。 async function createLocalMediaStream() { // (非https/localhost)下 navigator.mediaDevices 会返回 undefined const localStream = await navigator.mediaDevices.getUserMedia({ video: true, audio: true, }) document.getElementById('local').srcObject = localStream}可查阅:MediaDevices.getUserMedia() RTCPeerConnection咱们把发动 WebRTC 通信的两端被称为对等端,即是 Peer。所谓点对点通信(peer-to-peer)则是说两个客户端直连,发送数据不须要两头服务器,建设胜利的连贯则称为PeerConnection,而一次 WebRTC 通信可蕴含多个 PeerConnection。 RTCPeerConnection 则是创立点对点连贯的 API,代表一个由本地计算机到远端的 WebRTC 连贯。该接口提供了创立,放弃,监控,敞开连贯的办法的实现。 创立两个连贯实例 const peerA = new RTCPeerConnection()const peerB = new RTCPeerConnection()APIpc.createOffer:创立 offer 办法,办法会返回 SDP Offer 信息pc.setLocalDescription 设置本地 SDP 形容信息pc.setRemoteDescription:设置远端的 SDP 形容信息,即对方发过来的 SDP 信息pc.createAnswer:远端创立应答 Answer 办法,办法会返回 SDP Offer 信息pc.ontrack:设置完远端 SDP 形容信息后会触发该办法,接管对方的媒体流pc.onicecandidate:设置完本地 SDP 形容信息后会触发该办法,关上一个连贯,开始运转媒体流pc.addIceCandidate:连贯增加对方的网络信息pc.setLocalDescription:将 localDescription 设置为 offer,localDescription 即为咱们须要发送给应答方的 sdp,此形容指定连贯本地端的属性,包含媒体格式pc.setRemoteDescription:扭转与连贯相干的形容,该形容次要是形容有些对于连贯的属性,例如对端应用的解码器WebRTC 音视频通信根本流程一方发动调用 getUserMedia 关上本地摄像头媒体协商(信令替换)建设通信媒体协商媒体协商次要指 SDP 替换。 ...

March 27, 2022 · 3 min · jiezi

关于webrtc:使用基于-WebRTC-的-JavaScript-API-在浏览器环境里调用本机摄像头

HTML5,JavaScript 和古代浏览器这套三驾马车的组合,使得传统的 Web 利用较之过来能实现更多更丰盛的同用户交互的性能。摄像头现在已成为智能手机的标配,前端 Web 利用也呈现了越来越多的关上本机摄像头,扫描条形码,二维码等需要。 本文介绍两种通过 JavaScript 实现在浏览器环境里调用设施摄像头的开发技术。 办法1:基于古代浏览器反对的 WebRTC API 实现我采纳该思路实现了一个简略的 Web 页面,全副源代码保护在如下的 Github 代码仓库里: https://github.com/wangzixi-d... 首先看看运行该 Web 利用的成果。 通过笔记本电脑拜访,浏览器会弹出窗口询问用户是否容许该利用拜访设施上的摄像头: 点击容许之后,利用下方区域就会实时显示我的摄像头正对着的区域的图像: 点击“拍照”按钮后,摄像头显示的图像就会被固化在该按钮下方,并且以图片的形式主动保留到本地。 在我的三星手机上拜访该链接,首先一样要受权该利用应用摄像头: 对准我电脑背后一个异形手办进行拍照: 主动生成一张图片并保留到手机上: 几个要害的实现点阐明: (1) JavaScript 之所以通过浏览器可能辨认到设施可用摄像头(包含可用的音频输出和输出设备),是因为古代浏览器反对的一组名为 WebRTC(Web Real Time Communication,网页即时通信)的 API. 这个 API 能帮忙 Web 利用开发人员通过简略的 JavaScript 编程就能实现功能丰富的实时多媒体利用,而无需学习多媒体的数字信号处理常识。Web 利用的使用者也无需下载额定的插件。 用 JavaScript 进行设施可用多媒体设施的检测,外围代码如下: navigator.mediaDevices.enumerateDevices().then(gotDevices).catch(handleError);这句代码前半段 navigator.mediaDevices.enumerateDevices() 是浏览器反对的原生 API,这是一个异步调用,返回一个 promise 对象: 等到该异步调用的后果可供应用程序应用之后,咱们通过链式调用 then 传入的回调函数 gotDevices 被触发,输出的参数就是 navigator.mediaDevices.enumerateDevices() 调用的返回值。在调试器里看看这个返回值的明细: ...

March 16, 2022 · 2 min · jiezi

关于webrtc:WebRTC-简单入门与实践

一、前言WebRTC 技术曾经宽泛在各个行业及场景中被利用,但对少数开发者来说,实时音视频及相干技术却是比拟不常接触到的。 做为一名 Web 开发者,WebRTC 这块的概念着实花了不少工夫才搞明确,一是 WebRTC 自身有较多的独有概念,二是尽管带“Web”字样,但依赖底层概念和网络却是 Web 开发很少接触到的; 本篇文章以 0 教训音视频开发者 视角,类比罕用的 Web 技术,冀望帮忙您简略入门 WebRTC 技术,急躁看完本篇文章,你将: 理解什么是 WebRTC把握 WebRTC 通话原理利用 Chrome debug WebRTC 利用适宜浏览对象:Web开发,有 js 根底,对 WebRTC 感兴趣的同学 二、应用示例没有接触过 WebRTC 技术的同学,能够先体验下 ZEGO 的 GoEnjoy 产品,外面蕴含了 WebRTC 在浏览器中的规范应用计划,包含不限于:设施检测、兼容性检测、弱网断网应答策略等,利用是收费的,可戳--->示例 Demo 传送门 在进入注释之前,让咱们先对它有个根本的印象吧! 三、简略介绍体验完 Demo 后,有必要再理解一下技术的倒退历史、利用场景等,这些能让咱们晓得它为什么优良,哪方面优良,有哪些毛病等。 程序员常常用到 5W1H 分析法,那么本文就依照这个思路给大家做一下介绍: WhatWebRTC(Web Real-Time Communication),一个能够让用户用本人流量 实现音视频实时通信的框架(APIs),反对浏览器(Firefox、Chrome、safari)以及 iOS、Android 原生零碎。 When2017 年 12 月成为 W3C 草案,国内微信浏览器 19 年下半年才反对,国内手机自带浏览器目前还有不少兼容问题,2021 年 1 月 26 日,成为 W3C 正式规范。 ...

March 11, 2022 · 2 min · jiezi

关于webrtc:ZLMediaKit编译与webrtc推拉流测试

ZLMediaKit反对了webrtc的推流与播放。特此记录下编译与测试的过程。 编译环境OS版本:Ubuntu 20.04.2 LTSopenssl版本:OpenSSL 1.1.1fgcc版本:9.3.0cmake版本:3.16.3 编译筹备工作装置openssl。 $ git clone https://github.com/openssl/openssl.git$ ./config$ make -j4$ sudo make install# 查看openssl版本$ openssl version -a装置libsrtp。 $ git clone https://gitee.com/mirrors/cisco-libsrtp.git$ cd cisco-libsrtp# 反对webrtc$ ./configure --enable-openssl$ make -j4$ sudo make install编译ZLMediaKit下载源码。 # 国内用户举荐从同步镜像网站gitee下载 $ git clone --depth 1 https://gitee.com/xia-chu/ZLMediaKit$ cd ZLMediaKit# 千万不要遗记执行这句命令,同步三方依赖$ git submodule update --init编译源码。 $ mkdir build$ cd build$ cmake -DENABLE_WEBRTC=on ../$ make -j4如果编译不过能够尝试装置依赖库。 $ sudo apt-get install libssl-dev$ sudo apt-get install libsdl-dev$ sudo apt-get install libavcodec-dev$ sudo apt-get install libavutil-dev$ sudo apt-get install ffmpeg还须要留神openssl的装置门路,如果没对齐,也可能呈现编译或者运行谬误。这时只须要在指定门路上给openssl的库建个软连贯。编译胜利后会在release/linux/Debug/目录中生成相干程序。而后将ZLMediaKit中的www文件夹拷贝到release/linux/Debug/中,就能够进行webrtc的测试了。测试webrtc推拉流启动ZLMediaKit。 ...

February 14, 2022 · 1 min · jiezi

关于webrtc:资讯|WebRTC-M97-更新

WebRTC M97 目前在 Chrome 的稳定版中可用,蕴含 10 多个谬误修复、加强和稳定性/性能改良。 欢送关注网易云信公众号,咱们将定期翻译 WebRTC 相干内容,帮忙开发者取得最新资讯,走在行业前沿。 01.性能及问题修复可登陆: https://bugs.chromium.org/p/w... 输出问题 ID 即可查问 Bug 详情。 No.1 类型:Bug 问题 ID:11124 形容:套接字谬误时 CPU 占用达到 100% 组件:Internals No.2 类型:Bug 问题 ID:12132 形容:STUN_ATTRIBUTE_ORIGIN 应该从代码库中删除 组件:Cleanup No.3 类型:Bug 问题 ID:12194 形容:动静 rtp 无效负载类型的可用范畴已用尽 组件:PeerConnection No.4 类型:Bug 问题 ID:13265 形容:统计配置 ice 服务器的数量 组件:PeerConnection No.5 类型:Bug 问题 ID:13272 形容:增加 StateToString 函数将各种状态转换为字符串 组件:PeerConnection No.6 类型:Bug 问题 ID:13287 形容:setCodecPreferences 更改 rtx 编解码器在 SDP 中的地位 组件:PeerConnection No.7 ...

February 11, 2022 · 1 min · jiezi

关于webrtc:技术干货-基于标准-WebRTC-低延迟直播的开源实践

导读:2020年,新冠疫情暴发并席卷寰球,对包含中国在内的寰球经济造成了微小的冲击,同时深刻影响了社会生存。在这一背景下,以消费市场上轰轰烈烈的直播电商为引爆点,直播行业再次掀起热潮。在中国企业数字化转型的浪潮中倒退了十年之久的企业直播服务市场,也趁势进入高速倒退阶段。 文|洪顺迪 网易云信流媒体 Server 端研发工程师 1 典型的直播架构 在典型的直播架构中,右边是推流客户端,协定上才采纳 RTMP 上行;左边是拉流客户端,反对不同的拉流协定拉流,比拟常见的是:RTMP、FLV、HLS 1.1 现有架构的长处这套框架很好的利用了 CDN 厂商或者说云厂商的能力。只管拉流协定没有对立,rtmp/flv/hls 等拉流协定作为比拟成熟的流媒体协定,通过多年的倒退,失去了各 CDN 厂商广泛支持。在云端能力的反对下,服务端并发能力和拉流端减速能力大大增加了,直播行业蓬勃发展。 2 低提早直播的现状 在直播畛域中卡顿和提早就像是天平的两端。提早做的越短,则卡顿越高;提早越长,卡顿就越少。 个别场景下都是客户端用更大的 buffer 时长,就义延时来满足流畅性。随着行业的倒退,某一些利用场景对延时工夫的要求越来越刻薄,比方体育比赛直播,教育场景下老师与学生间的互动等,这些场景下常见的直播流媒体协定的毛病就体现进去了。 个别 rtmp 协定直播延时在 3-10s,如果通过层层 CDN 的缓存和转发,超过10秒也是常有的事,flv 和 hls 协定的延时更高。就拉流端来说,提早的很大一部分源自网络传输:rtmp 在传输媒体前的 tcp 3次握手和 c0/c1/c2 握手协定,无端引入了好几个 RTT 的提早;因为 rtmp/flv/hls 的传输层都是基于 tcp 协定,在网络不稳固的状况下,受限于 tcp 协定的拥塞管制不能充分利用网络带宽,客户端为了放弃流畅性,只能加大缓存工夫,因而更进一步加大了提早。\  在意识到现有流媒体直播协定的局限性后,各大友商也纷纷推出了本人的低延时直播,较好的起到了反抗弱网和放慢首屏的作用。但目前大都基于公有的信令协定和公有的 UDP 流媒体传输协定,各大云厂商无奈相互兼容,这就限度了低提早直播的大规模倒退。 3 基于规范 WebRTC 的低提早直播的开源实际网易云信始终在摸索如何做一个凋谢的低延时直播计划, 未来各家云厂商也可能比拟不便的实现,就像现有的 rtmp/hls 协定一样,推动整个直播行业低提早化。要实现这种计划须要做以下两件事件。 凋谢的信令协定: 信令协定须要满足绝大多数厂商的媒体协商需要,同时又能尽可能的简洁。凋谢的媒体协定: 媒体传输协定须要满足在各大厂商间可能通用,在这之上的 QoS 能力也须要凋谢,不能是公有的。根据下面的要求咱们抉择了 RTC 畛域成熟的解决方案——WebRTC。下图是咱们当初的实际架构。 上图中 WE-CAN 是网易云信的寰球减速 RTC 大网,媒体在 Server 间的网络传输依赖 WE-CAN。 边缘媒体服务器从 CDN 拉流到 WE-CAN 大网边缘节点,再从 WE-CAN 大网边缘节点发送给客户端。 ...

January 7, 2022 · 2 min · jiezi

关于webrtc:资讯|WebRTC-M96-更新

摘要:WebRTC M96 行将推出稳定版,蕴含 2 个新个性以及超过 11 个bug修复、性能加强和稳定性/性能方面的改良。 01. 公共服务布告No.1 题目:Plan B 弃用 形容:除非网站已注册限时的反向起源试验,否则在 M96 稳定版中Plan B SDP 将不再可用。 详情见: https://groups.google.com/g/d... No.2 题目:**dcSCTP 库 形容:用于 SCTP 传输的 DcSCTP 库的推出工作在 M96 中复原。 详情见: https://groups.google.com/g/d... 02. 亮点性能反对 RFC 2198 冗余 目前曾经反对应用 RED 的 OPUS 音频冗余。 详情见:  https://groups.google.com/g/d... 03. 性能及问题修复可登陆: https://bugs.chromium.org/p/w... 输出问题 ID 即可查问 Bug 详情。 No.1 类型:Bug 问题 ID:10569 形容:实现 RTCIceCandidatePairStats.packetsSent 和 packetsReceived 组件:Stats No.2 类型:Feature 问题 ID:10739 形容:增加对 abs-capture-time 标头扩大的反对 组件:Network>RTP No.3 类型:Bug 问题 ID:12169 ...

January 6, 2022 · 1 min · jiezi

关于webrtc:Mac下编译WebRTCMac和iOS版本

前言随着新冠疫情的影响,这两年音视频的需要呈爆发式增长。在音视频畛域中,WebRTC能够说是一个绕不开宝库,包含了音视频采集、编解码、传输、渲染的全过程。本文次要记录下在Mac平台上编译WebRTC Mac和iOS版本的全过程。 设置代理因为家喻户晓的起因,要下载WebRTC的源码是须要代理工具的。 export http_porxy="http://127.0.0.1:21087"export https_porxy="http://127.0.0.1:21087"装置工具depot_toolsgit clone获取depot_tools git clone https://chromium.googlesource.com/chromium/tools/depot_tools.git将depot_tools的门路配置到环境变量中 export PATH=$PWD/depot_tools:$PATH下载webrtc源码mkdir webrtccd webrtcfetch --nohooks webrtc_iosgclient sync默认下载的是最新的源码,如果想要切换到指定分支,能够应用以下命令: # 查看可用版本分支git branch -r# 切换到m79分支git checkout branch-heads/m79gclient sync# 或者强制切换到指定commit(b484ec0082948ae086c2ba4142b4d2bf8bc4dd4b是m79最初一次提交的commit id)gclient sync -r b484ec0082948ae086c2ba4142b4d2bf8bc4dd4b --force能够在从这里获取webrtc所有release版本的信息 编译Mac版本: gn gen out/mac-release --args='target_os="mac" target_cpu="x64" is_debug=false use_rtti=true is_component_build=false rtc_use_h264=false rtc_include_tests=false' --ide=xcodeninja -C out/mac-release编译胜利后,。 iOS版本: # 编译不带证书版本gn gen out/ios-release --args='target_os="ios" target_cpu="arm64" is_debug=false use_rtti=true is_component_build=false ios_enable_code_signing=false proprietary_codecs=false rtc_use_h264=false rtc_include_tests=false' --ide=xcodeninja -C out/ios-release# 获取证书名security find-identity -v -p codesigning# 编译带证书版本gn gen out/ios-release-sign --args='target_os="ios" target_cpu="arm64" is_debug=false use_rtti=true is_component_build=false ios_code_signing_identity="下面命令获取到的那串数字" proprietary_codecs=false rtc_use_h264=false rtc_include_tests=false' --ide=xcodeninja -C out/ios-release-sign编译胜利后,会在src\out\xxxx\下生成all.xcworkspace文件。关上就能够构建、调试webrtc的我的项目。其中APPRTCMobile是谷歌提供的示例demo,可打包在真机上运行。在src\out\xxxx\也生成了WebRTC.framework库文件,在内部我的项目中援用该库文件就能够应用其音视频能力了。 ...

December 25, 2021 · 1 min · jiezi

关于webrtc:优酷播放黑科技-基于WebRTC实现的直播云多视角技术解析

作者:张凌柱(以绳) 本文为《优酷播放黑科技》系列文章第二篇,第一篇文章可点击优酷播放黑科技 | 自在视角技术体验优化实际进行查看。点关注不迷路 ~直播内容区别于点播,因其实时性、强互动性的特点吸引着用户,在观看的同时还能够同步进行点赞、评论、打赏等互动行为。此类互动次要集中在用户的社交行为,而内容型的互动也随着点播中的“互动剧集”的呈现而映入公众的眼帘,用户能够在剧情停顿的要害节点抉择角色执行不同的行为继而进入到不同的分支剧情中。同样直播方向上的内容型互动也在被不停的摸索和利用中,其中一个例子就是同时进行多个视角的直播,容许用户切换抉择某个特定的视角观看直播内容。尤其在中大型的直播流动中(例如街舞、欧冠等),粉丝向比拟显著(明星、球星),如果能提供多个观看视角或者提供某个聚焦视角供切换抉择,在用户体验上无疑能有很大的晋升。 基于此,通过钻研与摸索,最终基于WebRTC落地实现了低提早高清晰度的多视角直播能力,并在《这!就是街舞》的年度总决赛正式上线利用。成果视频如下: 视频可点击查看:优酷播放黑科技 | 基于WebRTC实现的直播"云多视角"技术解析 计划选型是否实现低提早切换、高清晰度、全机型笼罩的用户体验是最终决定采纳哪种技术计划的重要衡量标准。业内罕用的应用层协定包含: HLS(含LHLS)RTMPRTP(严格来说RTP介于应用层和传输层之间)其中,RTMP因其优缺点(低提早但易被防火墙拦挡)被确定用于直播推流,本文暂不多作介绍,上面咱们次要针对拉流过程进行剖析。依据端上拉流个数能够将实现计划分为: 单路流伪多视角直播:基于HLS协定,端上同一时间仅拉取一路流,切视角须要从新切流地址起播;多路流多视角直播:基于HLS协定,端上同时拉取多路流进行解码渲染,切视角不须要切流地址起播;单路流多视角直播:基于RTP协定,端上同一时间仅拉取一路流,切视角不须要从新切流地址起播。横向比照对处于劣势的个性作标红解决后失去的表格: 计划协定同时预览无缝切换码率端性能累赘增量老本单路流伪多视角直播HLS否否一般一般无多路流多视角直播HLS是是高高CDN单路流多视角直播RTP是是一般一般边缘服务与流量带宽通过比照,咱们最终决定采纳基于RTP的单路流多视角直播,即边缘计划。 WebRTC 概述WebRTC,名称源自网页即时通信(英语:Web Real-Time Communication)的缩写,是一个反对网页浏览器进行实时语音对话或视频对话的 API。它于 2011 年 6 月 1 日开源并在 Google、Mozilla、Opera 反对下被纳入万维网联盟的 W3C 举荐规范。WebRTC默认应用UDP协定(实际上应用的是RTP/RTCP协定)进行音视频数据的传输,然而也能够通过TCP传输。目前次要利用于视频会议和连麦中。 WebRTC内部结构 Voice Engine 音频引擎负责音频采集和传输,具备降噪、回声打消等性能。Video Engine视频引擎负责网络抖动优化,互联网传输编解码优化。音视频引擎之上是 一套 C++ API。 WebRTC 协定栈 ICE、STUN、TURN 用于内网穿透, 解决了获取与绑定外网映射地址的问题。DTLS (UDP 版的 TLS)用于对传输内容进行加密 。RTP/SRTP次要用来传输对实时性要求比拟高的音视频数据,RTCP/SRTCP用来管制RTP传输品质。SCTP用于自定义利用数据的传输。 零碎设计多视角直播整体链路波及流生产、域名调度服务、边缘服务、合流服务、直播播控服务等多个环节,整体构造框架如下: 流生产:演播现场摄像机采集流上传到直播核心,直播核心对流进行编码及优化解决;合流服务:多路输出流通过工夫戳进行音视频对齐后,依照模版输入多路混合流;边缘服务:预缓存合流服务多路输入流, 对输入流进行编码, 通过RTP连贯传输给端侧;域名调度服务:进行IP、端口配置,供端侧与边缘服务通信;播控服务:提供合流服务申请参数配置、及多视角业务能力配置等播放管制服务。具体设计端侧为了尽可能的复用播控主链路,缩小对主播放链路的侵入, 减少了多视角播放器。多视角播放器与其余播放器放弃雷同的调用接口,在播控处依据业务类型决定是否创立多视角播放器。在业务层减少多视角插件,与其余业务解耦,能够很不便的挂载与移除。 端侧结构设计如下: 外围流程用户进入多视角模式次要起播流程如下: 目前反对3种展现状态,别离为mix模式、cover模式及source模式, 下图为具体状态及切换过程。 []() 边端指令端侧与边缘结点次要交互指令,通过RTP协定进行数据传输。通用头部传输格局如下,PT=96 代表H264媒体数据。 建连指令:阻塞式指令,端侧与边缘结点建设RTP连贯,须要期待边缘结点返回响应,如果在肯定工夫内无返回,则认为建连失败;断连指令:非阻塞式指令,端侧与边缘结点断开连接,无需期待边缘结点返回;播放指令:非阻塞式指令,端侧下发播放指令,须要传递播放流ID及OSS流配置信息,供边缘结点查找到正确流;切流指令:非阻塞式指令,端侧下发切换视角指令,为了与原视角放弃同步,须要传递原视角帧工夫戳到边缘服务。我的项目落地播放能力调整音频采样率调整WebRTC目前默认不反对48K音频采样率,而以后大型直播的采样率较高,如果不通过调整下发到端上会导致音频解码模块的解体; AAC音频解码能力扩大WebRTC里音频编码默认用的是Opus,但以后直播现状大部分都是AAC格局,所以须要客户端在offer SDP 中增加AAC编码信息并实现AAC解码器,边缘服务配合下发RTP打包数据; H.264编码反对为了尽可能地升高延时,WebRTC视频编码采纳的是VP8和VP9,须要迁徙至更通用的H.264编码; 在传输方式上,WebRTC应用P2P形式来进行媒体直达,它只是解决端到端的问题,对于大型PGC、OGC的直播内容来说显著不适宜,因而网络传输层并没有打洞逻辑,利用RTP连贯传输流媒体数据,RTCP进行传输品质管制。接入已有播放体系为了尽可能小的缩小对主播放器影响,与主播放器放弃了统一的数据申请流程、一样的播放能力接口、统一的数据埋点机会等: 多视角播放器:封装WebRTC, 扩大出多视角播放器, 专用于多视角视频播放;播控逻辑调整:调整直播旁路数据获取流程,将合路服务、AMDC等服务返回数据合并到数据流中;播放能力&统计调整:放弃原有播放能力及回调接口, 通过扩大接口参数来予以辨别;扩大错误码:基于主播放器谬误规定, 扩大出多视角播放器错误码。端侧问题解决最终须要实现下图所示的主播放窗口附带几个子播放窗口同时渲染: ...

December 20, 2021 · 1 min · jiezi

关于webrtc:资讯|WebRTC-M95-更新

WebRTC M95目前已在Chrome测试版中公布,蕴含4个新个性以及超过6个bug修复、性能加强、稳定性与性能等方面的改良。欢送关注网易云信账号,咱们将定期翻译 WebRTC 相干内容,帮忙开发者取得最新资讯,走在行业前沿。 01.亮点性能dcSCTP用于SCTP传输的DcSCTP库的推出开启了这一里程碑。详情见布告。 02. 性能及问题修复可登陆:https://bugs.chromium.org/p/w... 输出问题 ID 即可查问 Bug 详情。 No.1类型:Feature问题 ID:1146942形容:chromium/webrtc应用的pipewire 版本从 0.2 降级到 0.3组件:Internals>Media>ScreenCapture No.2类型:Feature问题 ID:1203442形容:删除3DES明码套件组件:Internals>Network>SSL No.3类型:Bug问题 ID:1241213形容:M93之后版本复用收发器来增加最近删除的视频轨道的性能不起作用组件:Blink>WebRTC No.4类型:Bug问题 ID:1247182形容:rtcp_receiver_fuzzer: webrtc::RTCPReceiver::ParseCompoundPacket应用了未初始化的值组件:Blink>WebRTC>Network No.5类型:Bug问题 ID:10812形容:解决编码器封装和测试模块的非整数帧率问题组件:Video No.6类型:Bug问题 ID:11640形容:反对RFC 2198冗余组件:Audio No.7类型:Bug问题 ID:12933形容:Chrome不反对接管角色设置选项不为actpass的提议SDP组件:PeerConnection No.8类型:Feature问题 ID:13077形容:可插入流:公开有效载荷类型组件:PeerConnection No.9类型:Bug问题 ID:13078形容:WgcCaptureSource在尝试采集所有显示器时抛出异样组件:DesktopCapture 原文链接:https://groups.google.com/g/d... 对于网易云信网易云信是集网易 20 余年 IM 以及音视频技术打造的交融通信云服务专家,稳固易用的通信与视频 PaaS 平台。提供交融通信与视频的外围能力与组件,蕴含 IM 即时通讯、5G 音讯平台、一键登录、信令、短信与号码隐衷爱护等通信服务,音视频通话、直播、点播、互动直播与互动白板等音视频服务,视频会议等组件服务。网易云信服务于网易云音乐、好将来、新东方、科大讯飞、南京银行等各行各业客户。

December 17, 2021 · 1 min · jiezi

关于webrtc:Windows下编译WebRTC

前言随着新冠疫情的影响,这两年音视频的需要呈爆发式增长。在音视频畛域中,WebRTC能够说是一个绕不开宝库,包含了音视频采集、编解码、传输、渲染的全过程。本文次要记录下在Windows平台上编译WebRTC的全过程。 装置VS在Windows下开发和调试程序咱们个别都是应用宇宙最强IDE——Visual Studio,webRTC也反对咱们生成VS的工程。装置VS过程不赘述(举荐装置VS2017或VS2019),须要留神的是VS装置的时候须勾选上面三项: Windows 10 SDK(10.0.18362)或以上的Windows 10 SDK(m84版的WebRTC源码要求10.0.18362或以上Windows 10 SDK)。用于 x86 和 x64 的 Visual C++ ATL。用于 x86 和 x64 的 Visual C++ MFC。VS2017装置选项中不带有Windows 10 SDK(10.0.18362),能够从从Win10 SDK下载,或者间接装置VS2019。 装置完VS后,还须要装置SDK调试工具。办法是: 关上控制面板->程序与性能,找到Windows Software Development Kit,鼠标右键->更改。在关上界面中抉择Change,点击Next。勾选Debugging Tools For Windows,点击Change。设置代理因为家喻户晓的起因,要下载WebRTC的源码是须要代理工具的。 set http_proxy=127.0.0.1:7777set https_proxy=127.0.0.1:7777装置工具depot_toolsgit clone获取depot_tools git clone https://chromium.googlesource.com/chromium/tools/depot_tools.git# 装置Windows上的编译工具gclient将depot_tools目录的门路配置到零碎环境变量Path中,且设置到最后面。 下载webrtc源码mkdir webrtc-checkoutcd webrtc-checkoutfetch --nohooks webrtcgclient sync默认下载的是最新的源码,如果想要切换到指定分支,能够应用以下命令: # 查看可用版本分支git branch -r# 切换到m79分支git checkout branch-heads/m79gclient sync# 或者强制切换到指定commit(b484ec0082948ae086c2ba4142b4d2bf8bc4dd4b是m79最初一次提交的commit id)gclient sync -r b484ec0082948ae086c2ba4142b4d2bf8bc4dd4b --force能够在从这里获取webrtc所有release版本的信息 编译# 设置vs2017环境变量set GYP_MSVS_VERSON=2017set vs2019_install=C:\Program Files (x86)\Microsoft Visual Studio\2017\Communityset GYP_MSVS_OVERRIDE_PATH=C:\Program Files (x86)\Microsoft Visual Studio\2017\Community# 设置vs2019环境变量set GYP_MSVS_VERSON=2019set vs2019_install=C:\Program Files (x86)\Microsoft Visual Studio\2019\Communityset GYP_MSVS_OVERRIDE_PATH=C:\Program Files (x86)\Microsoft Visual Studio\2019\Communityset GYP_GENERATORS=msvs-ninja,ninja# 通知depot_tools应用咱们本机的VS进行编译set DEPOT_TOOLS_WIN_TOOLCHAIN=0# 编译vs2017 release:gn gen out\Release-vs2017 --ide=vs2017 --args="is_debug=false target_os=\"win\" target_cpu=\"x64\" is_component_build=false is_clang=false use_lld=false treat_warnings_as_errors=false use_rtti=true rtc_include_tests=false rtc_build_examples=false"ninja -C out\Release-vs2017# 编译vs2019 release:gn gen out\Release-vs2019 --ide=vs2019 --args="is_debug=false target_os=\"win\" target_cpu=\"x64\" is_component_build=false is_clang=false use_lld=false treat_warnings_as_errors=false use_rtti=true rtc_include_tests=false rtc_build_examples=false"ninja -C out\Release-vs2019ps: ...

December 12, 2021 · 1 min · jiezi

关于webrtc:WebRTC简介

title: WebRTC简介 categories:[WebRTC] tags:[音视频编程] date: 2021/12/09 作者:hackett 微信公众号:加班猿 WebRTC简介WebRTC (Web Real-Time Communications) 是一项实时通信技术,它容许网络应用或者站点,在不借助两头媒介的状况下,建设浏览器之间点对点(Peer-to-Peer)的连贯,实现视频流和(或)音频流或者其余任意数据的传输。WebRTC蕴含的这些规范使用户在无需装置任何插件或者第三方的软件的状况下,创立点对点(Peer-to-Peer)的数据分享和电话会议成为可能。 WebRTC架构 色彩标识阐明(1)紫色局部是Web开发者API层; (2)蓝色实线局部是面向浏览器厂商的API层 (3)蓝色虚线局部浏览器厂商能够自定义实现 架构组件介绍(1) Your Web App Web开发者开发的程序,Web开发者能够基于集成WebRTC的浏览器提供的web API开发基于视频、音频的实时通信利用。 (2)Web API 面向第三方开发者的WebRTC规范API(Javascript),使开发者可能容易地开发出相似于网络视频聊天的web利用。 这些API可分成Network Stream API、 RTCPeerConnection、Peer-to-peer Data API三类,具体的API阐明能够看这里。 Network Stream API MediaStream:MediaStream用来示意一个媒体数据流。 MediaStreamTrack在浏览器中示意一个媒体源。 RTCPeerConnection RTCPeerConnection: 一个RTCPeerConnection对象容许用户在两个浏览器之间间接通信。 RTCIceCandidate :示意一个ICE协定的候选者。 RTCIceServer:示意一个ICE Server。 Peer-to-peer Data API DataChannel:数据通道( DataChannel)接口示意一个在两个节点之间的双向的数据通道 。 (3)WebRTC Native C++ API 本地C++ API层,使浏览器厂商容易实现WebRTC规范的Web API,抽象地对数字信号过程进行解决。 (4)Transport / Session 传输/会话层 会话层组件采纳了libjingle库的局部组件实现,毋庸应用xmpp/jingle协定 a. RTP Stack协定栈 Real Time Protocol b. STUN/ICE ...

December 9, 2021 · 2 min · jiezi

关于webrtc:WebRTC源码级深度解析进阶大厂高级音视频开发者MK

download:WebRTC源码级深度解析,进阶大厂高级音视频开发者allow_system_table_mods Allows modifications of the structure of system tables. 容许修改零碎表的结构。application_name Sets the application name to be reported in statistics and logs. 设置要在统计和日志中报告的应用程序名称。archive_command Sets the shell command that will be called to archive a WAL file. 设置将调用的命令来归档一个文件。archive_mode Allows archiving of WAL files using archive_command. 容许使用archive_command WAL文件归档。archive_timeout Forces a switch to the next xlog file if a new file has not been started within N seconds. 强制切换到下一个文件,如果一个新Xlog文件尚未在N秒开始。array_nulls Enable input of NULL elements in arrays. 启用数组中null元素的输出。authentication_timeout Sets the maximum allowed time to complete client authentication. 设置实现客户端身份考据的最大容许工夫。autovacuum Starts the autovacuum subprocess. 开始autovacuum子。autovacuum_analyze_scale_factor Number of tuple inserts, updates, or deletes prior to analyze as a fraction of reltuples. 元组的插入、更新或删除数,分析作为reltuples分数之前。autovacuum_analyze_threshold Minimum number of tuple inserts, updates, or deletes prior to analyze. 在分析之前插入、更新或删除的最小元组数。autovacuum_freeze_max_age Age at which to autovacuum a table to prevent transaction ID wraparound. 年龄在autovacuum表以防止事务ID的概括。autovacuum_max_workers Sets the maximum number of simultaneously running autovacuum worker processes. 组同时运行autovacuum工人最大过程数。autovacuum_naptime Time to sleep between autovacuum runs. 睡觉的工夫autovacuum之间运行。autovacuum_vacuum_cost_delay Vacuum cost delay in milliseconds, for autovacuum. 真空成本提早毫秒,对于autovacuum。autovacuum_vacuum_cost_limit Vacuum cost amount available before napping, for autovacuum. 真空成本金额可用午睡前后,为autovacuum。autovacuum_vacuum_scale_factor Number of tuple updates or deletes prior to vacuum as a fraction of reltuples. 一些元组更新或删除reltuples真空作为一部分之前。autovacuum_vacuum_threshold Minimum number of tuple updates or deletes prior to vacuum. 在真空之前元组更新或删除的最小数目。backslash_quote Sets whether "\'" is allowed in string literals. 设置字符串文本中是否容许“\”。bgwriter_delay Background writer sleep time between rounds. 背景作家轮间睡眠工夫。bgwriter_lru_maxpages Background writer maximum number of LRU pages to flush per round. 背景的作家最大数量的LRU页面刷新每轮。bgwriter_lru_multiplier Multiple of the average buffer usage to free per round. 平均缓冲区使用量的倍数为每轮收费。block_size Shows the size of a disk block. 浮现磁盘块的大小。bonjour Enables advertising the server via Bonjour. 使广告服务器通过卓悦。bonjour_name Sets the Bonjour service name. 集的Bonjour服务名称。bytea_output Sets the output format for bytea. 集bytea输入格局。check_function_bodies Check function bodies during CREATE FUNCTION. 在创建函数期间查看函数体。checkpoint_completion_target Time spent flushing dirty buffers during checkpoint, as fraction of checkpoint interval. 在查看点中清除脏缓冲区的工夫,作为检查点间隔的一部分。checkpoint_segments Sets the maximum distance in log segments between automatic WAL checkpoints. 设置主动检查点之间的日志段的最大距离。checkpoint_timeout Sets the maximum time between automatic WAL checkpoints. 设置主动检查点之间的最大工夫。checkpoint_warning Enables warnings if checkpoint segments are filled more frequently than this. 如果检查点段填充比此更频繁,则启用警告。client_encoding Sets the client's character set encoding. 设置客户端的字符集编码。client_min_messages Sets the message levels that are sent to the client. 设置发送给客户机的消息级别。commit_delay Sets the delay in microseconds between transaction commit and flushing WAL to disk. 在事务提交和刷新到磁盘之间设置提早微秒。commit_siblings Sets the minimum concurrent open transactions before performing commit_delay. 设置最小并发公开交易前执行commit_delay。config_file Sets the server's main configuration file. 设置服务器的主配置文件。constraint_exclusion Enables the planner to use constraints to optimize queries. 使布局人员能够使用束缚来优化查问。cpu_index_tuple_cost Sets the planner's estimate of the cost of processing each index entry during an index scan. 在索引扫描期间设置计划者对处理每个索引项的成本的估计值。cpu_operator_cost Sets the planner's estimate of the cost of processing each operator or function call. 设置计划者对每个操作员或函数调用途理成本的估计值。cpu_tuple_cost Sets the planner's estimate of the cost of processing each tuple (row). 设置计划程序处理每个元组(行)的成本的估计值。cursor_tuple_fraction Sets the planner's estimate of the fraction of a cursor's rows that will be retrieved. 设置要检索的游标行的小数部分的计划者的估计值。data_directory Sets the server's data directory. 设置服务器的数据目录。DateStyle Sets the display format for date and time values. 设置日期和工夫值的浮现格局。db_user_namespace Enables per-database user names. 启用每个数据库用户名。deadlock_timeout Sets the time to wait on a lock before checking for deadlock. 在查看死锁之前设置等待锁的工夫。debug_assertions Turns on various assertion checks. 打开各种断言查看。debug_pretty_print Indents parse and plan tree displays. 缩进的解析和计划树浮现。debug_print_parse Logs each query's parse tree. 记录每个查问的解析树。debug_print_plan Logs each query's execution plan. 记录每个查问的执行计划。debug_print_rewritten Logs each query's rewritten parse tree. 记录每个查问重写的解析树。default_statistics_target Sets the default statistics target. 设置默认统计目标。default_tablespace Sets the default tablespace to create tables and indexes in. 设置默认表空间以创建表和索引。default_text_search_config Sets default text search configuration. 设置默认文本搜寻配置。default_transaction_deferrable Sets the default deferrable status of new transactions. 套新事务的默认提早状态。default_transaction_isolation Sets the transaction isolation level of each new transaction. 设置每个新事务的事务隔离级别。default_transaction_read_only Sets the default read-only status of new transactions. 设置新事务的默认只读状态。default_with_oids Create new tables with OIDs by default. 创建新表时默认。dynamic_library_path Sets the path for dynamically loadable modules. 设置动静可加载模块的路径。effective_cache_size Sets the planner's assumption about the size of the disk cache. 设置布局程序对于磁盘缓存大小的假设。effective_io_concurrency Number of simultaneous requests that can be handled efficiently by the disk subsystem. 磁盘子系统可能高效处理的同时请求数。enable_bitmapscan Enables the planner's use of bitmap-scan plans. 使布局人员使用位图扫描计划。enable_hashagg Enables the planner's use of hashed aggregation plans. 使计划使用哈希聚合计划。enable_hashjoin Enables the planner's use of hash join plans. 使计划人员使用哈希连接计划。enable_indexonlyscan Enables the planner's use of index-only-scan plans. 使布局人员只使用索引扫描计划。enable_indexscan Enables the planner's use of index-scan plans. 容许计划人员使用索引扫描计划。enable_material Enables the planner's use of materialization. 容许策划者使用物化。enable_mergejoin Enables the planner's use of merge join plans. 使计划人员使用合并联接计划。enable_nestloop Enables the planner's use of nested-loop join plans. 使策划者能够使用嵌套循环连接计划。enable_seqscan Enables the planner's use of sequential-scan plans. 使布局人员使用次序扫描计划。enable_sort Enables the planner's use of explicit sort steps. 使布局人员使用显式排序步骤。enable_tidscan Enables the planner's use of TID scan plans. 使计划使用TID扫描计划。escape_string_warning Warn about backslash escapes in ordinary string literals. 警告在一般字符串中的反斜杠。event_source Sets the application name used to identify PostgreSQL messages in the event log. 设置用于必定在事件日志消息的应用程序名称PostgreSQL。exit_on_error Terminate session on any error. 终止任何谬误的会话。external_pid_file Writes the postmaster PID to the specified file. 将邮政局长PID写入指定的文件。extra_float_digits Sets the number of digits displayed for floating-point values. 设置浮现浮点值的位数。from_collapse_limit Sets the FROM-list size beyond which subqueries are not collapsed. 设置从列表的大小超过该子查问不倒塌。fsync Forces synchronization of updates to disk. 强制更新到磁盘的同步。full_page_writes Writes full pages to WAL when first modified after a checkpoint. 在检查点第一次修改后写入完整的页面。geqo Enables genetic query optimization. 启用遗传查问优化。geqo_effort GEQO: effort is used to set the default for other GEQO parameters. geqo:致力是用来为其余geqo参数设置默认。geqo_generations GEQO: number of iterations of the algorithm. geqo:算法的迭代次数。geqo_pool_size GEQO: number of individuals in the population. geqo:群体中的个体数。geqo_seed GEQO: seed for random path selection. geqo:种子随机路径抉择。geqo_selection_bias GEQO: selective pressure within the population. geqo:在人口压力。geqo_threshold Sets the threshold of FROM items beyond which GEQO is used. 设置阈值的物品之外,geqo使用。gin_fuzzy_search_limit Sets the maximum allowed result for exact search by GIN. 设置杜松子酒精确搜寻的最大容许后果。hba_file Sets the server's "hba" configuration file. 设置服务器的HBA配置文件。hot_standby Allows connections and queries during recovery. 容许复原期间的连接和查问。hot_standby_feedback Allows feedback from a hot standby to the primary that will avoid query conflicts. 容许来自热备份的反馈到主,避免查问冲突。ident_file Sets the server's "ident" configuration file. 设置服务器的“识别”配置文件。ignore_system_indexes Disables reading from system indexes. 禁用零碎索引读取。integer_datetimes Datetimes are integer based. 日期是基于整数。IntervalStyle Sets the display format for interval values. 设置区间值的浮现格局。 ...

November 20, 2021 · 5 min · jiezi

关于webrtc:WebRTC源码级深度解析进阶大厂高级音视频开发者MK

download:WebRTC源码级深度解析,进阶大厂高级音视频开发者Python字典内置函数和方法: 注:使用了 items、values、keys 返回的是可迭代对象,可能使用 list 转化为列表。 len(字典名): 返回键的个数,即字典的长度 复制代码 len(字典名):返回键的个数,即字典的长度dic = {'a':123,'b':456,'c':789,'d':567}print(len(dic)) 4复制代码str(字典名): 将字典转化成字符串 复制代码 str(字典名):将字典转化成字符串dic = {'a':123,'b':456,'c':789,'d':567}print(str(dic)) {'a': 123, 'b': 456, 'c': 789, 'd': 567}复制代码type(字典名): 查看字典的类型 复制代码 type(字典名):查看字典的类型dic = {'a':123,'b':456,'c':789,'d':567}print(type(dic)) <class 'dict'>复制代码内置方法: clear( ): 删除字典内所有的元素 复制代码 clear( ):删除字典内所有的元素dic = {'a':123,'b':456,'c':789,'d':567}dic.clear()print(dic) {}复制代码copy( ): 浅拷贝一个字典 复制代码 copy( ):浅拷贝一个字典dic = {'a':123,'b':456,'c':789,'d':567}dic_two = dic.copy()print(dic) {'a': 123, 'b': 456, 'c': 789, 'd': 567}print(dic_two) {'a': 123, 'b': 456, 'c': 789, 'd': 567}复制代码fromkeys(seq[,value]): 创建一个新字典,seq作为键,value为字典所有键的初始值(默认为None) 复制代码 ...

November 17, 2021 · 1 min · jiezi

关于webrtc:构建基于浏览器的Web-P2P网络直播

摘要 在2021年的互联网时代,越来越多的网络直播节目相继涌现。浏览器是用户最易接触的渠道之一,汇集了大量观看直播的用户。当用户们同时观看直播内容时,服务器接受的负载随着用户量的减少而增大,会导致播放的卡顿,提早等用户体验的降落;而且昂扬的服务器带宽老本也不容忽视。 那么是否存在一套解决方案,在保障用户体验与服务质量的前提下,又能够无效的升高服务器的负载与带宽呢?那就是接下来要介绍的Web P2P技术了。 一、Web P2P的前世今生 2010年,Adobe在Flash Player 10.0推出了实时流媒体RTMFP,应用RTMFP在Flash Player之间进行P2P成为可能。在随后的几年内,该协定在网络上如雨后春笋般的被宽泛部署,然而从2020年末开始,各家的浏览器都曾经彻底不反对Flash了。咱们又应该如何在Web外面应用P2P呢? 诞生于2011年的WebRTC技术,在Google、Microsoft、Apple、Mozilla等大厂的反对下,成为了H5的规范,并且Chrome、Edge、Safari、Firefox等支流浏览器也都反对WebRTC。所以就能够通过WebRTC来实现P2P了。 下文把基于WebRTC实现的HTML5 P2P简称为H5 P2P。 二、WebRTC简介 WebRTC的总体架构如下图所示,如果是浏览器开发者,通常须要关注并实现WebRTC C++ API,而咱们的指标是基于浏览器实现P2P,所以只须要关注Web API即可。 整体的H5 P2P都是基于RTCPeerConnection和RTCDataChannel来实现的,只是实现数据层面的P2P,不蕴含音视频通信的内容。 三、总体架构 H5 P2P客户端次要蕴含通信模块、传输模块、节点治理、调度模块、存储模块和统计模块: 通信模块:次要负责和服务端(上图中的Index、CPS、Tracker)进行信令的通信 传输模块:蕴含HTTPClient和基于RTCDataChannel实现的RTCClient(上传&下载) 节点治理:不同用户间P2P主被动连贯、断开、淘汰、资源信息同步 调度模块:依据buffer水位、分片信息、节点品质和规模进行CDN/P2P调度 存储模块:负责媒体数据的存储、排序、以及淘汰 统计模块:蕴含零碎运行的埋点的实现 H5 P2P服务端次要蕴含Index、CPS、Tracker和Stun服务: Index:索引服务,提供其余服务地址。 CPS:资源属性服务,将直播流的URL转换为RID。 Tracker:资源追踪服务,次要存储用户和资源之间的索引关系。 MQTT:信令服务,转发用户间建设P2P连贯的offer/answer/candidate SDP协定。 Stun:采纳coturn部署,次要用户节点之间建设对等连贯的UDP穿透。 四、阶段流程 下图简略的展现了整体计划的各个阶段、流程: Step 1:网页关上,首先向Index服务申请其余服务的地址,保留于内存中 Step 2:客户端收到直播申请,向CPS发送申请将URL转换为资源ID(RID),雷同内容雷同清晰度的直播流的资源ID(RID)是雷同的,表明能够相互分享数据 Step 3:客户端首先会启动HTTPClient进行数据下载,优先保障秒播。同时做以下2件事 a. 客户端向Tracker服务发送Address协定,获取其余正在观看该直播的用户地址,待后续建设连贯,分享数据 b. 客户端向Tracker服务发送Publish协定,将本人的信息告知Tracker,使得他人能够即便搜寻到本人,进行数据分享 Step 4:向从Tracker获取的其余用户建设连贯,彼此替换信息,数据分享 五、连贯建设 假如在Peer1和Peer2之间传输数据,那么在传输之前,首先须要建设连贯。在WebRTC中,浏览器间通过ICE框架建设对等连贯,次要蕴含Stun、TURN,上面别离简略介绍一下: ICEICE(Interactive Connectivity Establishment)提供的是一种P2P连贯框架,对立各种NAT穿透技术(STUN,TURN)。基于offer/answer/candidate模式,通过屡次地址替换,而后进行连通性测试,穿透用户网络间各类防火墙。ICE次要蕴含STUN、TURN等协定。 STUNSTUN(Simple Traversal of UDP Through NAT)容许位于NAT设施后的客户端找到本人的公网IP/Port地址,以及查问出本人的NAT设施类型,通过这些信息使得两个同时位于NAT后的2个设施之间建设UDP通信,具体的STUN流程能够参考RFC5389,不在此赘述。 TURN艰深的说,TURN(Traversal Using Relays around NAT)就是中继/转发,并不是所有的设施之间都能够依附STUN来建设连贯的,那么当两个设施之间无奈依附STUN建设连贯时,就会启用TURN来进行数据直达。 ...

September 30, 2021 · 1 min · jiezi

关于webrtc:Chrome下使用WebRTC实现屏幕共享

概述屏幕共享就是将本人电脑的屏幕内容以视频的形式分享给其他人观看,以进步沟通效率。屏幕共享作为一种实现互动的形式,经常出现在用户的生存场景中,比方: 视频会议中,屏幕共享能够将讲话者本地的文件、数据、网页、PPT 等画面分享给其余与会人。在线课堂场景中,屏幕共享能够将老师的课件、笔记、讲课内容等画面展现给学生观看。那么如何可能简略不便的实现屏幕共享呢?本篇文章将具体介绍如何在Chrome下应用WebRTC疾速实现屏幕共享。 屏幕共享实现 屏幕共享大抵能够分为屏幕流捕获,流传输和屏幕流渲染。 屏幕流捕获:能够应用Chrome提供的getDisplayMedia办法来捕捉屏幕流,为流传输提供数据。流传输:应用WebRTC来将数据传输给服务器或者另一个客户端,因WebRTC提供的低提早和抗弱网等能力能够保障很好的用户体验,所以是一个十分适合的抉择屏幕流渲染:能够应用Canvas或者Video来渲染播放,本篇文章中应用Video元素来渲染播放。一些筹备Windows 10零碎Chrome 93(留神本篇文章应用了Chrome提供的api来捕捉屏幕流,此api须要Chrome 72及以上版本)筹备一个html文件,编写另个video标签,一个用来播放本地捕捉的屏幕共享流,一个用来渲染播放远端传输过去的屏幕共享流 <div id="videos"> <div class="video-container"> <h2>本地捕捉的屏幕共享流</h2> <video id="srcVideo" playsinline controls muted loop class="srcVideo"> </video></div><div class="video-container"> <h2>远端传输过去的屏幕共享流渲染</h2> <video id="shareStreamVideo" playsinline autoplay muted class="shareStreamVideo"></video></div></div> 筹备一个js文件用来编写屏幕共享的逻辑,并且在之前筹备的html文件引入。屏幕流捕捉捕捉屏幕流能够应用navigator.mediaDevices.getDisplayMedia(displayMediaOptions)办法获取,此办法为异步办法,会将屏幕流包装成一个Promise对象,解析Promise后会返回一个MediaStream对象,咱们能够从这个对象中取出视频或者音频Track进行流传输。 const srcVideo = document.getElementById('srcVideo');const shareStreamVideo = document.getElementById('shareStreamVideo');let srcStream;let shareStream;// 定义捕捉流的参数let displayMediaOptions = { video: { width: {max: 1280}, height: {max: 720}, frameRate: {ideal: 15} }};navigator.mediaDevices.getDisplayMedia(option).then(stream => { srcStream = stream; srcVideo.srcObject = stream; srcVideo.play(); // 传输流 call();});`能够看到,捕捉流的时候可能设置不同的参数来获取可能满足咱们须要的流。这里咱们设置捕捉一个1280*720分辨率,15帧的屏幕流。 流传输与渲染在咱们进行流传输之前,先科普一个概念,针对屏幕共享流的传输,依据共享内容的不同,咱们个别会分为两个模式: 清晰度优先 针对一些动态文件的分享,比方PTT,笔记和一些展现文本为主的场景下实用此种模式。此种模式能够保障在网络状况不好的状况下,仍然不会升高分辨率,保障画面有一个比拟好的清晰度。但与此同时可能会升高帧率,导致看起来比拟卡顿。晦涩度优先 针对一些动静画面的分享,比方视频,动静网页等场景下实用于此模式。此种模式能够保障在网络状况不好的状况下,尽量保障共享画面不会呈现中断和卡顿,帧率也不会升高。但同时可能降低码率和分辨率,导致画面的清晰度无奈保障。 说到这里通知大家一个好消息,WebRTC曾经给咱们提供了设置这两种传输模式的形式,那就是通过MediaStreamTrack的contentHint属性设置,咱们来置一下 function setVideoTrackContentHints(stream, hint) { const track = stream.getVideoTracks()[0]; if ('contentHint' in track) { track.contentHint = hint; if (track.contentHint !== hint) { console.log('Invalid video track contentHint: \'' + hint + '\''); } } else { console.log('MediaStreamTrack contentHint attribute not supported'); }}function call() { // 克隆流 shareStream = srcStream.clone(); // "detail"设置清晰度优先(也可应用"text"),如果须要设置晦涩度优先,应用"motion" setVideoTrackContentHints(shareStream, 'detail'); // 建设PeerConnection establishPC(shareStreamVideo, shareStream);}接下来咱们创立PeerConnection,并且传输流。之后模仿接管流后去渲染。咱们这里会创立两个PeerConnection来模仿两个客户端。 ...

September 16, 2021 · 2 min · jiezi

关于webrtc:WebRTC网页录制音视频教程

导语:最近钻研了一下网页录制音视频的原理以及实现,当初就目前的实现办法做一个总结。目录相干API办法介绍实战演练相干API要实现这个性能就波及到两个js api。 getUserMediaMediaRecorder办法介绍getUserMedia通过getUserMedia这个接口来获取设施的摄像头和麦克风,返回一个Promise对象。 语法var stream = navigator.mediaDevices.getUserMedia(constraints); constraints包含一下几种写法: 申请音视频const constraints = { audio: true, video: true}申请特定的设施视频分辨率const constraints = { audio: true, video: { width: { min: 1280 }, height: { min: 720 } }}应用前摄像头(默认)const constraints = { audio: true, video: { facingMode: "user" }}强制应用后置摄像头const constraints = { audio: true, video: { facingMode: { exact: "environment" } }}例如: const constraints = { audio: true, video: { width: 1280, height: 720 }};async function createMedia() { try { let stream = await navigator.mediaDevices.getUserMedia(constraints); var video = document.querySelector('video'); video.srcObject = stream; video.onloadedmetadata = function (e) { video.play(); }; } catch (error) { console.log(`getUserMedia: ${error}`); }}createMedia();当然了这个stream还有一些办法能够应用,比方 ...

August 22, 2021 · 2 min · jiezi

关于webrtc:玩转-WebRTC-通信一文读懂-SDP-协议

简介在网络多媒体通话场景下,会议的参与者往往是用 SDP 协定来传递、协商媒体详细信息、网络地址和其余元数据。SDP 协定的全称是 session description protocol,含意是会话形容协定,它不是一种传输协定,而是由 ITEF 组织下的 MMusic 工作组设计的一种会话形容格局。 SDP 利用SDP 最罕用于 RTC 实时通话的协商过程,在 WebRTC 中,通信单方在连贯阶段应用 SDP 来协商后续传输过程中应用的音视频编解码器(codec)、主机候选地址、网络传输协定等。 在理论的利用过程中,通信单方能够应用 HTTP、WebSocket、DataChannel 等传输协定来互相传送 SDP 内容,这个过程称作 offer/answer 替换,也就是发起方发送 offer,接管方收到 offer 后回复一个 answer。例如在下图的服务端架构中,客户端将 offer 发送给信令服务器,信令服务器转发给媒体服务器,媒体服务器将 offer 和本身的能力进行比拟后失去 answer,信令服务器再将 answer转发给客户端,随后客户端和媒体服务器就能够进行 RTP 通信。 SDP 格局SDP 协定的设计能够参考 RFC4566 文档。它是一种具备非凡约定格局的纯文本形容文档,也就是它的内容都是由 UTF-8 编码的文本,有点相似于 JSON/XML。一个 SDP 会话形容包含若干行 type=value 模式的文本,其中 type 是一个辨别大小写的字母,例如 v、m 等,value 是一个结构化的文本,格局不固定。通常 value 由若干宰割符隔开的字段组成或者是一个字符串, 整个协定文本辨别大小写。"=" 两侧不容许有空格存在。 SDP 整体构造SDP 由一个会话级形容(session level description)和多个媒体级形容(media level description)组成。会话级形容的作用域是整个会话,在 SDP 中,从 "v=" 行开始到第一个 "m=" 行之前都是属于会话级形容的内容。媒体级形容对某个媒体流的内容进行形容,例如某个音频流或者某个视频流,从某个 "m=" 行开始到下个 "m=" 行之前是属于一个媒体级形容的内容。如下图所示: ...

July 29, 2021 · 6 min · jiezi

关于webrtc:玩转-WebRTC-安全通信一文读懂-DTLS-协议

在 WebRTC 中,为了保障媒体传输的安全性,引入了 DTLS 来对通信过程进行加密。DTLS 的作用、原理与 SSL/TLS 相似,都是为了使得本来不平安的通信过程变得平安。它们的区别点是 DTLS 实用于加密 UDP 通信过程,SSL/TLS 实用于加密 TCP 通信过程,正是因为应用的传输层协定不同,造成了它们实现下面的一些差别。 基本概念对称密钥加密技术对称密钥加密的含意是加密过程和解密过程应用的是同一个密钥。常见的对称加密算法有 DES、3DES、AES、Blowfish、IDEA、RC5、RC6。 非对称加密密钥加密技术非对称密钥加密的含意是加密过程和解密过程应用了不同的密钥,别离称为公开密钥和公有密钥。公钥是家喻户晓的,然而密钥只能为报文的指标主机所持有。相比对称加密技术,它的长处是不必放心密钥在通信过程中被别人窃取;毛病是解密速度慢,耗费更多的 CPU 资源。常见的非对称加密算法有 RSA、DSA、DH 等。 数字签名数字签名是附加在报文上的非凡加密校验码,即所谓的校验和,其中利用了非对称加密密钥加密技术。数字签名的次要作用是避免报文被篡改,一旦报文被攻击者篡改,通过将其与校验和进行匹配,能够立即被接收者发现。数字签名的过程如下图所示: 发送者 A 将报文摘要(报文通过 SHA-1 等哈希算法生成摘要)通过公有密钥加密生成签名,与明文报文一起发给接收者 B,接收者 B 能够通过对收到的信息进行计算后失去两份报文摘要,比拟这两份报文摘要是否相等能够验证报文是否被篡改: 明文报文通过应用与发送端雷同的哈希算法生成摘要 1;签名通过公开密钥解密后生成摘要 2。数字证书数字证书是由一些公认可信的证书颁发机构签发的,不易伪造。包含如下内容: 证书序列号证书签名算法证书颁发者有效期公开密钥证书签发机构的数字签名数字证书能够用于接收者验证对端的身份。接收者(例如浏览器)收到某个对端(例如 Web 服务器)的证书时,会对签名颁发机构的数字签名进行查看,一般来说,接收者当时就会事后装置很多罕用的签名颁发机构的证书(含有公开密钥),利用事后的公开密钥能够对签名进行验证。以 Google 为例,在浏览器中拜访 Google 首页,点击左上角的感叹号就能够看到 Google 证书的残缺信息,包含以上提到的所有内容:参考资料https://zhangbuhuai.com/post/... SSL/TLS 协定简介要理解 DTLS,首先从咱们比拟相熟的 SSL/TLS 开始讲起。SSL(Secure Socket Layer) 和 TLS(Transport Layer Security) 简略了解就是同一件货色的两个演进阶段,同样都是在应用层和传输层之间退出的平安层,最早的时候这个平安层叫做 SSL,由 Netscape 公司推出,起初被 IETF 组织标准化并称之为 TLS。SSL/TLS 的作用是为了解决互联网通信中存在的三种危险: 窃听危险:第三方能够获知通信内容;篡改危险:第三方能够批改通信内容;假冒危险:第三方能够假冒别人身份参加通信。SSL/TLS 协定可能做到以下这几点,从而解决上述的三种危险: 所有信息通过加密流传,第三方无奈窃听;具备数据签名及校验机制,一旦被篡改,通信单方立即能够发现;具备身份证书,避免其他人假冒。协定栈SSL/TLS 建设在 TCP 传输层上,最常应用 SSL/TLS 的场景是在 HTTPS 中,通过在 HTTP 和 TCP 中加了一层 SSL/TLS,使得不平安的 HTTP 成为了平安的 HTTPS。协定栈如下图所示: ...

July 28, 2021 · 5 min · jiezi

关于webrtc:实践解析-如何通过-WebAssembly-在-Web-进行实时视频人像分割

5 月 15 日,声网Agora 高级架构师高纯加入了 WebAssambly 社区举办的第一场线下流动“WebAssembly Meetup”,并围绕声网Agora 在 Web 实时视频人像宰割技术的利用落地,分享了实践经验。以下为演讲分享整顿。 RTC 行业在近几年的倒退突飞猛进,在线教育、视频会议等场景凋敝蓬勃。场景的倒退也给技术提出了更高的要求。于是,机器学习越来越多地利用到了实时音视频场景中,比方超分辨率、美颜、实时美声等。这些利用在 Web 端也存在同样的需要,同时也是所有音视频开发者面对的挑战。所幸 WebAssembly 技术为 Web 高性能计算提供了可能。咱们首先围绕 Web 端的人像宰割利用进行了摸索实际。 视频人像宰割都用在什么场景?提到人像宰割,咱们首先想到的利用场景,就是在影视制作中的绿幕抠图。在绿幕环境下拍摄视频后,通过后期制作,将背景替换成电脑合成的电影场景。 另一种利用场景大家应该都见过。在 B 站上,你会发现有些视频的弹幕不会遮挡画面上的人物,文字会从人像的前面穿过。这也是基于人像宰割技术。 以上列举的人像宰割技术都是在服务端实现的,而且不是实时音视频场景。 而咱们声网做的人像宰割技术实用于视频会议、在线教学等实时音视频场景。咱们能够通过人像宰割技术,能够对视频的背景进行含糊解决,或替换视频背景。 [⏸️点击查看视频] 为什么这些实时场景须要这项技术呢? 最近的一项钻研发现,在均匀 38 分钟的电话会议中,有整整 13 分钟的工夫被节约在解决烦扰和中断上。从在线面试、演讲和员工培训课程到集思广益、销售推介、IT 帮助、客户反对和 网络研讨会,所有这些状况都面临同样的问题。因而,应用背景含糊或从自定义和预设的许多虚构背景选项中抉择一个,能够大大减少烦扰。 还有一项考察显示,有 23% 的美国员工示意视频会议让他们感到不难受;75% 的人示意他们依然更喜爱语音会议,而不是视频会议。这是因为人们不心愿将本人的寓居环境、隐衷裸露在公众视线中。那么通过替换视频背景,就能够解决这个问题。 目前,实时音视频场景下的人像宰割、虚构背景,大多是运行在原生客户端上的。只有 Google Meet 利用 WebAssembly 实现过在 Web 实时视频中的人像宰割。声网的实现是联合机器学习、WebAssembly、WebGL 等技术实现的。 Web 实时视频虚构背景的实现人像宰割的技术组件和实时处理流程 在做 Web 的人像宰割时,咱们还会须要用到这些组件: WebRTC:做音视频的采集和传输。TensorFlow:作为人像宰割模型的框架。WebAssembly:做人像宰割算法的实现。WebGL:GLSL 实现图像处理算法,来解决人像宰割后的图像。Canvas: 最终渲染视频和图像后果。Agora Web SDK:进行实时的音视频传输。人像宰割的实时处理流程是这样的。首先会利用 W3C 的 MediaStream 的 API 进行采集。而后数据会交给 WebAssembly 的引擎去进行预测。因为机器学习的运算开销较大,这就要求输出的数据不能太大,所以须要在输出到机器学习框架前对视频图像做一些缩放的解决或归一化。运算后果从 WebAssembly 输入后还要进行一些后处理,而后再传递给 WebGL。WebGL 会通过这些信息与原始视频信息来做滤波、叠加等解决,最初生成出的后果。这些后果会到 Canvas 上,而后通过 Agora Web SDK 来进行实时传输。 ...

July 23, 2021 · 2 min · jiezi

关于webrtc:基于kurento-webRTC构建一个直播系统demo

webrtc-mcu一个基于kurento & webRTC构建的直播零碎demo借鉴了kurento one2many示例KMS作为offer,用户作为viewer。通过游览器上的kurento util调用node端的kurento client,实现对KMS API的调用,在KMS中构建一条媒体管线。每退出一个viewe便在媒体管线中构建一个由playerEndpoint + WebrtcEndpoint组成的端点。目前能够将本地视频文件和m3u8直播流作为直播内容。应用办法在ubuntu上部署KMS装置node.js运行sudo npm install 留神在ubuntu上,"postinstall": "cd static && bower install" 要写为 "postinstall": "cd static && bower install --allow-root" 参考资料Kurento Tutorials Node.js - One to many video callhttps://doc-kurento.readthedo...JavaScript Kurento Client https://doc-kurento-zh-cn.rea...http://www.voidcn.com/article...kurento_utils_js https://doc-kurento.readthedo...How to ues coturn https://doc-kurento.readthedo...中文教程 比拟残缺的中文文档 https://blog.gmem.cc/webrtc-s...Kurento Utils JS http://www.voidcn.com/article...https://my.oschina.net/997155...chrome webrtc查看工具 chrome://webrtc-internals/WebRTC和相干技术 Learning WebRTChttps://cloud.tencent.com/dev...P2P ICE https://evilpan.com/2015/12/2...https://cnodejs.org/topic/547...https://www.liangzl.com/get-a...P2P技术之STUN、TURN、ICE详解 http://www.52im.net/thread-55...拓展 - WebRTC 多视频网络拓扑之三种架构 https://www.cnblogs.com/baito...SDP https://www.jianshu.com/p/94b...

July 18, 2021 · 1 min · jiezi

关于webrtc:未来可期WebRTC成为实时通讯方案的行业标准

2011年Google将WebRTC我的项目开源。作为Google开源的技术标准,而WebRTC技术并不是一个能够拿来就用,并且性能很好的产品。本文次要来谈一谈WebRTC的优缺点。倒退及现状WebRTC技术在被Google开源之前,技术就曾经被国内很多厂商所应用和青眼。例如,QQ就应用了WebRTC的局部技术。。WebRTC的倒退状况能够从标准规范和浏览器反对这两个方面看。 WebRTC规范是由W3C和IETF所联结制订 在2016年1月28日,W3C颁布了最新的WebRTC规范,规范中定义了WebIDL中一系列的ECMAScript API来容许应用适合的RTP的浏览器或设施来接管/发送媒体。WebRTC对于浏览器的实现现状 从2010年左右,实时通信只能应用专有软件、插件或 Adobe Flash 进行实时通信;2013年,Chrome和Firefox间进行了首次跨浏览器视频通话2014年,第一次跨浏览器数据传输得以实现,通过客户端进行实时通信,它被称为WebRTC,现在,咱们每天都在Chrome,Mozilla Firefox,Opera,Safari,Edge,iOS 和 Android 的实时互动场景中应用它。长处【开发/使用方便】:在WebRTC呈现之前想要进行实时通信就须要装置插件和客户端,这是一个简单的过程。 当初,WebRTC技术内置于浏览器中,用户不须要应用任何插件或者软件就能通过浏览器来实现实时通信。对于开发者来说,在Google将WebRTC开源之前,浏览器之间实现通信的技术开发是一个很艰难的工作,当初开发者应用简略的HTML标签和JavaScript API就可能实现Web音/视频通信的性能。【应用收费】:WebRTC技术曾经较为成熟,其集成了最佳的音/视频引擎,非常先进的codec,然而Google对于这些技术不收取任何费用。【弱小的打洞能力】:WebRTC技术蕴含了应用STUN、ICE、TURN、RTP-over-TCP的要害NAT和防火墙穿透技术,并反对代理。毛病【编译WebRTC简单过高】:编译WebRTC的源码就是一个比拟大的挑战,搭建其简单的编译环境往往会遇到很多意想不到的问题。【不稳固因素过多】:WebRTC技术中很多的参数都是由GIPS公司的工程师们依附教训所设定的值,这就会呈现卡顿、延时、回声、丢包、多人视频不稳固等问题。【设计和部署计划过少】WebRTC技术不足服务器计划的设计和部署。【传输品质难以保障】:WebRTC的传输设计基于P2P,难以保障传输品质,优化伎俩也无限,只能做一些端到端的优化,难以应答简单的互联网环境。 比方对跨地区、跨运营商、低带宽、高丢包等场景下的传输品质根本是靠天吃饭,而这恰好是国内互联网利用的典型场景。【群聊机制待优化】:WebRTC比拟适宜一对一的单聊,尽管性能上能够扩大实现群聊,然而没有针对群聊,特地是超大群聊进行任何优化。【设施端适配问题】如回声、录音失败等问题层出不穷。这一点在安卓设施上尤为突出。因为安卓设施厂商泛滥,每个厂商都会在规范的安卓框架上进行定制化,导致很多可用性问题(拜访麦克风失败)和品质问题(如回声、啸叫)。【对Native开发反对不够】:WebRTC顾名思义,次要面向Web利用,尽管也能够用于Native开发,然而因为波及到的畛域常识(音视频采集、解决、编解码、实时传输等)较多,整个框架设计比较复杂,API粒度也比拟细,导致连工程项目的编译都不是一件容易的事。总而言之WebRTC尽管提供了一套音视频实时通信的解决方案,然而在理论利用中,因为网络传输、设施适配以及多方通话上都存在很多问题,成果并不现实。技术实现Web实时通信(WebRTC)是规范,协定和JavaScript API的汇合,两者的组合可实现浏览器(对等)之间的对等音频,视频和数据共享。WebRTC无需依赖第三方插件或专有软件,而是将实时通信转变为任何Web应用程序都能够通过简略的JavaScript API加以利用的规范性能。例如,音频和视频电话会议以及对等数据交换,须要在浏览器中提供许多新性能:音频和视频解决性能,新的应用程序API,以及对六种新性能的反对。网络协议浏览器将这种复杂性的大部分从三个次要API中形象进去:MediaStream:获取音频和视频流RTCPeerConnection:音频和视频数据的通信RTCDataChannel:任意应用程序数据的通信它只须要十几行JavaScript代码,任何Web应用程序都能够通过对等数据传输实现丰盛的电话会议体验。这就是WebRTC的承诺和力量!然而,列出的API只是冰山一角:信令,对等设施发现,连贯协商,安全性以及新协定的整个层只是将它们整合在一起的一些组件。实际上,与所有其余浏览器通信不同,WebRTC通过UDP传输其数据。然而,UDP只是一个终点。要使浏览器中的实时通信成为事实,它须要破费比原始UDP多得多的费用。让咱们认真看看。 最新的Chrome和Firefox浏览器为所有用户提供WebRTC反对!话虽这么说,WebRTC也在浏览器API级别以及传输和协定级别上都在踊跃构建中。因而,将来几章中探讨的特定API和协定可能仍会更改 总结随着挪动互联网的、AI、5G等等新兴技术的高速倒退,联合WebRTC技术,将来将衍生出更多的利用场景,扭转人类的衣、食、住、行等生存形式。

June 2, 2021 · 1 min · jiezi

关于webrtc:详解-WebRTC-高音质低延时的背后-AGC自动增益控制

后面咱们介绍了 WebRTC 音频 3A 中的声学回声打消(AEC:Acoustic Echo Cancellation)的基本原理与优化方向,这一章咱们接着聊另外一个 "A" -- 自动增益管制(AGC:Auto Gain Control)。本文将联合实例全面解析 WebRTC AGC 的根本框架,一起摸索其基本原理、模式的差别、存在的问题以及优化方向。作者|珞神 审校|泰一 前言自动增益管制(AGC:Auto Gain Control)是我认为链路最长,最影响音质和主观听感的音频算法模块,一方面是 AGC 必须作用于发送端来应答挪动端与 PC 端多样的采集设施,另一方面 AGC 也常被作为压限器作用于接收端,平衡混音信号避免爆音。设施的多样性最间接的体现就是音频采集的差别,个别体现为音量过大导致爆音,采集音量过小对端听起来很吃力。 在音视频通话的事实场景中,不同的参会人谈话音量各有不同,参会用户须要频繁的调整播放音量来满足听感的须要,戴耳机的用户随时接受着大音量对耳朵的 “暴击”。因而,对发送端音量的平衡在上述场景中显得尤为重要,优良的自动增益控制算法可能对立音频音量大小,极大地缓解了由设施采集差别、谈话人音量大小、间隔远近等因素导致的音量的差别。 AGC 在 WebRTC 中的地位在讲 AGC 音频流解决框架之前,咱们先看看 AGC 在音视频实时通信中的地位,如图 1 展现了同一设施作为发送端音频数据从采集到编码,以及作为接收端音频数据从解码到播放的过程。AGC 在发送端作为均衡器和压限器调整推流音量,在接收端仅作为压限器避免混音之后播放的音频数据爆音,实践上推流端 AGC 做的足够鲁棒之后,拉流端仅作为压限器是足够的,有的厂家为了进一步减小混音之后不同人声的音量差别也会再做一次 AGC。 图 1 WebRTC 中音频信号上下行解决流程框图 AGC 的外围参数先科普一下样本点幅度值 Sample 与分贝 dB 之间的关系,以 16bit 量化的音频采样点为例:dB = 20 * log10(Sample / 32768.0),与 Adobe Audition 右侧纵坐标刻度统一。幅度值示意:16bit 采样最小值为 0,最大值绝对值为 32768(幅度值如下图左边栏纵坐标)。 分贝示意:最大值为 0 分贝(分贝值如下图左边栏纵坐标),个别音量达到 -3dB 曾经比拟大了,3 也常常设置为 AGC 指标音量。 ...

May 27, 2021 · 5 min · jiezi

关于webrtc:Why-WebRTC|前世今生

作者:声网 WebRTC 团队 前言近几年实时音视频通信利用呈现出了大暴发的趋势。在这些实时通信技术的背地,有一项不得不提的技术——WebRTC。 往年 1 月,WebRTC 被 W3C 和 IETF 公布为正式规范。据调研机构 GrandViewReseach 的报告显示,预计 2025 年寰球 WebRTC 市场规模将达到 210.23 亿美元,相较 2019 年 23 亿美元的市场规模,5 年的复合年增长率为 43.6%。 本系列内容将和大家一起来探讨,为什么 WebRTC 受到开发者及企业的青眼 ?将来 WebRTC 又将如何倒退?以及声网Agora 是怎么基于 WebRTC 进行二次开发,又将如何反对 WebRTC NV 版本的? 在线会议、在线教育、在线面试、在线社交、在线医疗、金融证券在线开户、智能家居等等曾经成为了古代人们生存中十分相熟的一部分,将常见的线下场景转至线上,人们足不出户便能体验上述场景。这些实时互动场景在很大水平上曾经扭转了咱们本来的生存形式。 如果咱们将工夫倒回到 10 年前,也就是在 4G 行将商用的时候,简直所有的媒体和技术都在强调 4G 能够看高清视频,但少数都聚焦在探讨手机看视频有如许的不便,没有人预测到短视频的彻底暴发;少数人都晓得 4G 的上传速度能够视频直播了,但过后的构想更多的是利用于业余的新闻畛域,没有想到这个全民皆可直播的时代的降临;对于视频会议的构想也大多停留在跨国办公的需要上,但没想到就在去年,线上办公简直成为了每一位上班族的日常。 在这十年间,实时互动场景的日常化又是如何一步一步实现的呢? 从 2010 年左右,实时通信只能应用专有软件、插件或Adobe Flash进行实时通信;2013年,Chrome 和 Firefox 之间进行了首次跨浏览器视频通话;2014年,第一次跨浏览器数据传输得以实现,通过客户端进行实时通信关上了一个新兴的趋势......而明天,它被称为WebRTC,咱们每天都在 Chrome,Mozilla Firefox,Opera,Safari,Edge,iOS 和 Android 的实时互动场景中应用它。 什么是 WebRTCWebRTC 是一个由 Google、Mozilla、Opera 等发动的开源我的项目,名称源自网页即时通信(Web Real-Time Communication)的缩写。因而,不难看出这项技术最开始的指标是心愿为实现自在地在浏览器上进行实时音视频传输做筹备的。 “其实 WebRTC 在不同场景下蕴含不同的含意,它既能够代表 Google 开源的 WebRTC 我的项目,又能够代表 W3C(World Wide Web Consortium-万维网联盟) 工作组制订的 WebRTC 规范,也能够代表浏览器中的 WebRTC 接口,咱们将他们统称为 WebRTC 技术。”【1】少数时候,对于开发者而言 WebRTC 是一套反对网页浏览器进行实时音视频对话的 W3C Javascript API,它包含了音视频的采集、编解码、网络传输、显示等性能。 ...

May 19, 2021 · 2 min · jiezi

关于webrtc:上手-WebRTC-DTLS-遇到很多-BUG浅谈-DTLS-Fragment

上一篇《详解 WebRTC 传输平安机制:一文读懂 DTLS 协定》具体论述了 DTLS。本文将联合 DTLS 开发中遇到的问题,具体解读 DTLS 的一些根底概念以及 Fragment 的机制,并进一步深究 DTLS 协定。作者|泰一 审校|进学、莫战 前言最近在做 J 和 G 这两套 RTC 零碎的 DTLS-SRTP 握手加密工作,要求应用 CA 机构颁发的证书。在本机调试的过程中发现:G 零碎应用 CA 证书,DTLS 握手胜利,而 J 零碎则握手失败。 通过几番调试与剖析,定位到了起因:J 零碎相较于 G 零碎多了一个 TURN 转发模块,该模块设置的接收缓冲区的上限值为 1600 字节,而 CA 证书的大小则有近 3000 字节,因而 TURN 模块转发给客户端的证书不残缺,导致 DTLS 握手失败。 大家都晓得, WebRTC 的 DTLS 应用的是自签名的证书,这个证书个别不会太大,如下图所示,只有 286 字节。 然而,如果要应用 CA 颁发的证书,那么这个证书可能会很大,如下图所示,竟达到了 2772 字节,显然超出了 TURN 模块的接收缓冲区的大小。 上图中,你可能留神到了这个 CA 证书被分成了两片(two fragments),这其实是 DTLS 协定层做的。不过值得思考的是,CA 证书的每一片的大小都未超出 TURN 模块接收缓冲区的 1600 字节的限度,然而为什么 J 零碎的 TURN 转发模块仍然会接管失败呢? ...

May 17, 2021 · 3 min · jiezi

关于webrtc:详解-WebRTC-传输安全机制一文读懂-DTLS-协议

作者|进学 审校|泰一 DTLS (Datagram Transport Layer Security) 基于 UDP 场景下数据包可能失落或从新排序的现实情况下,为 UDP 定制和改良的 TLS 协定。在 WebRTC 中应用 DTLS 的中央包含两局部:协商和治理 [SRTP]() 密钥和为 [DataChannel]() 提供加密通道。 本文结合实际数据包剖析 WebRTC 应用 DTLS 进行 SRTP 密钥协商的流程。并对在理论我的项目中应用 DTLS 遇到的问题进行总结。 DTLS 协定简介在剖析 DTLS 在 WebRTC 中的利用之前,先介绍下 DTLS 协定的基本原理。DTLS 协定由两层组成: Record 协定 和 Handshake 协定 Record 协定:应用对称密钥对传输数据进行加密,并应用 HMAC 对数据进行完整性校验,实现了数据的平安传输。Handshake 协定:应用非对称加密算法,实现 Record 协定应用的对称密钥的协商。 HandShakeTLS 握手协定流程如下,参考 RFC5246 DTLS 握手协定流程如下,参考 RFC6347 TLS 和 DTLS 的握手过程基本上是统一的,差异以及特地阐明如下: DTLS 中 HelloVerifyRequest 是为避免 DoS 攻打减少的音讯。TLS 没有发送 CertificateRequest,这个也不是必须的,是反向验证即服务器验证客户端。DTLS 的 RecordLayer 新增了 SequenceNumber 和 Epoch,以及 ClientHello 中新增了 Cookie,以及 Handshake 中新增了 Fragment 信息(避免超过 UDP 的 MTU),都是为了适应 UDP 的丢包以及容易被攻打做的改良。参考 RFC 6347DTLS 最初的 Alert 是将客户端的 Encrypted Alert 音讯,解密之后间接响应给客户端的,实际上 Server 应该回应加密的音讯,这里咱们的服务器回应明文是为了解析客户端加密的那个 Alert 包是什么。RecordLayer 协定是和 DTLS 传输相干的协定,UDP 之上是 RecordLayer,RecordLayer 之上是 Handshake 或 ChangeCipherSpec 或 ApplicationData。RecordLayer 协定定义参考 RFC4347,实际上有三种 RecordLayer 的包: ...

May 8, 2021 · 5 min · jiezi

关于webrtc:资讯|WebRTC-M90-更新

WebRTC M90 目前已在 Chrome 测试版中公布,蕴含 2 个新个性和超过 29 个 bug 修复,以及性能加强、稳定性与性能等方面的改良。 欢送关注本账号,咱们将定期翻译 WebRTC 相干内容,帮忙开发者取得最新资讯,走在行业前沿。 01. 公共服务布告Plan B SDP 弃用 揭示:Plan B SDP 已被弃用,未来会被彻底删除。 工夫线见:https://groups.google.com/g/discuss-w 02.性能MediaStreamTrack Insertable Streams 源试用版该 API 是 MediaStream 和 WebCodecs API 的扩大,容许应用程序: 拜访 MediaStreamTrack 中的原始数据;定义新的自定义 MediaStreamTracks。这两个性能能够组合应用,例如创立媒体特效(比方:"funny hats")。 该 API 依赖于 WebCodecs raw media interfaces 以及 WHATWG Streams API。该个性是 WebCodecs 源试用版的一部分。 getCurrentBrowsingContextMedia 源试用版这是一个用于获取以后 Tab 内容的新的试验性 API,目前正在开发中。第一次实现能够作为试用版应用,更多信息见:https://docs.google.com/document/d/1CIQH2ygvw7eTGO__Pcds_D46Gcn-iPAqESQqOsHHfkI/edit 03.性能及问题修复可登陆:https://bugs.chromium.org/p/webrtc/issues/list 输出问题 ID 即可查问 bug 详情。  No.1 类型:Bug问题 ID:1138888    形容:WebRTC 低提早渲染器  组件:Blink>WebRTC>VideoNo.2类型:Bug问题 ID:1155477形容:AEC3:线性滤波器会在长时间通话中逐步发散 组件:Blink>WebRTC>AudioNo.3类型:Bug问题 ID:1170699形容:WebRTC 的 AV1 编码初始化失败组件:Blink>WebRTCNo.4类型:Feature问题 ID:516700形容:WebRTC Chromium 时钟差组件:Blink>WebRTCNo.5类型:Bug问题 ID:10675形容:反对以 text2pcap 格局记录原始 rtp组件:Network>RTPNo.6类型:Bug问题 ID:11031形容:MID 协商实现后,重传可能会失败 [Unified Plan]组件:Network>RTPNo.7类型:Feature问题 ID:11989形容:为VoIP APIs提供VoipStatistics接口用于媒体统计组件:AudioNo.8类型:Bug问题 ID:12265形容:AEC3: 线性滤波器会在长时间通话中逐步发散组件:AudioNo.9类型:Bug问题 ID:12279形容:(network.cc:908): 每 2 秒呈现 10051 连贯失败组件:PeerConnection,ToolsNo.10类型:Bug问题 ID:12380形容:当接管 Opus 流时,每次刷新 DTX 包舒服乐音会忽然扭转能量值组件:AudioNo.11类型:Bug问题 ID:12383形容:收集 bundle 应用的统计信息 No.12类型:Bug问题 ID:12384形容:Windows 客户端上每次音频通话 Registry-Key-MMDevices-Audio-Handles 都会减少组件:AudioNo.13类型:Bug问题 ID:12398形容:应用svc并且宽/高的值为奇数时,AV1编码器呈现seg谬误组件:Video  No.14类型:Bug问题 ID:12407形容:SEA 为静止图层创立并初始化编码器组件:VideoNo.15类型:Bug问题 ID:12426形容:多线程拜访 JsepTransport::jsep_transports_by_name_时未作爱护No.16类型:Bug问题 ID:12427形容:PeerConnetion 不同线程之间编排 JsepTransportController 事件No.17类型:Bug问题 ID:12430形容:RtpBitrateConfigurator 的 TSAN 上报No.18类型:Bug问题 ID:12431形容:RTC 事件日志可视化在 Python3 环境下不失效组件:ToolsNo.19类型:Feature问题 ID:12432形容:在 RTC 事件日志中可视化 RTCP BYE 音讯组件:ToolsNo.20类型:Bug问题 ID:12439形容:如果零碎工夫回退,传统 getStats 将进行工作组件:StatsNo.21类型:Bug问题 ID:12445形容: JsepTransportController::mid_to_transport_未作爱护No.22类型:Bug问题 ID:12448形容:ULPFEC:达到程序异样以及达到提早过久组件:VideoNo.23类型:Bug问题 ID:12455形容:  webrtc::AudioSendStream::Config::ToString() 在 M90 版本调用失败组件:AudioNo.24类型:Feature问题 ID:12459形容:限度最大图层数时,容许裁剪分辨率组件:VideoNo.25类型:Bug问题 ID:12487形容:实现视频 RTP 流的抖动数据统计  原文链接:https://groups.google.com/g/discuss-webrtc/c/8VgEFxD_S80/m/C6e_utBTAAAJ ...

April 28, 2021 · 1 min · jiezi

关于webrtc:Windows7下载编译webrtc

Windows7下载编译webrtc一、前提最重要的是应用稳固的FQ工具,下载中遇到的大部分谬误都是因为网络不稳固导致下载失败 二、下载代码1、下载安装VS2017,装置时抉择VC++,Win10SDK; 2、装置depot_tools,地址https://storage.googleapis.co... 3、设置环境变量Path中增加depot_tools门路,重启cmd并设置代理; 4、执行gclient下载依赖库; 5、下载win10SDK,实现后设置环境变量,如:WINDOWSSDKDIR=D:\Windows Kits\10; 6、批改零碎区域语言为英语,控制面板->时钟、语言和区域->区域->治理(选项卡)->更改零碎区域设置; 并重启; 7、设置环境变量 set DEPOT_TOOLS_WIN_TOOLCHAIN=0 set GYP_MSVS_VERSION=2017 当前每次编译时都要设置这两个环境变量。 8、mkdir webrtc cd webrtc fetch --nohooks webrtc (需期待较长时间) 办法一: gclient sync -r 275e7061c770d35903137094efa136eea64156c6(需期待相当长的工夫) -r后为具体版本 办法二: git branch -r 查看所有分支 git checkout branch-heads/61 切换到该分支 gclient sync 版本获取:进入https://webrtc.org/release-no... 9、如果下面命令没有出错,阐明曾经下载实现; 三、编译1、Ninja编译a、生成工程 gn gen out/x86/Debug --args="is_debug=true rtc_include_tests=false target_cpu=\"x86\" use_custom_libcxx=false" gn gen out/x86/Release --args="is_debug=false rtc_include_tests=false target_cpu=\"x86\" symbol_level=0 enable_nacl=false use_custom_libcxx=false" gn gen out/x64/Debug --args="is_debug=true rtc_include_tests=false target_cpu=\"x64\" use_custom_libcxx=false" gn gen out/x64/Release --args="is_debug=false rtc_include_tests=false target_cpu=\"x64\" symbol_level=0 enable_nacl=false use_custom_libcxx=false" ...

April 28, 2021 · 1 min · jiezi

关于webrtc:如何用-Electron-WebRTC-开发一个跨平台的视频会议应用

在搭建在线教育、医疗、视频会议等场景时,很多中小型公司经常面临 PC 客户端和 Web 端二选一的抉择。Electron 技术的呈现解决了这一难题,只需前端开发就能实现一个跨平台的 PC 端利用。本文次要介绍应用 Electron + WebRTC 搭建跨平台的视频会议利用的技术计划。作者| 峻崎 审校| 泰一 什么是 Electron?Electron 是应用 JavaScript、Html 和 CSS 构建跨平台的桌面应用程序。(官网链接) 为什么要应用 Electron?目前很多中小型公司并不具备 pc 端上的开发能力,广泛只有挪动端开发团队 + 前端开发团队。而在浏览器中应用音视频会议的限度又十分多。所以如何可能低成本,疾速开发一个 pc 端的利用,就成了很多中小型公司的需要。而 Electron 只须要前端开发就能实现一个跨平台的 pc 端利用。前端开发能够把原有的页面迅速移植到 electron 程序中,甚至能够间接在 Electron 中间接加载网页。 Electron 的架构首先 Electron 外面蕴含了一个 chromium,而 chromium 的架构能够简略了解为: 因而,Electron 的架构就能够简略了解为: Electron 反对平台MacOS对 macOS 提供 64 位版本,并且只反对 macOS 10.10 (Yosemite) 以及更高版本。 Windows仅反对 Windows 7 或更高版本为 Windows 零碎提供 ia32 (x86) 和 x64 (amd64) 两种二进制版本。 ...

April 15, 2021 · 2 min · jiezi

关于webrtc:阿里云-RTC-QoS-屏幕共享弱网优化之若干编码器相关优化

屏幕共享是视频会议中应用频率最高的性能之一,但在理论场景中用户所处网络环境简单,常遇到丢包或者拥塞的状况,所以如何优化弱网环境下的用户体验也成为了音视频通信中重要的一环。本文次要分享阿里云 RTC QoS 如何通过若干编码器相干优化晋升弱网环境下的屏幕共享体验。 作者:长程/田伟峰审校:泰一 内容阐明:本文介绍以下四个方面的优化: Screen Content Coding ToolsLong Term Reference (LTR)Fast QP Rate ControlContent Adaptive Frame Rate对本文中成果测试的阐明: 为保障视频品质,屏幕共享的 Codec 设置了最大 QP (Quantization Parameter),在本文前面的测试中,这个最大 QP 对所有配置都是一样的。为了更好的比拟,成果测试中展现了流畅性和清晰度两个维度的成果。对于流畅性的比拟,因为视频分辨率太大,所以对其画面进行了缩放,使得原始版本和改良版本能够放在同一个视线中播放,以很好的看到卡顿和提早的改良。画面含糊是因为上述起因降分辨率所致,在清晰度的比照中能够看到原始分辨率的画面。Screen Content Coding ToolsCodec 中减少并改良了对于屏幕内容(其内容多为如 Word、Excel、PPT 等计算机生成的图形,文字等,具备反复纹理多,色调散布较离散,无噪声等特点)特地适宜的 Coding Tools 如 Intra Block Copy (Current Picture Reference),Transform Skip 等,显著晋升了屏幕内容的压缩效率,能够做到绝对于原 Codec,对于屏幕内容视频雷同品质下均匀能够节俭带宽 20%+,编码工夫只减少 10%,对某些典型序列场景带宽能够节俭 40%+,因为是非规范的 Coding Tools,理论应用中会依据 SDP 协商,当所有与会方都反对该个性时才会开启。 SCC Tools 成果流畅性成果测试 SCC Tools 在弱网下的改良成果。 上图中,上半局部是减少了 Screen Content Coding Tools 编码进去的码流,下半局部是原始 Codec 编出的码流,能够看出应用 Screen Content Coding Tools 之后卡顿和提早明显降低了。 ...

January 20, 2021 · 2 min · jiezi

关于webrtc:WebRTC-ICE-状态与提名处理

大家都晓得奥斯卡有提名,其实在 WebRTC 的 ICE 中也有提名,有惯例的提名,也有激进的提名,而且提名的候选人不肯定是最优良的候选人喔,本文就带你一探其中玄妙。文章内容次要形容 RFC 5245 中 ICE 相干的状态和 ICE 提名机制,并联合 libnice(0.14) 版本进行剖析。 作者:阵图,阿里云开发工程师审校:泰一,阿里云高级开发工程师 Scene剖析一个问题时候遇到这样的场景:服务端一个 Candidate,客户端三个不同优先级的 Candidate,然而最初竟然抉择了一个优先级最低的 Pair。 服务端有一个 Relay Candidate,端口 50217。 a=candidate:3 1 udp 503316991 11.135.171.187 50217 typ relay raddr 10.101.107.25 rport 40821 客户端有三个 Candidate,端口 50218(两头优先级),50219(最低优先级),50220(最高优先级)。 Candidate 1:candidate:592388294 1 udp 47563391 11.135.171.187 50219 typ relay raddr 0.0.0.0 rport 0 generation 0 ufrag fO75 network-cost 50Candidate 2:candidate:592388294 1 udp 48562623 11.135.171.187 50218 typ relay raddr 0.0.0.0 rport 0 generation 0 ufrag fO75 network-cost 50Candidate 3:candidate:592388294 1 udp 49562879 11.135.171.187 50220 typ relay raddr 0.0.0.0 rport 0 generation 0 ufrag fO75 network-cost 50然而最初抉择的却是最低优先级的 Pair,50219。 ...

January 13, 2021 · 3 min · jiezi

关于webrtc:lightrtc-理念与实践

在与同行交换过程中,发现很多同行对 WebRTC 改变太多,导致无奈降级 WebRTC 版本。而 WebRTC 开源社区的疾速迭代,让他们感到欣慰又焦虑:开源社区的迭代成果,是不是超过了他们对 WebRTC 的优化成果?咱们针对特定场景优化 WebRTC 时,怎么紧跟 WebRTC 开源社区通用的优化? 作者:阿里云智能技术专家 熊金水 理念简言之,把 WebRTC 作为 Framework 应用,而不是 Library,即:WebRTC 仓库轻量化,外围模块插件化。 具体的,WebRTC 作为 Framework 串联外围模块;外围模块既能够以插件模式应用咱们的实现,也能够 Fallback 到 WebRTC 的默认实现。目标是缩小 WebRTC 抵触的可能性,进步降级 WebRTC 的敏捷性。 指标:一年降级一次 WebRTC,一次破费一个人月。 架构模块拆解WebRTC 的外围模块,包含: 音频ADM 采集、APM、ACM 编码;NetEQ 与解码、AM、ADM 渲染;视频采集、编码;JB、解码、渲染;通用RTP 打包与解包、FEC 生成与复原、CC 与 Pacer、ICE、SDP 信令等。WebRTC 在长期的演进中,API 曾经具备了作为 Framework 的大部分能力。红色的外围模块,曾经根本能够插件化,如上面的 API: 仓库治理light-rtc 作为 WebRTC 仓库,咱们须要保留两个 Remote,一个是 Alibaba,一个是 Google。降级 WebRTC 时,咱们从 Google 上 Pull 最新代码, 解决抵触,而后 Push 到 Alibaba。 ...

January 4, 2021 · 2 min · jiezi

关于webrtc:实战排查|为什么遮挡推流摄像头会导致播放绿屏

前言:做音视频的小伙伴们多少都遇到过奇怪的BUG(如:卡顿、花屏、绿屏、变声等),表象上矛盾点颇多,推理得出的论断都是:“不应该啊!”,最终你抽丝剥茧,发现假相只有一个:“事出反常必有妖”! 作者:安果,阿里云高级技术专家,从事阿里云 RTC 服务器研发 奇怪景象背景:RTC 互动中减少对 RTMP 的反对,实现 RTC 与 RTMP 互相订阅。 遇到一个奇怪的 BUG,遮挡住 RTC 端的摄像头,有的 RTMP 播放端(iPad air 2,iPad mini 2/4)会偶发绿屏。 要不先发版?初步剖析问题后,咱们认为这是:一个偶发的终端兼容性问题,有很大概率须要批改 RTC 端的编码来适配,耗时不好评估。 “间隔发版本的工夫不到 2 周,要不就先发版本吧?” 这个申请被产品有情的回绝了(这次真的感激你们的保持),测试也反馈了新的状况:iPhone 6 也呈现了绿屏,敞开 RTC 端的摄像头也可能绿屏,Mac 摄像头对着红色墙面也可能绿屏(测试的同学们也太能折腾了),同时确认了 RTMP 编码 RTMP 播放时雷同场景不绿屏。 编码还是封装的坑?疑难杂症先会诊,同编解码的同学一起探讨完后确认两个可能的点: 1.编码的 264 码流不兼容。2.封装发送的 RTMP 数据不兼容。 咱们制订了后续的排查计划: 1.录制 RTMP 编码和 RTC 编码的码流做比照。2.应用 FFmpeg 发送 RTC 编码的码流确认是否绿屏。 1.码流比照咱们录制了一个残缺测试过程中的码流供编解码同学剖析,通过粗略的比照发现一个重要的区别 vui 中色域相干信息不统一,色域会影响 yuv->rgb 的转换。下图是不绿屏码流的 vui 通过这个线索,咱们做了两个验证测试: 1.咱们的 vui 是否会造成彩色显示异样,通过摄像头采集一个彩色手机,在图像中造成大面积彩色。验证后果:失常显示。 ...

December 17, 2020 · 2 min · jiezi

关于webrtc:WebRTC的媒体获取以及媒体录制

在前一篇讲了WebRTC的基本概念,接下去的几篇会介绍WebRTC的外围用法。 WebRTC离不开音频和视频,那么最开始的问题就是,这些媒体数据是怎么获取的?在RTC中,采集音频或视频设施后会源源不断地产生媒体数据,这些数据被称为媒体流。例如,从Canvas、摄像头或计算机桌面捕捉的流为视频流,从麦克风捕捉的流为音频流。媒体流是朝远端发送音视频数据的前置条件,否则会呈现连贯建设后数据不通的状况,即看不到对方的视频或听不到对方的声音。因为这些媒体流中混入的可能是多种数据,因而WebRTC又将其划分成多个轨道,分为视频媒体轨道和音频媒体轨道。这个和现实生活相比很好了解,比方高速要求开120KM,如果自行车下来了,就会造成整体速度的降落,所以才会分不同的车道,更快的火车就有铁轨,飞机也有飞机的路线,这样每个交通工具都可能利用带宽最大化。在WebRTC中,每个轨道对应于具体的设施,如视频直播中,主播的计算机上可能插入了多个高清摄像头和业余话筒。这些设施的名称和Id能够通过媒体轨道获取,从而能够对其进行管制或拜访以后设施状态,如麦克风静音和勾销静音。 媒体流和轨道相干API MediaStream 媒体流能够通过getUserMedia或getDisplayMedia接口获取 MediaStreamTrack 媒体轨道通过MediaStream的getVideoTracks获取所有的视频轨道,通过getAudioTracks获取所有的音频轨道 Video.captureStream Video为视频源对象,如正在点播的电影,通过captureStream办法能够捕捉到其媒体流,传入的帧率越大,视频画面越晦涩,同时所需的带宽也越大 Canvas.captureStream Canvas为浏览器画布对象,如通过Canvas实现的一个画板,通过captureStream办法能够捕捉其媒体流,即可动静的获取画板中所画的内容。同理,传入的帧率越大,画板描述的动作越晦涩,当然,所需的带宽也越大,个别帧率取10就够用了 媒体流解决是通过MediaStream接口进行的。一个流蕴含几个轨道,比方视频轨道和音频轨道。有两种办法能够输入MediaStream对象:其一,能够将输入显示为视频或音频元素;其二,能够将输入发送到RTCPeerConnection对象,而后将其发送到近程计算机。媒体流不仅能够通过拜访设施产生,还能够通过其余形式获取。归纳起来有以下几种形式。 摄像头:捕捉用户的摄像头硬件设施。麦克风:捕捉用户的麦克风硬件设施。计算机屏幕:捕捉用户的计算机桌面。画布Canvas:捕捉浏览器的Canvas标签内容。视频源Video:捕捉Video标签播放的视频内容。远端流:应用对等连贯来接管新的流,如对方发过来的音视频流。要进行媒体流的开发,就要先相熟外围API,简略演绎一下MediaStream的属性、事件及办法。 属性通过MediaStream.active能够监听流是否处于活动状态,即是否有音视频流。罕用属性如下所示。·MediaStream.active:如果MediaStream处于活动状态,则返回true,否则返回false。MediaStream.ended:如果在对象上已触发完结事件,则返回true,这意味着流已齐全读取,如果未达到流结尾,则为false。MediaStream.id:对象的惟一标识符。MediaStream.label:用户代理调配的惟一标识符。在高速上,有可能因为车出了故障造成拥挤,也有可能因为变道降速、提速,这些在WebRTC中就叫做事件。 MediaStream事件用于监听流解决及活动状态变动。如当用户点击共享屏幕的“进行”按钮时会触发MediaStream.oninactive事件。当增加新的MediaStreamTrack对象时触发MediaStream.addTrack事件。 罕用的事件如下。 MediaStream.onactive:当MediaStream对象变为活动状态时触发的流动事件的处理程序。MediaStream.onaddtrack:在增加新的MediaStreamTrack对象时触发的addTrack事件的处理程序。MediaStream.onended:当流终止时触发的完结事件的处理程序。MediaStream.oninactive:当MediaStream对象变为非活动状态时触发的非流动事件的处理程序。MediaStream.onremovetrack:在从它移除MediaStreamTrack对象时触发的removeTrack事件的处理程序。很显然,高速上如果有某个事件,那就须要比方打高速交警,开双闪等,在web RTC中,也有相似的对事件的解决。次要就是用办法MediaStream,用于增加、删除、克隆及获取音视频轨道。办法及阐明如下 MediaStream.addTrack():将作为参数的MediaStreamTrack对象增加到MediaStream中。如果曾经增加了音轨,则没有产生任何事件。MediaStream.clone():应用新id返回MediaStream对象的克隆。MediaStream.getAudioTracks():从MediaStream对象返回音频MediaStreamTrack对象的列表。MediaStream.getTrackById():通过id返回跟踪。如果参数为空或未找到id,则返回null。如果多个轨道具备雷同的id,则返回第一个轨道MediaStream.getTracks():从MediaStream对象返回所有MediaStreamTrack对象的列表。MediaStream.getVideoTracks():从MediaStream对象返回视频MediaStreamTrack对象的列表。MediaStream.removeTrack():从MediaStream中删除作为参数的MediaStreamTrack对象。如果已删除该轨道,则不会产生任何操作。再来讲一下很重要的媒体录制。影像及声音的保留在有些场景下是有必要的,如医生会诊,举办重要视频会议,老师传授课程等场景,目标是便于日后回放。 MediaRecorder是管制媒体录制的API,在原生App开发中是一个利用宽泛的API,用于在App内录制音频和视频。事实上随着Web的利用越来越富媒体化,W3C也制订了相应的Web规范,称为MediaRecorder API,它给咱们的Web页面赋予了录制音视频的能力,使得Web能够脱离服务器、客户端的辅助,独立进行媒体流的录制。任何媒体模式的标签都能够录制,包含音频标签<audio>、视频标签<video>以及画布标签<canvas>,其中<audio>与<video>能够来自网络媒体文件,也能够来自本机设备采集。而<canvas>的内容则更加自在,任何绘制在画布上的用户操作、2D或3D图像,都能够进行录制。它为Web提供了更多可能性,咱们甚至能够把一个HTML5游戏流程录成视频,保留落地或进行实况传输。录制进去的是通过规范编码后的媒体流数据,能够注入<video>标签,也能够打包生成文件,还能够进行流级别的数据处理,比方画面辨认、动静插入内容、播放跳转管制等。最初生成的文件能够是mp3、mp4、ogg以及webm等格局。 罕用API能够应用MediaRecorder.start(timeslice)录制媒体,其中,timeslice是可选项,如果没有设置,则在整个录制实现后触发ondataavailable事件,如果设置了,比方设置为10,就会每录制10毫秒触发一次ondataavailable事件。罕用办法如下所示。·MediaRecorder.stop():进行录制。·MediaRecorder.pause():暂停录制。·MediaRecorder.resume():复原录制。·MediaRecorder.isTypeSupported():查看是否反对录制某个格局。 制事件MediaRecorder有两个重要事件, MediaRecorder.ondataavailable:当数据无效时触发的事件,数据无效时能够把数据存储到缓存区里。MediaRecorder.onerror:当有谬误时触发的事件,出错时录制会被进行。bitsPerSecond:指定音频和视频的比特率,此属性能够用来指定下面两个属性。如果只有上述两个属性之一或此属性被指定,则此属性能够用于设定另外一个属性。 通过MediaRecorder对象能够将麦克风采集的音频数据录制成一个声音文件,如ogg文件。 WebRTC能够间接捕捉用户电脑的整个屏幕,也可捕捉某个利用窗口。旧的Chrome浏览器还须要借助插件来解决这一问题,新的Chrome则能够间接获取。当获取到用户电脑的数据流stream后,再应用MediaRecorder则可将其录制成视频文件。显示器的分辨率能够设置成不同的值,如2880×1800、1440×900。分辨率越高,清晰度越高。当显示器的分辨率较高时,如果捕捉时设置了一个较小的束缚,则可能最终录下来的视频不清晰。 最初附上相干代码: import React from "react";import {Button} from "antd";let mediaRecorder;let recordedBlobs;let stream;class RecordScreen extends React.Component { startCaptureScreen = async (e) => { try { stream = await navigator.mediaDevices.getDisplayMedia({ video: { width: 2880, height: 1800} });  const video = _this_.refs['myVideo']; const videoTracks = stream.getVideoTracks(); console.log(视频资源名称: ${videoTracks[0].label}); window._stream_ = stream; video.srcObject = stream;  _this_._startRecord_();  } catch (e) { console.log('getUserMedia谬误:' + error); } }  startRecord = (e) => { stream.addEventListener('inactive', e => { console.log('监听到屏幕捕捉进行后进行录制!'); _this_._stopRecord_(e); });  recordedBlobs = []; try { mediaRecorder = new MediaRecorder(window._stream_, {mimeType: 'video/webm'}); } catch (e) { console.error('创立MediaRecorder谬误:', e); _return_; }  mediaRecorder.onstop = (event) => { console.log('录制进行: ', event); console.log('录制的Blobs数据为: ', recordedBlobs); };  mediaRecorder.ondataavailable = (event) => { console.log('handleDataAvailable', event); if (event.data && event.data.size > 0) { recordedBlobs.push(event.data);} }; mediaRecorder.start(10); console.log('MediaRecorder started', mediaRecorder); } stopRecord = (e) => { mediaRecorder.stop(); stream.getTracks().forEach(track => track.stop()); stream = _null_;  const blob = new Blob(recordedBlobs, {type: 'video/webm'}); const url = window.URL._createObjectURL_(blob); const a = document.createElement('a'); a.style.display = 'none'; a.href = url; a.download = 'screen.webm'; document.body.appendChild(a); a.click(); mediaRecorder = new MediaRecorder(window._stream_, {mimeType: 'video/webm'}); } _catch_(e) { console.error('创立MediaRecorder谬误:', e); _return_; } mediaRecorder._onstop_ = (event) => { console.log('录制进行: ', event); console.log('录制的Blobs数据为: ', recordedBlobs); }; mediaRecorder._ondataavailable_ = (event) => { console.log('handleDataAvailable', event); if (event.data && event.data.size > 0) { recordedBlobs.push(event.data); } }; mediaRecorder.start(10;console.log( 'MediaRecorder started' mediaRecorder;}  stopRecord = (e) => { mediaRecorder.stop(); stream.getTracks().forEach(track => track.stop()); stream = _null_;  const blob = new Blob(recordedBlobs, {type: 'video/webm'}); const url = window.URL._createObjectURL_(blob); const a = document.createElement('a'); a.style.display = 'none'; a.href = url; a.download = 'screen.webm'; document.body.appendChild(a); a.click(); ...

December 15, 2020 · 2 min · jiezi

关于webrtc:WebRTC-系列之视频辅流

作者:网易云信资深客户端开发工程师 陶金亮 近几年,实时音视频畛域越来越热,业界很多音视频引擎都是基于 WebRTC 进行实现的。本文次要介绍 WebRTC 在视频辅流上的需要背景以及相干技术实现。 WebRTC 中的 SDP 反对两种计划: PlanB 计划 和 Unified Plan 计划。晚期咱们应用多PeerConnection的 Plan B 计划中只反对一条视频流发送,这条视频流,咱们称之为”支流”。目前咱们应用单 PeerConnection 的 Unified Plan 计划,新增一条视频辅流,何为视频”辅流”?视频辅流是指第二条视频流,个别用于屏幕共享。 需要背景随着业务的倒退,一路视频流满足不了更多理论业务场景的需要,例如在多人视频聊天、网易会议以及其余在线教育场景下,须要同时发送两路视频流:一路是摄像头流,另一路是屏幕共享流。 然而,目前应用 SDK 分享屏幕时,采纳的是从摄像头采集通道进行屏幕分享。在该计划下,分享者只有一路上行视频流,该场景中要么上行摄像头画面,要么上行屏幕画面,两者是互斥的。 除非实例一个新的 SDK 专门采集并发送屏幕画面,但实例两个 SDK 的计划在业务层解决起来非常麻烦且会存在许多问题,例如如何解决两个流间的关系等。 在 WebRTC 场景中,还存在一种能够独自为屏幕分享开启一路上行视频流的计划,并称之为“辅流(Substream)”。辅流分享即共享者同时公布摄像头画面和屏幕画面两路画面。 另外,有了这个辅流的通道,当设施为新版本 iPhone(新版本 iPhone 具备同时开启前后摄像头的能力)时,也为反对前后2路摄像头发送视频数据奠定了根底。 技术背景后期 SDK 的架构设计是一个多 PeerConnection 的模型,即:一个 PeerConnection 对应一路音视频流。随着新的 SDP(Session Description Protocol)格局(UnifyPlan)的推出和反对,一个 PeerConnection 能够对应多路音视频流,即单 PeerConnection 模型,即基于单 PC 的架构,容许创立多个 Transceiver,用于发送多条视频流。 技术实现目前视频流次要分为三类:Camera 流、屏幕共享流、自定义输出视频流,别离有不同属性: 将 Camera 流作为支流,反对 Simulcast;将自定义视频输出(非屏幕共享)作为支流,不反对 Simulcast;将屏幕共享作为辅流,不反对 Simulcast,有独自的屏幕共享编码策略;因为 iOS 屏幕共享的特殊性,其须要通过自定义视频输出的形式来获取视频数据,因而存在如下图所示的流程图: ...

December 10, 2020 · 2 min · jiezi

关于webrtc:深入浅出-WebRTC-AEC声学回声消除

前言:近年来,音视频会议产品晋升着工作协同的效率,在线教育产品冲破着传统教育模式的种种限度,娱乐互动直播产品丰盛着生存社交的多样性,背地都离不开音视频通信技术的优化与翻新,其中音频信息内容传递的流畅性、完整性、可懂度间接决定着用户之间的沟通品质。自 2011 年 WebRTC 开源以来,无论是其技术架构,还是其中丰盛的算法模块都是值得咱们细细品味,音频方面熟知的 3A 算法(AGC: Automatic gain control; ANS: Adaptive noise suppression; AEC: Acoustic echo cancellation)就是其中闪闪发光的明珠。本文章将联合实例全面解析 WebRTC AEC 的根本框架和基本原理,一起摸索回声打消的基本原理,技术难点以及优化方向。 作者:珞神,阿里云高级开发工程师,负责阿里云 RTC 音频研发 回声的造成WebRTC 架构中上下行音频信号处理流程如图 1,音频 3A 次要集中在上行的发送端对发送信号顺次进行回声打消、降噪以及音量平衡(这里只探讨 AEC 的解决流程,如果是 AECM 的解决流程 ANS 会前置),AGC 会作为压限器作用在接收端对行将播放的音频信号进行限幅。 那么回声是怎么造成的呢? 如图 2 所示,A、B 两人在通信的过程中,咱们有如下定义: x(n): 远端参考信号,即 A 端订阅的 B 端音频流,通常作为参考信号;y(n): 回声信号,即扬声器播放信号 x(n) 后,被麦克风采集到的信号,此时通过房间混响以及麦克风采集的信号 y(n) 曾经不能等同于信号 x(n) 了, 咱们记线性叠加的局部为 y'(n), 非线性叠加的局部为 y''(n), y(n) = y'(n) + y''(n);s(n): 麦克风采集的近端谈话人的语音信号,即咱们真正想提取并发送到远端的信号;v(n):环境乐音,这部分信号会在 ANS 中被减弱;d(n): 近端信号,即麦克风采集之后,3A 之前的原始信号,能够示意为:d(n) = s(n) + y(n) + v(n);s'(n): 3A 之后的音频信号,即筹备通过编码发送到对端的信号。WebRTC 音频引擎可能拿到的已知信号只有近端信号 d(n) 和远端参考信号 x(n)。 ...

December 10, 2020 · 4 min · jiezi

关于webrtc:使用webrtcnodejs搭建多人视频会议在线直播

git地址:webrtc-demo npm installnode app.js // 默认端口https://localhost:3000全局装置nodemon 用 nodemon app.js // 热更新启动node启动的是https 能够掉起本地获取摄像头权限浏览器输出https://localhost:3000https://localhost:3000/ 获取音视频设施信息https://localhost:3000/room 残缺我的项目 展现本地流 连贯近程流https://localhost:3000/mediastream WebRTC 次要提供了三个外围的 API:getUserMedia:能够获取本地的媒体流,一个流蕴含几个轨道,比方视频和音频轨道。RTCPeerConnection:用于建设 P2P 连贯以及传输多媒体数据。RTCDataChannel:建设一个双向通信的数据通道,能够传递多种数据类型。如果假如,对等体 A 想要与对等体 B 建设 WebRTC 连贯,则须要执行以下操作: Peer A应用 ICE 生成它的 ICE候选者。在大多数状况下,它须要 NAT(STUN)的会话遍历实用程序或 NAT(TURN)服务器的遍历应用中继。Peer A 将 ICE候选者 和会话形容捆绑到一个对象中。该对象在对等体 A 内存储为本地形容(对等体本人的连贯信息),并通过信令机制传送给对等体 B.这部分称为要约。对等体 B 接管该提议并将其存储为近程形容(另一端的对等体的连贯信息)以供进一步应用。对等体 B 生成它本人的 ICE候选者和会话形容,将它们存储为本地形容,并通过信令机制将其发送给对等体A.这部分称为答案。 (注:如前所述,步骤2和3中的ICE候选人也能够独自发送)对等体 A 从对等体 B 接管答案并将其存储为近程形容。这样,两个对等体都具备彼此的连贯信息,并且能够通过 WebRTC 胜利开始通信!// 获取音视频设施初始化本地流function start() { if(!navigator.mediaDevices || !navigator.mediaDevices.getUserMedia) { console.log("不反对"); return } else { var deviceId = viodeSource.value; // 音频视频采集 var constraints = { video: { width: 640, height: 480, frameRate: 15,//30, // 帧率 // facingMode: "enviroment" // 摄像头 deviceId: deviceId ? deviceId : undefined // 视频设施id // 设置之后能够在手机上切换摄像头 前置后置切换 }, audio: { noiseSuppression: true, //降噪 echoCancellation: true // 回音打消 } } // 只设置音频 // var constraints = { // video: false, // audio: true // } navigator.mediaDevices.getUserMedia(constraints) .then(gotMediaStream) .then(gotDevices) .catch(handleError) }}function gotMediaStream(stream) { console.log(stream) videoplay.srcObject = stream; //设置视频流 window.stream = stream; // 获取视频束缚 var videoTrack = stream.getVideoTracks()[0]; var videoConstraints = videoTrack.getSettings(); constraints.textContent = JSON.stringify(videoConstraints); //打印在页面上 // audioplayer.srcObject = stream; // 只设置音频 return navigator.mediaDevices.enumerateDevices(); // promise返回 then 后接口 then}建设信令服务器应用node+koa2搭建信令服务器引入socket.io ...

November 27, 2020 · 4 min · jiezi

关于webrtc:从-0-到-1-构建实时音视频引擎

最近几年,实时音视频畛域越来越热,往年的疫情更是“推波助澜”了一把。网易智企旗下产品网易云信在实时音视频畛域深耕多年,积攒了不少实践经验。在本文里,笔者将以烹饪为比喻,深入浅出地将网易云信如何从0到1构建实时音视频引擎的过程分享给读者。跟业界很多引擎的实现计划一样,网易云信也是基于 WebRTC 构建的实时音视频引擎。本文会从介绍 WebRTC 提供了什么开始,一步步引入工程化/产品化/优化实际等内容,残缺出现引擎的整个构建过程。 WebRTC 是什么首先,WebRTC 是什么? WebRTC 全称 Web Real-Time Communication。本来是用于反对网页浏览器开发实时音视频用的一套 API,它提供了对立的交互协定:SDP,同时提供了视频会议的核心技术,包含音频引擎、视频引擎、传输管制三大块,并且还反对跨平台:Windows / Mac / Linux / Android / iOS。 WebRTC 原本就是给浏览器用的,没有 native 代码能够参考。然而,在 2011 年它被 Google 开源了,源码被利用于各种 native 开发,并被业内宽泛借鉴,大有一统天下的趋势。 WebRTC 提供了什么?有了 WebRTC,是不是就等于有了实时音视频引擎呢?并不是,以烹饪来做比喻的话,有了 WebRTC 就好比是有了厨具/原材料,而实时音视频引擎是给客户的那顿大餐。 有了厨具/原材料,第一步是什么呢?“学会厨具应用办法”— WebRTC 的源码工程化。 WebRTC 官网和其余第三方渠道已有不少材料介绍如何应用 Google 提供的工具编译出 WebRTC 的生成物,本文不再具体赘述。 会用厨具之后,是不是就能做出一顿好吃的饭菜了呢? 事实往往是这样的:用着很牛的厨具和资料,做着难以下咽的操持… 所以要以正当的步骤来做一顿饭菜,这饭菜才适宜下咽。 基于 WebRTC 网易云信如何构建音视频能力在网易云信的实际中,咱们抉择了怎么的步骤呢?因为基于 WebRTC 建设通话的根底是通过设置 SDP 来实现的,所以咱们抉择了通过信令传递 SDP 信息,而后设置 SDP 信息给 PeerConnection 来实现建联。整个多人音视频能力中外围的是公布、订阅、响应订阅等媒体性能,其余的性能都是围绕着这些外围性能来做的。而外围性能是采纳如下流程来实现的: 举例: ...

November 24, 2020 · 1 min · jiezi

关于webrtc:WebRTC点对点通信的有趣故事

WebRTC给咱们带来了浏览器中的视频、音频聊天体验。但集体认为,它最实用的个性莫过于DataChannel——在浏览器之间建设一个点对点的数据通道。在DataChannel之前,浏览器到浏览器的数据传递通常是这样一个流程:浏览器1发送数据给服务器,服务器解决,服务器再转发给浏览器2。这三个过程都会带来相应的耗费,占用服务器带宽不说,还减缓了音讯从发送到接管的工夫。其实最现实的形式就是浏览器1间接与浏览2进行通信,服务器不须要参加其中。WebRTC DataChannel就提供了这样一种形式。 老刘和老姚当然服务器齐全不参加其中,显然是不可能的,用户须要通过服务器上存储的信息,能力确定须要和谁建设连贯。这里通过一个故事来讲述建设连贯的过程: 不如钓鱼去一些背景: 老刘和老姚都住在同一个小区但不同的片区,小区很破旧,没有电话片区互相隔离且片区门口有个保安,保安只意识本人片区的人,遇到不意识的人就须要查问凭证能力通过,而凭证须要找物业能力确定门卫老大爷意识小区里的所有人然而不晓得都住哪,有什么音讯都能够在出入小区的时候代为传播当初,老刘据说老姚钓鱼技术高超,想和老姚探讨钓鱼技巧。只有老刘和老姚相互之间晓得对方的门牌号以及凭证,就能够串门了: 门卫老大爷意识老刘和老姚老刘找物业确定了本人片区的出入凭证,将凭证、本人的门牌号以及用意通知门卫老大爷,让其转交给老姚老姚买菜归来遇到门卫老大爷,门卫老大爷将老刘的音讯传播给老姚。于是老姚晓得怎么去老刘家了老姚很开心,他也找物业获取了本人小区的凭证,并将凭证、本人的门牌号等信息交给门卫老大爷,心愿他传播给老刘老刘吃早餐回来遇到门卫老大爷,老大爷把老姚的小区凭证、门牌号等信息通知老刘,这样老刘就晓得了怎么去老姚家了老刘和老姚相互之间晓得了对方的门牌号和小区出入凭证,他们相互之间有什么须要交换的间接串门就行了,音讯不再须要门卫老大爷来代为传播了 换个角度咱们把角色做一个映射: 老刘:浏览器1老姚:浏览器2片区:不同网段保安:防火墙片区凭证:ICE candidate物业:ICE server门牌号:session description门卫老大爷:server于是乎故事就变成了这样: 浏览器1和浏览器2在server上注册,并保有连贯浏览器1从ice server获取ice candidate并发送给server,并生成蕴含session description的offer,发送给serverserver发送浏览器1的offer和ice candidate给浏览器2浏览器2发送蕴含session description的answer和ice candidate给serverserver发送浏览器2的answer和ice candidate给浏览器1这样,就建设了一个点对点的信道,流程如下所示: 原文地址:应用WebRTC搭建前端视频聊天室——点对点通信篇

November 12, 2020 · 1 min · jiezi

关于webrtc:WebRTC视频通话调试

在上一节曾经做好了前端的调试,能够在前端调用发送视频。一、后端在网页建设 webRTC 通信的时候,须要先给后端发送申请建设连贯,即依据登录用户来生成webRTC ID,做为通信标识,并且将建设的用户信息保留在后端Redis服务中。 能够看到,webrtcroom:http 保留所有连贯webRTC的客户端,这里的客户端是只有在浏览器关上一个新页面,就会主动创立一个新的连贯webrtc ID。

November 4, 2020 · 1 min · jiezi

关于webrtc:前端音视频WebRTC实时通讯的核心

观感度:???????????????????? 口味:新疆炒米粉 烹饪工夫:10min 本文已收录在前端食堂同名仓库Github github.com/Geekhyt,欢迎光临食堂,如果感觉酒菜还算可口,赏个 Star 对食堂老板来说是莫大的激励。通过上两个系列专栏的学习,咱们对前端音视频及 WebRTC 有了初步的理解,是时候敲代码实现一个 Demo 来实在感触下 WebRTC 实时通信的魅力了。还没有看过的同学请移步: 前端音视频的那些名词前端音视频之WebRTC初探RTCPeerConnectionRTCPeerConnection 类是在浏览器下应用 WebRTC 实现实时互动音视频零碎中最外围的类,它代表一个由本地计算机到远端的 WebRTC 连贯。该接口提供了创立、放弃、监控及敞开连贯的办法的实现。 想要对这个类理解更多能够移步这个链接, https://developer.mozilla.org/zh-CN/docs/Web/API/RTCPeerConnection 其实,如果你有做过 socket 开发的话,你会更容易了解 RTCPeerConnection,它其实就是一个增强版本的 socket。 在上个系列专栏 前端音视频之WebRTC初探 中,咱们理解了 WebRTC 的通信原理,在实在场景下须要进行媒体协商、网络协商、架设信令服务器等操作,我画了一张图,将 WebRTC 的通信过程总结如下: 不过明天咱们为了单纯的搞清楚 RTCPeerConnection,先不思考开发架设信令服务器的问题,简略点,咱们这次尝试在同一个页面中模仿两端进行音视频的互通。 在此之前,咱们先理解一些将要用到的 API 以及 WebRTC 建设连贯的步骤。 相干 APIRTCPeerConnection 接口代表一个由本地计算机到远端的 WebRTC 连贯。该接口提供了创立、放弃、监控、敞开连贯的办法的实现。PC.createOffer 创立提议 Offer 办法,此办法会返回 SDP Offer 信息。PC.setLocalDescription 设置本地 SDP 形容信息。PC.setRemoteDescription 设置远端 SDP 形容信息,即对方发过来的 SDP 数据。PC.createAnswer 创立应答 Answer 办法,此办法会返回 SDP Answer 信息。RTCIceCandidate WebRTC 网络信息(IP、端口等)PC.addIceCandidate PC 连贯增加对方的 IceCandidate 信息,即增加对方的网络信息。WebRTC 建设连贯步骤1.为连贯的两端创立一个 RTCPeerConnection 对象,并且给 RTCPeerConnection 对象增加本地流。2.获取本地媒体形容信息(SDP),并与对端进行替换。3.获取网络信息(Candidate,IP 地址和端口),并与远端进行替换。Demo 实战首先,咱们增加视频元素及管制按钮,引入 adpater.js 来适配各浏览器。 ...

October 18, 2020 · 3 min · jiezi

关于webrtc:WebRTC-框架下的实时视频关键路径

在以后数字化浪潮下,基于互联网的实时音视频通信曾经成为越来越多互联网利用的标配。得益于互联网基础设施的日趋完善和优良开源解决方案WebRTC的呈现,音视频实时通信的开发门槛也升高很多。但音视频利用的技术和工程实现复杂度还是比拟高的,有必要深刻其中搞清楚实现的前因后果。本文基于webRTC框架对实时音视频通信的一些要害实现做一些探讨,但其原理是相通的并不局限于webRTC。 WebRTC实时音视频通信框架从它的名字上也能够看出webRTC是作为web端的实时通信计划提出的,目前在google鼎力推动下曾经成为支流浏览器的标配性能。基于图1的架构实现信令服务器,web APP就能够轻松取得音视频通信的能力。 下面的场景只是简略的P2P(点对点)两方的通信,如果要反对多方通信和克服理论网络环境中各类防火墙的挑战,通常会引入更多的服务器性能单元,比方MCU(Multipoint Control Unit),SFU(Selective Forwarding Unit)。如图2,减少了Media Server承当MCU/SFU等性能,减少Data Server承当媒体类的信息交互,这种架构下原来的点对点的去核心构造变成了星状的构造。 通信的单方有三类交互信息,依据信息各自的特点能够有不同的传输方式。其中,signaling plane信令通道webRTC并没有实现,预留好了管制接口。Data plane和media plane,webRTC提供了一套齐备的计划。 信令(signaling plane):交互协商单方的音视频编解码能力,实现通信链路(data/media plane)建设所必须的信息和参数交互。 数据(data plane):交互单方非音视频类的信息,个别实时性要求不高。 媒体(media plane):交互音视频数据,实时性要求高。 三条通信通道各有各的角色,各自实现本人的工作。media plane的整个链路解决最为简单,实时要求也最高。本文仅就media plane的视频流(video)在SFU架构下端到端处理过程做一个残缺解剖,参考webRTC m79分支做了逻辑形象,对其余非webRTC的视频解决零碎也有参考意义。 WebRTC的视频流要害门路视频从发送端摄像头采集到接收端显示器渲染,咱们定义为一个端到端的处理过程。接下来形容的过程是典型的精简零碎的处理过程,理论生产线上的处理过程有可能还会多一些额定步骤。一件事件如果能抓住它的主线,那这件事件就不会跑偏。 media plane的传输通道的协定栈如图3所示,ICE(Interactive Connectivity Establishment )用来防火墙穿透和链路连通性监测。DTLS(Datagram Transport Level Security)过程实现密钥的替换,是后续media加密的辅助过程,如果不加密能够跳过,浏览器是默认关上加密性能的。在通过ICE和DTLS两个辅助过程后,media最终在(S)RTP/(S)RTCP之上传输。咱们重点关注在这个媒体信息的传输门路。接下来咱们看一下视频画面是怎么流过端到端的,要害门路如图4所示。 依照视频画面的解决程序咱们逐渐看一下每个步骤产生了什么事件 发送方向(采集端-媒体服务器)video capture:webRTC提供了丰盛的设施治理性能,能够依据摄像头的能力和业务须要订阅不同等级的视频输入,能够管制摄像头输入的分辨率和帧率。 video adapter:视频帧适配器,能够裁剪视频画面,升高/升高视频辨率或丢帧以扭转输出到encoder的数据量。video adapter与encoder之间会有交互,两者配合能够管制编码器的码率输入。 encoder:编码器,webrtc应用了openh264开源实现。 RTP/RTCP packetizer:组包器,依照RTP/RTCP协定标准组包。 Pacer queue:发送队列,组包器输入的RTP包放入该队列中期待发送。 Pacer&prober:发包器&带宽探测器,发包器依据以后预估的带宽限度,往Transport安稳发包。带宽探测器用于探测以后网络带宽下限,探测包的发送跟以后发送的理论无效包速率无关。 Transport:网络传输模块,加密,端口复用等网络传输性能。 接管方向(媒体服务器-播放端)Transport:网络传输模块,解密,de端口解复用等网络传输性能。 RTP/RTCP depacketizer:解包器,依照RTP/RTCP协定标准解包,。 Packet buffer:视频包缓存,和解包器一起负责RTP包的乱序和丢包解决。去掉RTP包头后,视频包会存入该buffer,每次来了新包都会查看以后的缓存外面是否曾经能够形成残缺的视频帧,如果残缺则组成残缺帧持续下一步的解决,否则则完结以后包的解决。 Frame queue:帧队列,负责缓存以后待解码的视频帧。 Decoder:解码器,负责视频帧解码。解码的开始机会思考了网络抖动、编码器提早、渲染提早。 Video render:渲染器,视频渲染接口模块。 媒体服务器媒体服务器的实现不在webRTC的范畴内,但也有不少优良的开源实现,比方Kurento/Jitsi/Janus/Srs/OWT等。为了更好的服务业务需要,更多的音视频解决方案公司打造本人的媒体服务器,将webRTC媒体流引入到本人的媒体解决方案中。以Kurento为例,介绍一下Media server上的视频流解决。图片起源https://www.kurento.org/kurento-architecture Kurento Media Server的媒体解决流水线是基于GStreamer实现的,其模块化和可扩展性做的十分好。一路视频流依据不同的业务需要,可能通过不同复杂程度的解决。列举几类典型的解决流水。 ...

October 13, 2020 · 1 min · jiezi

关于webrtc:前端音视频之WebRTC初探

观感度:???????????????????? 口味:干锅虾球 烹饪工夫:10min 本文已收录在前端食堂同名仓库Github github.com/Geekhyt,欢迎光临食堂,如果感觉酒菜还算可口,赏个 Star 对食堂老板来说是莫大的激励。在上个系列专栏前端音视频的那些名词中,咱们对比特率、帧率、分辨率、容器格局以及编码格局有所理解,如果还没看过的同学请点击上方链接自行跳转。 明天,咱们来一起学习一下 WebRTC,置信你曾经对这个前端音视频网红儿有所耳闻了。 WebRTC Web Real-Time Communication 网页即时通信WebRTC 于 2011 年 6 月 1 日开源,并在 Google、Mozilla、Opera 等大佬们的反对下被纳入 W3C 举荐规范,它给浏览器和挪动利用提供了即时通信的能力。 WebRTC 劣势及利用场景劣势跨平台(Web、Windows、MacOS、Linux、iOS、Android)实时传输音视频引擎收费、免插件、免装置支流浏览器反对弱小的打洞能力利用场景在线教育、在线医疗、音视频会议、即时通讯工具、直播、共享远程桌面、P2P网络减速、游戏(狼人杀、线上KTV)等。 (有喜爱玩狼人杀的同学吗?有工夫能够一起来一局,给我一轮听发言的工夫,给你裸点狼坑,一个坑容错。) WebRTC 整体架构拉回来,咱们看一看 WebRTC 的整体架构,我用不同的色彩标识出了各层级所代表的含意。 Web 利用Web APIWebRTC C++ APISession Management 信令治理Transport 传输层Voice Engine 音频引擎Video Engine 视频解决引擎咱们再来看下外围的模块: Voice Engine 音频引擎VoIP 软件开发商 Global IP Solutions 提供的 GIPS 引擎能够说是世界上最好的语音引擎,谷歌大佬一举将其收买并开源,也就是 WebRTC 中的 音频引擎。 iSAC:WebRTC 音频引擎的默认编解码器,针对 VoIP 和音频流的宽带和超宽带音频编解码器。iLBC:VoIP 音频流的窄带语音编解码器。NetEQ For Voice:针对音频软件实现的语音信号处理元件。NetEQ 算法是自适应抖动控制算法以及语音包失落暗藏算法,可能无效的解决网络抖动和语音包失落时对语音品质产生的影响。Acoustic Echo Canceler:AEC,回声消除器。Noise Reduction:NR,噪声克制。Video Engine 视频解决引擎VPx 系列视频编解码器是 Google 大佬收买 ON2 公司后开源的。 ...

October 9, 2020 · 1 min · jiezi

关于webrtc:开源轻松实现RTC与SIP互通

RTC与SIP互通所波及的问题要想让RTC与SIP互通,要解决两个层面的问题:信令层和媒体层。两个网络应用的信令机制不同,所以要进行信令的转换,能力实现媒体的协商,建设会话。媒体层要实现编码的转换,以及rtp/srtp转换等性能。 优质通信三要素信令层的协商:稳固的信令是实现RTC与SIP互通的根底,保达、异样解决、断线重连等机制。SIP协定与RTC协定互转的解决:上述曾经探讨了,RTC与SIP互通须要媒体层协定的转换。减速线路:媒体在服务间的直达,丢包以及提早的解决。就近接入、节点抉择等。ARCall-RTC与SIP互通解决方案为何制订RTC与SIP互通的开源计划RTC与SIP互通是基于市场的呼叫核心解决方案的需要,随着RTC技术的广泛应用,各个环节的利用需要层出不穷,传统的SIP呼叫核心也须要降级技术计划,咱们在给贝壳找房,浙江省公安厅等大型企业提供技术计划后进行项目分析发现:咱们在提供服务时客户更关注的是本人的业务流程,如何让客户疾速的集成,以及集成后灵便的革新计划来应答多变的需要,是我的项目可能顺利疾速推动的重要因素。 anyRTC寰球超过200数据中心,笼罩200+国家和地区,国内线路涵盖华东、华南、华北、东北、西南、东南、香港、台湾。客户就近接入、依据智能算法,给出最优门路。 开源阐明开源代码地址 开源的RTC和SIP互通的网关代码,其中应用了三大模块:RTC,RTM,SIP,相干的模块以库的模式提供,反对Linux和Windows平台。 开源的网关代码反对与ArCall开源我的项目互通,反对呼叫流程制订和批改。 开源的网关反对三种模式: IVR呼叫核心模块实用于呼叫核心,手机/网页/小程序客户端呼入IVR,通过语音导航实现相应的业务流程。 SIP被动呼RTC模块实用于客户坐席被动呼叫消费者,反对SIP呼叫客户端,反对SIP直呼手机号等。 RTC直呼SIP座机实用于企业内外网互通,通过APP客户端间接呼叫员工或指定坐席的工位座机。 呼叫流程这里用到了anyRTC的实时音讯SDK,请查看具体API阐明我的项目地址 1,状态流转图呼叫邀请中,主叫能够通过 LocalInvitation 对象提供的 getState 办法查问以后呼叫邀请的无关状态;被叫能够通过 SDK 返回的 RemoteInvitation对象的 getState办法查问以后呼叫邀请的相干状态。 LocalInvitationState下图形容了与主叫相干的呼叫邀请状态流转图: RemoteInvitationState下图形容了与被叫相干的呼叫邀请状态流转图: [外链图片转存失败,源站可能有防盗链机制,倡议将图片保留下来间接上传(img-kK8qpGPl-1597912226518)(https://web-cdn.agora.io/docs...] 2,API 时序图勾销已发送呼叫邀请 承受/回绝呼叫邀请 注意事项及限度条件主叫设置的呼叫邀请 content 的字符串长度:8 KB,格局为 UTF-8。被叫设置的呼叫邀请响应 response 的字符串长度:8 KB,格局为 UTF-8。呼叫邀请的 channel ID 仅用于与老信令互通时设置。设置的 channel ID 必须与老信令 SDK 设置雷同能力实现互通。字符串长度:64 字节,格局为 UTF-8。结语SIP与RTC互通,咱们实现了一整套的呼叫,通信流程,以及异样解决。更多场景玩法期待您去开掘~ 分割咱们联系电话:021-65650071 QQ征询群:580477436 ArCall技术交换群:597181019 征询邮箱:hi@dync.cc 技术问题:开发者论坛 获取更多帮忙返回:www.anyrtc.io

August 20, 2020 · 1 min · jiezi

关于webrtc:Openviduserver搭建kurento负载均衡机制

为什么要扩大流媒体服务器(kurento)咱们从openvidu官网上拉下代码,启动后,默认是一个openvidu服务器对一个kurento服务器。别离去解决信令和流媒体。依据官网文档所指的,一个session,参与者有7个的会话条件下,不同配置的服务器可能接受的压力如下图:是的,当咱们应用4c8g的服务器的时候,实践上只能解决7个session,也就是只有7个房间同时存在!这在生产上是基本不可能接受的。因为信令服务器压力自身不大,所以咱们必须扩大媒体服务器(kurento),让其承受能力减少。 怎么扩大kurentoopenvidu 分为CE版本和Pro版本,咱们应用的是CE版本,也就是源代码外面不会将kurento的代码给咱们,那咱们该怎么扩大源代码,让其能够负载多个kurento呢?首先能够看一下openviduPro-kurento的架构 是的,如上图,一个openvidu服务器扩大了3台kurento服务器,因为瓶颈在kurento上,不思考openviduserver的话,实践上咱们的可承受能力会乘以3!接下来咱们剖析一下openvidu的源码。 KMS_URIS=["ws://116.196.10.***:8888/kurento"]io.openvidu.server.config.OpenviduConfig:... public List<String> checkKmsUris() { String property = "KMS_URIS"; return asKmsUris(property, getValue(property)); }...从这里能够看到,代码的入口在这里。然而如果咱们在KMS_URIS外面增加多个kurento地址,他还是只会取地址外面的第一条kurento地址,也就是没有解决负载操作。起因在上面: public class FixedOneKmsManager extends KmsManager { @Override public List<Kms> initializeKurentoClients(List<KmsProperties> kmsProperties, boolean disconnectUponFailure) throws Exception { KmsProperties firstProps = kmsProperties.get(0); KurentoClient kClient = null; Kms kms = new Kms(firstProps, loadManager); try { kClient = KurentoClient.create(firstProps.getUri(), this.generateKurentoConnectionListener(kms.getId())); this.addKms(kms); kms.setKurentoClient(kClient); // TODO: This should be done in KurentoClient connected event kms.setKurentoClientConnected(true); kms.setTimeOfKurentoClientConnection(System.currentTimeMillis()); } catch (KurentoException e) { log.error("KMS in {} is not reachable by OpenVidu Server", firstProps.getUri()); if (kClient != null) { kClient.destroy(); } throw new Exception(); } return Arrays.asList(kms); } @Override @PostConstruct protected void postConstructInitKurentoClients() { try { List<KmsProperties> kmsProps = new ArrayList<>(); for (String kmsUri : this.openviduConfig.getKmsUris()) { String kmsId = KmsManager.generateKmsId(); kmsProps.add(new KmsProperties(kmsId, kmsUri)); } this.initializeKurentoClients(kmsProps, true); } catch (Exception e) { // Some KMS wasn't reachable log.error("Shutting down OpenVidu Server"); System.exit(1); } }}initializeKurentoClients 办法外面分明的写了,只会取KMS_URIS的第0条数据。那如果咱们想解决多条,这里就须要返回一个汇合,很简略,咱们定义一个本人的KmsManager类,重写initializeKurentoClients办法。如下: ...

August 3, 2020 · 3 min · jiezi

关于webrtc:Ubuntu安装kurento

装置指南kurento media server(kms) 能够通过多种形式装置 AWSdocker形式本地装置咱们须要在生产上应用,并且服务器应用的是京东云,所以抉择的是本地装置的形式。 本地装置应用这种办法,能够从Kurento我的项目提供的本地Ubuntu软件包存储库中装置Kurento Media Server。KMS 对Ubuntu的两个长期反对(LTS)版本有明确的反对:Ubuntu 16.04(Xenial)和Ubuntu 18.04(Bionic)(仅64位)。 关上终端并运行以下命令: 确保已装置GnuPG。sudo apt-get update && sudo apt-get install --no-install-recommends --yes \ gnup将Kurento存储库增加到系统配置中# Import the Kurento repository signing keysudo apt-key adv --keyserver keyserver.ubuntu.com --recv-keys 5AFA7A83# Get Ubuntu version definitionssource /etc/upstream-release/lsb-release 2>/dev/null || source /etc/lsb-release# Add the repository to Aptsudo tee "/etc/apt/sources.list.d/kurento.list" >/dev/null <<EOF# Kurento Media Server - Release packagesdeb [arch=amd64] http://ubuntu.openvidu.io/6.14.0 $DISTRIB_CODENAME kms6EOF装置KMS:sudo apt-get update && sudo apt-get install --no-install-recommends --yes \ kurento-media-server这将装置Kurento Media Server的发行版本。该服务器蕴含与Ubuntu初始化系统集成的服务文件,因而您能够应用以下命令来启动和进行它: ...

August 3, 2020 · 1 min · jiezi

关于webrtc:关于NATICESTUNTURN

对于NAT,ICE,STUN,TURN这些是开发人员必须十分理解的重要概念,能力应用WebRTC。这是上面有些问题将被解决: 什么是NAT?什么是NAT穿透?什么是ICE?什么是STUN?什么是TURN?如何装置Coturn?如何测试我的STUN / TURN服务器?如何配置STUN / TURN?WebRTC故障排除高级常识:NAT类型和NAT遍历什么时候须要STUN和TURN?NAT前面的每个WebRTC参与者都须要 STUN(可能还有 TURN)。尝试从 NAT前面进行连贯的所有对等方都须要“关上 ”本人的端口,这一过程称为 NAT遍历。这能够通过应用部署在NAT内部的 STUN服务器来实现。 STUN服务器配置为应用一系列UDP和TCP端口。在服务器的网络配置或平安组中,所有这些端口也应向所有流量凋谢。 如果要在NAT环境中装置Kurento(例如,如果服务器位于NAT防火墙前面),则还须要在/etc/kurento/modules/kurento/WebRtcEndpoint.conf.ini中配置内部STUN服务器。同样,位于NAT前面的所有浏览器客户端都须要应用RTCPeerConnection构造函数的iceServers字段配置STUN服务器详细信息。 比方: Kurento Media Server及其应用程序服务器在云计算机中运行,对传入连贯没有任何NAT或端口限度,而浏览器客户端从可能受限制的NAT网络运行,该网络禁止在未“关上”任何端口的端口上进行传入连贯提前 浏览器客户端能够出于信令目标与Application Server通信,然而最终,大部分音频/视频通信是在浏览器的WebRTC引擎和KMS之间实现的。 在这种状况下,客户端可能将数据发送到KMS,因为其NAT将容许传出数据包。然而,KMS 无奈将数据发送到客户端,因为客户端的NAT已敞开,无奈接管传入的数据包。这能够通过配置客户端应用STUN服务器来解决。客户端的浏览器将应用此服务器关上NAT中的相应端口。实现此操作后,客户端当初能够从KMS接管音频/视频流: 此过程由客户端浏览器的ICE实现实现。 请留神,只有KMS自身也配置为应用STUN服务器,您也能够在NAT防火墙后部署KMS。 如何装置coturnCoturn是STUN服务器和TURN中继,反对ICE协定所需的所有性能,并容许从NAT前面建设WebRTC连贯。 Coturn能够间接从Ubuntu软件包存储库装置: sudo apt-get update && sudo apt-get install --no-install-recommends --yes \ coturn要为WebRTC配置它,请依照下列步骤操作: 编辑/etc/turnserver.conf。此示例配置是很好的第一步;它将与Coturn和Kurento Media Server一起用于WebRTC流时无效。然而,您可能须要依据须要进行更改: # This server's external/public address, if Coturn is behind a NAT.# It must be an IP address, not a domain name.external-ip=<CoturnIp># STUN listener port for UDP and TCP.# Default: 3478.#listening-port=<CoturnPort># TURN lower and upper bounds of the UDP relay ports.# Default: 49152, 65535.#min-port=49152#max-port=65535# Uncomment to run server in 'normal' 'moderate' verbose mode.# Default: verbose mode OFF.#verbose# Use fingerprints in the TURN messages.fingerprint# Use long-term credential mechanism.lt-cred-mech# Realm used for the long-term credentials mechanism.realm=kurento.org# 'Static' user accounts for long-term credentials mechanism.user=<TurnUser>:<TurnPassword># Set the log file name.# The log file can be reset sending a SIGHUP signal to the turnserver process.log-file=/var/log/turnserver/turnserver.log# Disable log file rollover and use log file name as-is.simple-log留神: ...

August 3, 2020 · 1 min · jiezi

关于webrtc:WebRTC系列之音频的那些事

文|网易智慧企业资深客户端开发工程师 年初因为工作须要,开始学习WebRTC,被其简单的编译环境和微小的代码量所折服,注定是一块难啃的骨头。俗话说万事开头难,保持一个恒心,究竟能学习到WebRTC的设计精华。 明天和大家聊聊WebRTC中音频的那些事。WebRTC由语音引擎,视频引擎和网络传输三大模块组成,其中语音引擎是WebRTC中最具价值的技术之一,实现了音频数据的采集、前解决、编码、发送、承受、解码、混音、后处理、播放等一系列解决流程。 音频引擎次要蕴含:音频设备模块ADM、音频编码器工厂、音频解码器工厂、混音器Mixer、音频前解决APM。 音频工作机制 想要零碎的理解音频引擎,首先须要理解外围的实现类和音频数据流向,接下来咱们将简略的剖析一下。 音频引擎外围类图 音频引擎WebrtcVoiceEngine次要蕴含音频设备模块AudioDeviceModule、音频混音器AudioMixer、音频3A处理器AudioProcessing、音频治理类AudioState、音频编码器工厂AudioEncodeFactory、音频解码器工厂AudioDecodeFactory、语音媒体通道蕴含发送和承受等。 1.音频设备模块AudioDeviceModule次要负责硬件设施层,包含音频数据的采集和播放,以及硬件设施的相干操作。 音频混音器AudioMixer次要负责音频发送数据的混音(设施采集和伴音的混音)、音频播放数据的混音(多路承受音频和伴音的混音)。音频3A处理器AudioProcessing次要负责音频采集数据的前解决,蕴含回声打消AEC、自动增益管制AGC、噪声克制NS。APM分为两个流,一个近端流,一个远端流。近端(Near-end)流是指从麦克风进入的数据;远端(Far-end)流是指接管到的数据。音频治理类AudioState蕴含音频设备模块ADM、音频前解决模块APM、音频混音器Mixer以及数据流转核心AudioTransportImpl。音频编码器工厂AudioEncodeFactory蕴含了Opus、iSAC、G711、G722、iLBC、L16等codec。音频解码器工厂AudioDecodeFactory蕴含了Opus、iSAC、G711、G722、iLBC、L16等codec。音频的工作流程图 1. 发动端通过麦克风进行声音采集 2. 发动端将采集到的声音信号输送给APM模块,进行回声打消AEC,乐音克制NS,自动增益管制解决AGC 3. 发动端将解决之后的数据输送给编码器进行语音压缩编码 4. 发动端将编码后的数据通过RtpRtcp传输模块发送,通过Internet网路传输到接收端 5. 接收端承受网络传输过去的音频数据,先输送给NetEQ模块进行抖动打消,丢包暗藏解码等操作 6. 接收端将解决过后的音频数据送入声卡设施进行播放 NetEQ模块是Webrtc语音引擎中的外围模块 在 NetEQ 模块中,又被大抵分为 MCU模块和 DSP 模块。 MCU 次要负责做延时及抖动的计算统计,并生成对应的管制命令。 而 DSP 模块负责接管并依据 MCU 的管制命令进行对应的数据包解决,并传输给下一个环节。 音频数据流向 依据下面介绍的音频工作流程图,咱们将持续细化一下音频的数据流向。将会重点介绍一下数据流转核心AudioTransportImpl在整个环节中表演的重要角色。 数据流转核心AudioTransportImpl实现了采集数据处理接口RecordDataIsAvailbale和播放数据处理接口NeedMorePlayData。 RecordDataIsAvailbale负责采集音频数据的解决和将其散发到所有的发送Streams。 NeedMorePlayData负责混音所有接管到的Streams,而后输送给APM作为一路参考信号处理,最初将其重采样到申请输入的采样率。 RecordDataIsAvailbale外部次要流程: 由硬件采集过去的音频数据,间接重采样到发送采样率由音频前解决针对重采样之后的音频数据进行3A解决VAD解决数字增益调整采集音量音频数据回调内部进行内部前解决混音发送端所有须要发送的音频数据,包含采集的数据和伴音的数据计算音频数据的能量值将其散发到所有的发送StreamsNeedMorePlayData外部次要流程: 混音所有接管到的Streams的音频数据1.1 计算输入采样率CalculateOutputFrequency() 1.2 从Source收集音频数据GetAudioFromSources(),选取没有mute,且能量最大的三路进行混音 1.3 执行混音操作FrameCombiner::Combine() 特定条件下,进行噪声注入,用于采集侧作为参考信号对本地伴音进行混音操作数字增益调整播放音量音频数据回调内部进行内部前解决计算音频数据的能量值将音频重采样到申请输入的采样率将音频数据输送给APM作为一路参考信号处理由上图的数据流向发现,为什么须要FineAudioBuffer和AudioDeviceBuffer? 因为WebRTC 的音频流水线只反对解决 10 ms 的数据,不同的操作系统平台提供了不同的采集和播放时长的音频数据,不同的采样率也会提供不同时长的数据。 例如iOS上,16K采样率会提供8ms的音频数据128帧;8K采样率会提供16ms的音频数据128帧;48K采样率会提供10.67ms的音频数据512帧。 ...

July 29, 2020 · 1 min · jiezi

关于webrtc:WebRTC系列之音频的那些事

文|网易智慧企业资深客户端开发工程师 年初因为工作须要,开始学习WebRTC,被其简单的编译环境和微小的代码量所折服,注定是一块难啃的骨头。俗话说万事开头难,保持一个恒心,究竟能学习到WebRTC的设计精华。 明天和大家聊聊WebRTC中音频的那些事。WebRTC由语音引擎,视频引擎和网络传输三大模块组成,其中语音引擎是WebRTC中最具价值的技术之一,实现了音频数据的采集、前解决、编码、发送、承受、解码、混音、后处理、播放等一系列解决流程。 音频引擎次要蕴含:音频设备模块ADM、音频编码器工厂、音频解码器工厂、混音器Mixer、音频前解决APM。 音频工作机制 想要零碎的理解音频引擎,首先须要理解外围的实现类和音频数据流向,接下来咱们将简略的剖析一下。 音频引擎外围类图 音频引擎WebrtcVoiceEngine次要蕴含音频设备模块AudioDeviceModule、音频混音器AudioMixer、音频3A处理器AudioProcessing、音频治理类AudioState、音频编码器工厂AudioEncodeFactory、音频解码器工厂AudioDecodeFactory、语音媒体通道蕴含发送和承受等。 1.音频设备模块AudioDeviceModule次要负责硬件设施层,包含音频数据的采集和播放,以及硬件设施的相干操作。 音频混音器AudioMixer次要负责音频发送数据的混音(设施采集和伴音的混音)、音频播放数据的混音(多路承受音频和伴音的混音)。音频3A处理器AudioProcessing次要负责音频采集数据的前解决,蕴含回声打消AEC、自动增益管制AGC、噪声克制NS。APM分为两个流,一个近端流,一个远端流。近端(Near-end)流是指从麦克风进入的数据;远端(Far-end)流是指接管到的数据。音频治理类AudioState蕴含音频设备模块ADM、音频前解决模块APM、音频混音器Mixer以及数据流转核心AudioTransportImpl。音频编码器工厂AudioEncodeFactory蕴含了Opus、iSAC、G711、G722、iLBC、L16等codec。音频解码器工厂AudioDecodeFactory蕴含了Opus、iSAC、G711、G722、iLBC、L16等codec。音频的工作流程图 1. 发动端通过麦克风进行声音采集 2. 发动端将采集到的声音信号输送给APM模块,进行回声打消AEC,乐音克制NS,自动增益管制解决AGC 3. 发动端将解决之后的数据输送给编码器进行语音压缩编码 4. 发动端将编码后的数据通过RtpRtcp传输模块发送,通过Internet网路传输到接收端 5. 接收端承受网络传输过去的音频数据,先输送给NetEQ模块进行抖动打消,丢包暗藏解码等操作 6. 接收端将解决过后的音频数据送入声卡设施进行播放 NetEQ模块是Webrtc语音引擎中的外围模块 在 NetEQ 模块中,又被大抵分为 MCU模块和 DSP 模块。 MCU 次要负责做延时及抖动的计算统计,并生成对应的管制命令。 而 DSP 模块负责接管并依据 MCU 的管制命令进行对应的数据包解决,并传输给下一个环节。 音频数据流向 依据下面介绍的音频工作流程图,咱们将持续细化一下音频的数据流向。将会重点介绍一下数据流转核心AudioTransportImpl在整个环节中表演的重要角色。 数据流转核心AudioTransportImpl实现了采集数据处理接口RecordDataIsAvailbale和播放数据处理接口NeedMorePlayData。 RecordDataIsAvailbale负责采集音频数据的解决和将其散发到所有的发送Streams。 NeedMorePlayData负责混音所有接管到的Streams,而后输送给APM作为一路参考信号处理,最初将其重采样到申请输入的采样率。 RecordDataIsAvailbale外部次要流程: 由硬件采集过去的音频数据,间接重采样到发送采样率由音频前解决针对重采样之后的音频数据进行3A解决VAD解决数字增益调整采集音量音频数据回调内部进行内部前解决混音发送端所有须要发送的音频数据,包含采集的数据和伴音的数据计算音频数据的能量值将其散发到所有的发送StreamsNeedMorePlayData外部次要流程: 混音所有接管到的Streams的音频数据1.1 计算输入采样率CalculateOutputFrequency() 1.2 从Source收集音频数据GetAudioFromSources(),选取没有mute,且能量最大的三路进行混音 1.3 执行混音操作FrameCombiner::Combine() 特定条件下,进行噪声注入,用于采集侧作为参考信号对本地伴音进行混音操作数字增益调整播放音量音频数据回调内部进行内部前解决计算音频数据的能量值将音频重采样到申请输入的采样率将音频数据输送给APM作为一路参考信号处理由上图的数据流向发现,为什么须要FineAudioBuffer和AudioDeviceBuffer? 因为WebRTC 的音频流水线只反对解决 10 ms 的数据,不同的操作系统平台提供了不同的采集和播放时长的音频数据,不同的采样率也会提供不同时长的数据。 例如iOS上,16K采样率会提供8ms的音频数据128帧;8K采样率会提供16ms的音频数据128帧;48K采样率会提供10.67ms的音频数据512帧。 ...

July 29, 2020 · 1 min · jiezi

关于webrtc:WebRTC-之ICE浅谈-内有干货免费下载

前言ICE全称Interactive Connectivity Establishment:交互式连通建设形式。 ICE参照RFC5245倡议实现,是一组基于offer/answer模式解决NAT穿梭的协定汇合。 它综合利用现有的STUN,TURN等协定,以更无效的形式来建设会话。 客户端侧无需关怀所处网络的地位以及NAT类型,并且可能动静的发现最优的传输门路。 webrtc·1.04 Classic STUN(RFC3489)的劣势Classic STUN 有着诸多局限性,例如: 不能确定取得的公网映射地址是否用于P2P通信没有加密办法不反对TCP穿梭不反对对称型NAT的穿梭不反对IPV6STUN(RFC5389)协定RFC5389是RFC3489的升级版 反对UDP/TCP/TLS协定反对平安认证ICE利用STUN(RFC5389) Binding Request和Response,来获取公网映射地址和进行连通性查看。同时扩大了STUN的相干属性: PRIORITY:在计算candidate pair优先级中应用USE-CANDIDATE:ICE提名时应用tie-breaker:在角色冲突时应用TURN协定ICE应用TURN(RFC 5766)协定作为STUN的辅助,在点对点穿梭失败的状况下,借助于TURN服务的转发性能,来实现互通。端口与STUN保持一致 TURN音讯都遵循 STUN 的音讯格局,除了ChannelData音讯。 反对UDP/TCP/TLS协定,实用于UDP被限度的网络。反对IPV6。TURN的流程:创立Allocation:client 应用allocation transaction创立relay 端口,并在allocation的响应中回复给client。 当allocation创立后须要应用refresh request来保活,默认lifetime为10分钟。 创立Permission:由allocation创立Permission,每个Permission 由 IP 地址 和lifetime组成。 有两种办法来创立和刷新Permission CreatePermissionChannelBind收发数据:CreatePermission应用Send and Data indication音讯ChannelBind应用ChannelData音讯ICE介绍ICE 的角色分为 controlling和controlled。 Offer 一方为controlling角色,answer一方为controlled角色。 2. ICE的模式 分为FULL ICE和Lite ICE: FULL ICE:是单方都要进行连通性查看,实现的走一遍流程。 Lite ICE: 在FULL ICE和Lite ICE互通时,只须要FULL ICE一方进行连通性查看, Lite一方只需回应response音讯。这种模式对于部署在公网的设施比拟罕用。 3. Candidate 媒体传输的候选地址,组成candidate pair做连通性查看,确定传输门路,有如下属性: Type 类型有:Host/Srvflx/Relay/Prflx Componet ID传输媒体的类型,1代表RTP;2代表 RTCP。 WebRTC采纳Rtcp-mux形式,也就是RTP和RTCP在同一通道内传输,缩小ICE的协商和通道的保活。 ...

July 24, 2020 · 2 min · jiezi

WebRTC系列之音频的那些事

WebRTC系列之音频的那些事 年初因为工作需要,开始学习WebRTC,就被其复杂的编译环境和巨大的代码量所折服,注定是一块难啃的骨头。俗话说万事开头难,坚持一个恒心,终究能学习到WebRTC的设计精髓。今天和大家聊聊WebRTC中音频的那些事。WebRTC由语音引擎,视频引擎和网络传输三大模块组成,其中语音引擎是WebRTC中最具价值的技术之一,实现了音频数据的采集、前处理、编码、发送、接受、解码、混音、后处理、播放等一系列处理流程。 音频引擎主要包含:音频设备模块ADM、音频编码器工厂、音频解码器工厂、混音器Mixer、音频前处理APM。 音频工作机制 想要系统的了解音频引擎,首先需要了解核心的实现类和音频数据流向,接下来我们将简单的分析一下。 音频引擎核心类图: 音频引擎WebrtcVoiceEngine主要包含音频设备模块AudioDeviceModule、音频混音器AudioMixer、音频3A处理器AudioProcessing、音频管理类AudioState、音频编码器工厂AudioEncodeFactory、音频解码器工厂AudioDecodeFactory、语音媒体通道包含发送和接受等。 1.音频设备模块AudioDeviceModule主要负责硬件设备层,包括音频数据的采集和播放,以及硬件设备的相关操作。 2.音频混音器AudioMixer主要负责音频发送数据的混音(设备采集和伴音的混音)、音频播放数据的混音(多路接受音频和伴音的混音)。 3.音频3A处理器AudioProcessing主要负责音频采集数据的前处理,包含回声消除AEC、自动增益控制AGC、噪声抑制NS。APM分为两个流,一个近端流,一个远端流。近端(Near-end)流是指从麦克风进入的数据;远端(Far-end)流是指接收到的数据。 4.音频管理类AudioState包含音频设备模块ADM、音频前处理模块APM、音频混音器Mixer以及数据流转中心AudioTransportImpl。 5.音频编码器工厂AudioEncodeFactory包含了Opus、iSAC、G711、G722、iLBC、L16等codec。 6.音频解码器工厂AudioDecodeFactory包含了Opus、iSAC、G711、G722、iLBC、L16等codec。 音频的工作流程图: 1.发起端通过麦克风进行声音采集 2.发起端将采集到的声音信号输送给APM模块,进行回声消除AEC,噪音抑制NS,自动增益控制处理AGC 3.发起端将处理之后的数据输送给编码器进行语音压缩编码 4.发起端将编码后的数据通过RtpRtcp传输模块发送,通过Internet网路传输到接收端 5.接收端接受网络传输过来的音频数据,先输送给NetEQ模块进行抖动消除,丢包隐藏解码等操作 6.接收端将处理过后的音频数据送入声卡设备进行播放 NetEQ模块是Webrtc语音引擎中的核心模块 在 NetEQ 模块中,又被大致分为 MCU模块和 DSP 模块。MCU 主要负责做延时及抖动的计算统计,并生成对应的控制命令。而 DSP 模块负责接收并根据 MCU 的控制命令进行对应的数据包处理,并传输给下一个环节. 音频数据流向 根据上面介绍的音频工作流程图,我们将继续细化一下音频的数据流向。将会重点介绍一下数据流转中心AudioTransportImpl在整个环节中扮演的重要角色。 数据流转中心AudioTransportImpl实现了采集数据处理接口RecordDataIsAvailbale和播放数据处理接口NeedMorePlayData。RecordDataIsAvailbale负责采集音频数据的处理和将其分发到所有的发送Streams。NeedMorePlayData负责混音所有接收到的Streams,然后输送给APM作为一路参考信号处理,最后将其重采样到请求输出的采样率。 RecordDataIsAvailbale内部主要流程: 1.由硬件采集过来的音频数据,直接重采样到发送采样率 2.由音频前处理针对重采样之后的音频数据进行3A处理 3.VAD处理 4.数字增益调整采集音量 5.音频数据回调外部进行外部前处理 6.混音发送端所有需要发送的音频数据,包括采集的数据和伴音的数据 7.计算音频数据的能量值 8.将其分发到所有的发送Streams NeedMorePlayData内部主要流程: 1.混音所有接收到的Streams的音频数据 1.1 计算输出采样率CalculateOutputFrequency() 1.2 从Source收集音频数据GetAudioFromSources(),选取没有mute,且能量最大的三路进行混音 1.3 执行混音操作FrameCombiner::Combine() 2.特定条件下,进行噪声注入,用于采集侧作为参考信号 3.对本地伴音进行混音操作 4.数字增益调整播放音量 5.音频数据回调外部进行外部前处理 6.计算音频数据的能量值 7.将音频重采样到请求输出的采样率 8.将音频数据输送给APM作为一路参考信号处理 由上图的数据流向发现,为什么需要FineAudioBuffer和AudioDeviceBuffer?因为WebRTC 的音频流水线只支持处理 10 ms 的数据,不同的操作系统平台提供了不同的采集和播放时长的音频数据,不同的采样率也会提供不同时长的数据。例如iOS上,16K采样率会提供8ms的音频数据128帧;8K采样率会提供16ms的音频数据128帧;48K采样率会提供10.67ms的音频数据512帧. ...

July 7, 2020 · 1 min · jiezi

前端实时音视频WebRTC入门概览

在前端领域,WebRTC是一个相对小众的技术;但对于在线教育而言,却又是非常的核心。网上关于WebRTC的文章很多,本文将尝试以WebRTC工作过程为脉络进行介绍,让读者对这门技术有一个完整的概念。WebRTC(Web Real-Time Communications)是由谷歌开源并推进纳入W3C标准的一项音视频技术,旨在通过点对点的方式,在不借助中间媒介的情况下,实现浏览器之间的实时音视频通信。 与Web世界经典的B/S架构最大的不同是,WebRTC的通信不经过服务器,而直接与客户端连接,在节省服务器资源的同时,提高通信效率。为了做到这点,一个典型的WebRTC通信过程,包含四个步骤:找到对方,进行协商,建立连接,开始通讯。下面将分别阐述这四个步骤。 第一步:找到对方虽然不需要经过服务器进行通信,但是在开始通信之前,必须知道对方的存在,这个时候就需要信令服务器。 信令服务器所谓信令(signaling)服务器,是一个帮助双方建立连接的「中间人」,WebRTC并没有规定信令服务器的标准,意味着开发者可以用任何技术来实现,如WebSocket或AJAX。 发起WebRTC通信的两端被称为对等端(Peer),成功建立的连接被称为PeerConnection,一次WebRTC通信可包含多个PeerConnection。 const pc2 = new RTCPeerConnection({...});在寻找对等端阶段,信令服务器的工作一般是标识与验证参与者的身份,浏览器连接信令服务器并发送会话必须信息,如房间号、账号信息等,由信令服务器找到可以通信的对等端并开始尝试通信。 其实在整个WebRTC通信过程中,信令服务器都是一个非常重要的角色,除了上述作用,SDP交换、ICE连接等都离不开信令,后文将会提到。 第二步:进行协商协商过程主要指SDP交换。 SDP协议SDP(Session Description Protocol)指会话描述协议,是一种通用的协议,使用范围不仅限于WebRTC。主要用来描述多媒体会话,用途包括会话声明、会话邀请、会话初始化等。 在WebRTC中,SDP主要用来描述: 设备支持的媒体能力,包括编解码器等ICE候选地址流媒体传输协议SDP协议基于文本,格式非常简单,它由多个行组成,每一行都为一下格式: <type>=<value>其中,type表示属性名,value表示属性值,具体格式与type有关。下面是一份典型的SDP协议样例: v=0o=alice 2890844526 2890844526 IN IP4 host.anywhere.coms=c=IN IP4 host.anywhere.comt=0 0m=audio 49170 RTP/AVP 0a=rtpmap:0 PCMU/8000m=video 51372 RTP/AVP 31a=rtpmap:31 H261/90000m=video 53000 RTP/AVP 32a=rtpmap:32 MPV/90000其中: v=代表协议版本号o=代表会话发起者,包括username、sessionId等s=代表session名称,为唯一字段c=代表连接信息,包括网络类型、地址类型、地址等t=代表会话时间,包括开始/结束时间,均为0表示持久会话m=代表媒体描述,包括媒体类型、端口、传输协议、媒体格式等a=代表附加属性,此处用于对媒体协议进行扩展Plan B VS Unified Plan在WebRTC发展过程中,SDP的语义(semantics)也发生了多次改变,目前使用最多的是Plan B和Unified Plan两种。两者均可在一个PeerConnection中表示多路媒体流,区别在于: Plan B:所有视频流和所有音频流各自放在一个m=值里,用ssrc区分Unified Plan:每路流各自用一个m=值目前最新发布的 WebRTC 1.0 采用的是Unified Plan,已被主流浏览器支持并默认开启。Chrome浏览器支持通过以下API获取当前使用的semantics: // ChromeRTCPeerconnection.getConfiguration().sdpSemantics; // 'unified-plan' or 'plan b'协商过程协商过程并不复杂,如下图所示: 会话发起者通过createOffer创建一个offer,经过信令服务器发送到接收方,接收方调用createAnswer创建answer并返回给发送方,完成交换。 // 发送方,sendOffer/onReveiveAnswer为伪方法const pc1 = new RTCPeerConnection();const offer = await pc1.createOffer();pc1.setLocalDescription(offer);sendOffer(offer);onReveiveAnswer((answer) => { pc1.setRemoteDescription(answer);});// 接收方,sendAnswer/onReveiveOffer为伪方法const pc2 = new RTCPeerConnection();onReveiveOffer((offer) => { pc2.setRemoteDescription(answer); const answer = await pc2.createAnswer(); pc2.setLocalDescription(answer); sendAnswer(answer);});值得注意的是,随着通信过程中双方相关信息的变化,SDP交换可能会进行多次。 ...

July 6, 2020 · 3 min · jiezi

基于声网的音视频SDK和FreeSWITCH开发WebRTC2SIP-Gateway-方案和思路一

为什么做这个?今年初接到一个项目任务,客户要求在自己的音视频平台系统中集成webrtc功能(原系统是基于SIP协议开发的,已经稳定运行多年,有很多客户)。在比对了多家RTC产品的效果后,他们对声网音视频DEMO效果后非常满意,指定要求用声网的SD-RTN传输网络,全面改造客户端软件。据客户实测,在某些国家和地区,同样网络环境下比微信要好很多,比如在东非和中国之间语音通话,延迟很小、声音也更清晰。 话不多说,先列下客户要求和当前产品的问题:1.要求全面改造Android、IOS、Windows、MacOS、Web版5个平台的客户端软件,原来的客户端分别是基于Pjsip、Linphone、Sipjs开发的;2.要求在网络环境差的地方,也能满足清晰语音通话的要求(声网专为此而生);3.最小侵入性,尽量不改变服务器端的系统功能,实现客户无感升级;4.解决SIP协议经常碰到丢包、被过滤UDP等无法呼叫,或者呼叫听不清的问题;5.解决SIP服务器经常被尝试攻击呼叫、恶意扫描注册攻击等行为,提高系统稳定性;6.实现WebRTC协议和SIP协议的双向互通,既要兼容SIP呼叫,支持RTC客户端送呼叫到SIP Server,也要支持SIP Server呼入到客户端软件(在声网的音视频实时传输网传输)。 其实刚接到需求的时候,大家一起讨论分析过,觉得这种项目看着有不少预算,但是要做的是全平台的客户端,开发任务繁重,要考虑的细节也比较多,没准是个坑,能不能达到客户期望难说,多数同事不建议做。然后在领导和客户一起去happy一晚后,这活儿不知道怎么就接了下来(⊙⊙) 老板理由很简单,这也不做那也不做,那我们可以做什么?如果谁都能做,客户还会找我们吗? 那就干吧,马上行动,各种查资料,翻阅声网的技术开发文档,并咨询声网的技术同学。2天后拿出了初步方案。 解决思路:1、自己写信令模块,保持灵活性,简单实现:开发TCP Server承担信令服务器;2、核心是开发一个SIP2WebRTC/WebRTC2SIP协议转换网关,维护一个状态机;3、开发音视频编解码处理器,解决声网语音和SIP语音编码互通;4、开发一个状态管理模块,SessionManger,以维护客户端的状态IP+端口;5、结合声网的音视频SDK,集成自己的信令模块,实现和WebRTC2SIP 模块通讯;6、自定义常见的SIP呼叫信令,供各平台客户端保持一致。 常用的SIP 信令有:1注册、2呼叫、3接听、4挂断、5拒接、6取消、7Hold、8DTMF、9用户未反映、10用户离线、11Transfer、12会议(我简单介绍前面的6个) 我们暂且把这个系统命名为 WebRTC2SIP Connector 或者SIP2WebRTC Connector吧。至于为什么这么叫,我也不知道,可能叫XX Gateway的太多了,不这么叫显不出声网的SD-RTN有多牛X,我是他爹,想叫什么都可以( ̄▽ ̄)* 理清思路后,我们需要确认几个核心问题:1、以哪个平台的SDK为基础开发这个WebRTC2SIP Connector 核心模块?2、Agora SDK是否支持多并发呼叫?3、声网的语音编码格式和视频编码格式是什么?采样率多少?4、SIP客户测有没有什么具体的编码要求?客户可接受固定一个语音编码,我选择PCMA 这里特别感谢一下声网,对我们这种小众需求做出了快速响应,也感谢声网技术支持同学Nemo,专门来到公司交流了几个小时,并分享了一些技术信息。 他建议我们:1、用Agora Windows SDK 或者 Linux SDK 开发协议转换模块;2、2个SDK都支持多并发呼叫;3、语音是pcm格式,视频是yuv格式;采样率是48khz 到这里心里有数了,简要文字描述下大概流程就是:1、各客户端SDK启动的时候,发起TCP连接,登录TCP Server信令服务器, WebRTC2SIP转接模块初始化也发起TCP连接登录TCP Server ,由TCP Server记录大家的UID,IP和端口等信息。2、呼叫的时候,申请一个房间号,并根据自定义信令格式发起calling 报文,TCP Server收到后,转发给转接模块WebRTC2SIP ,WebRTC2SIP收到后创建1个线程,解析报文,并启动声网的SDK,加入指定房间号,开始读取音频流程,同时启动线程,封装SIP标准报文,发起sip invite请求给电话服务器SIP Server; SIP Server收到呼叫请求就去呼叫被叫电话号码,并返回ring振铃信号;WebRTC2SIP收到振铃信号,封装自定义的振铃信息给客户端SDK,被叫接听后,WebRTC2SIP,启动Media Coder开始解析媒体流,并resample 后,写入到声网的房间里面。实现语音通话。描述个大概,相信能看明白。3、从SIP呼入到声网的SDK,大同小异,反过来。 这里要注意:1、每个终端都要自定义编号;2、每个呼叫都要加入声网的房间channel 实现音视频互通;3、因为编码不一样,所以需要resample 这个很重要,不要接通了没有声音,双方不匹配。4、WebRTC2SIP 模块要多线程方式处理,以实现并发呼叫;5、WebRTC2SIP 模块要维护一个完整的状态机,给每个通话加唯一编号,不至于出错。 到现在我们讲清楚了大概的解决方案和技术思路,看到这里,各位客官应该明白了,其实这个做起来没啥难度,至少现在看来是这样的。

July 1, 2020 · 1 min · jiezi

极客时间从0打造音视频直播系统课程返现-学习笔记

关注有课学微信公众号,回复 直播 获取购买《从0打造音视频直播系统》极客时间专栏地址,购买成功后提交购买截图即可获得返现,另外送 《从0打造音视频直播系统》专栏学习笔记,待学习笔记更新完成送统一通过微信公众号发放。 《从0打造音视频直播系统》专栏作者为李超,新东方音视频直播技术专家,前沪江音视频架构师。 可以预见在未来两三年内,随着 5G 的到来,类似目前常见的抖音、微信短视频、娱乐直播、教育直播、音视频会议音视频技术会是大势,也必定会像当年移动互联网一样出现井喷的人才需求,音视频人才会成为新的宠儿。面对这样的机遇,你若能掌握音视频技术的核心技术,一定可以在未来职场上获得丰厚的回报和满满的成就感。专栏分为 3 大模块 WebRTC 1 对 1 通话主要讲解如何在浏览器间实现 1 对 1 通话,比如一个人在北京,另一个人在上海,他们打开浏览器进入同一个房间后,就可以进行音视频通话了。这一模块精编了环环相扣的 22 篇文章,每篇文章对应一个实现 WebRTC 1 对 1 通话的主题。也就是说,这 22 篇文章是可以串联为一个即学即用的 1 对 1 实时通话的例子。WebRTC 多人音视频实时通话主要探讨如何实现多人音视频实时互动。首先为你介绍几种多人音视频实时互动的架构,以及它们的优劣;然后,再重点讲解如何使用 SFU 架构实现多人音视频实时通话(SFU 是现在最流行的多人实时互动架构)。学完本模块内容后,你就可以亲手实现多人音视频实时通话了。支持上万人同时在线的直播系统重点介绍 CDN 原理、RTMP、HLS 协议,以及如何使用各种播放器从 CDN 拉取媒体流。其中,CDN 是支持上万人同时在线直播系统的主要技术,而 RTMP 和 HLS 是其使用的底层传输协议。学完本模块内容后,你就会清楚地知道上万人同时在线直播的原理,并可以自己实现一套这样的直播系统。

July 15, 2019 · 1 min · jiezi

Centos-下安装-WebRTC

一、环境安装安装 java yum -y install java-1.8.0-openjdk*安装 node.js curl -sL https://rpm.nodesource.com/setup_10.x | bash -yum install -y nodejs# 确认是否成功node --versionnpm --version# 构建 apprtc 用到npm -g install grunt-cligrunt --version安装 python 和 python-webtest # 安装epel扩展源yum -y install epel-releaseyum install python python-webtest python-pippip install --upgrade pip安装 google_appengine mkdir /root/webrtccd /root/webrtcwget https://storage.googleapis.com/appengine-sdks/featured/google_appengine_1.9.40.zip# 安装 unzip 解压工具yum -y install unzip unzip google_appengine_1.9.40.zip 配置环境变量,在 /etc/profile 文件最后增加下列代码: export GOOGLE_ENGINE_HOME=/root/webrtc/google_appengineexport PATH=$PATH:$GOOGLE_ENGINE_HOME使环境变量生效 source /etc/profile安装 go yum -y install go #安装 Golang创建 go 工作目录 ...

June 4, 2019 · 4 min · jiezi

纯js实现web端录音与播放功能

纯js实现web端录音功能,功能并不是特别多,逐步增加中,详细地址:github。getUserMedia在非localhost和127的情况下,需要开启https,由于腾讯云的没备案,demo就不放了,可以自行获取代码并启动测试。实现方式实现原理的话,主要是以下三点,利用webrtc的getUserMedia方法获取设备音频输入,使用audioprocess得到音频流(pcm流,范围-1到1)。转码,利用前端中的ArrayBuffer等二进制操作按采样位数处理流信息。使用decodeAudioData转码arraybuffer到audioBuffer并播放(小文件,大文件使用audio)。使用方式script方式直接引入dist下的recorder.js即可let recorder = new Recorder();npm方式安装:npm i js-audio-recorder调用:import Recorder from ‘js-audio-recorder’;let recorder = new Recorder();API基本方法// 开始录音recorder.start();// 暂停录音recorder.pause();// 继续录音recorder.resume()// 结束录音recorder.stop();// 录音播放recorder.play();// 销毁录音实例,释放资源,fn为回调函数,recorder.destroy(fn);recorder = null;下载功能// 下载pcm文件recorder.downloadPCM();// 下载wav文件recorder.downloadWAV();// 重命名pcm文件,wav也支持recorder.downloadPCM(‘重命名’);获取录音时长// 回调持续输出时长recorder.onprocess = function(duration) { console.log(duration);}// 手动获取录音时长console.log(recorder.duration);默认配置sampleBits,采样位数,默认是16 sampleRate,采样频率,浏览器默认的,我的chrome是48000 numChannels,声道数,默认是1传入参数new Recorder时支持传入参数,{ sampleBits: 16, // 采样位数,范围8或16 sampleRate: 16000, // 采样率,范围11025、16000、22050、24000、44100、48000 numChannels: 1, // 声道,范围1或2}注意使用127.0.0.1或localhost尝试,因为getUserMedia在高版本的chrome下需要使用https。兼容性主要是以下几个方面:Web Audio Apihttps://caniuse.com/#search=w…getUserMediahttps://caniuse.com/#search=g…Typed Arrayshttps://caniuse.com/#search=t…欢迎访问和查看:recorder。其他资源基于阿里云实现简单的语音识别功能web Audio学习与音频播放web Audio实现pcm音频数据收集js实现pcm数据编码js转化pcm到wav格式与播放

April 17, 2019 · 1 min · jiezi

WebRTC学习资料整理

目前在做基于WebRTC的语音和视频终端,语音和视频通话的质量都不错。感谢WebRTC,站在巨人的肩膀上,我们可以看得更远。WebRTC浏览器兼容性参考:https://caniuse.com/#search=w…github demos下面两个都是github项目,项目中有各种WebRTC的demo。除了demo之外,这两个项目的issuese也是非常值得看的,可以解决常见的问题https://webrtc.github.io/samp…https://github.com/muaz-khan/…相关资料网站webrtc官网: https://webrtc.org/webrtchacks: https://webrtchacks.com/webrtc官网: https://webrtc.org.cn/webrtc安全相关: http://webrtc-security.github...webrtc谷歌开发者教程: https://codelabs.developers.g...sdp for webrtc https://tools.ietf.org/id/dra…各种资料 https://webrtc.org/start/https://www.w3.org/TR/webrtc/浏览器内核webkit官网:https://webkit.org/WebRTC相关库webrtc-adapter https://github.com/webrtchack...WebRTC周边js库库地址Addlivehttp://www.addlive.com/platfo…Apidazehttps://developers.apidaze.io…Bistrihttp://developers.bistri.com/…Crocodilehttps://www.crocodilertc.net/…EasyRTChttp://www.easyrtc.com/docs/Janushttp://janus.conf.meetecho.co…JsSIPhttp://jssip.net/documentation/Openclovehttp://developer.openclove.co…Oraclehttp://docs.oracle.com/cd/E40…Peerjshttp://peerjs.com/docs/#apiPhonohttp://phono.com/docsPlivohttps://plivo.com/docs/sdk/web/Pubnubhttp://www.pubnub.com/docs/ja…Quobishttps://quobis.atlassian.net/…SimpleWebRTC from &Yethttp://simplewebrtc.com/SIPML5http://sipml5.org/docgen/symb…TenHandshttps://www.tenhands.net/deve…TokBoxhttp://tokbox.com/opentokTwiliohttp://www.twilio.com/client/apiVoximplanthttp://voximplant.com/docs/re…Vlinehttps://vline.com/developer/d…Weemohttp://docs.weemo.com/js/Xirsyshttp://xirsys.com/_static_con…Xsockets.nethttp://xsockets.net/docs/java…VoIP/PSTNhttps://kamailio.orghttps://freeswitch.org/值得关注的人https://github.com/muaz-khanhttps://github.com/chadwallac…https://github.com/fippoWebRTC主题github上webrtc主题相关的仓库,干货非常多 https://github.com/topics/webrtc相关文章guide-to-safari-webrtcWebKit: On the Road to WebRTC 1.0, Including VP8whats-in-a-webrtc-javascript-library

March 31, 2019 · 1 min · jiezi

WebRTC 入门教程(一)| 搭建WebRTC信令服务器

作者:李超,音视频技术专家。本入门教程将分为三篇内容,分别讲述信令服务器的搭建、媒体服务器的搭建、Android 端的 WebRTC 应用实现,全文采用开源框架来搭建,适用于大多数入门的开发者。转载请注明出处。如遇到 WebRTC 开发问题,可以点击这里,关注作者与他交流。前言我们在学习 WebRTC 时,首先要把实验环境搭建好,这样我们就可以在上面做各种实验了。对于 WebRTC 来说,它有一整套规范,如怎样使用它的接口、使用SDP进行媒体协商、通过ICE收集地址并进行连通性检测等等。除此之外,WebRTC还需要房间服务器将多端聚集到一起管理,以及信令服务器进行信令数据交换(如媒体描述信息SDP的交换,连接地址的交抽换等),但在WebRTC的规范中没有对这部分内容进行规定,所以需要由用户自己处理。你可以根据自己的喜好选择服务器(如 Apache,Nginx 或 Nodejs),我今天将介绍如何使用 Nodejs 来搭建信令服务器。为什么选择 NodejsApache、Nginx和Nodejs都是非常成熟的Web服务器,Nginx 可以说是的性能是最好的Web服务器了。但从未来的发展来说,Nodejs可能会更有优势。现在以Chrome为代表的浏览器的功能越来越强大,以前认为通过浏览器不可能完成的事儿,现在它都可以轻松实现。H5、 WebSocket的出现以及现在WebRTC的加入,让大家越来越觉得以后的浏览器可以说是“无所不能”。因此,推动 JavaScript 语言的发展越来越迅速。这可以从现在 JavaScript 技术的火爆,以及各种层叠不穷JS FrameWork的出现得以印证。而 Nodejs 的最大优点即是可以使用 JS 语言开发服务器程序。这样使得大量的前端同学可以无缝的转到服务器开发,甚至有可能前后端使用同一套代码实现。对于这一点我想无论是对个人还是对于企业都是具大的诱惑。一方面 JS 语言的简单性可以方便开发出各种各样功能的服务端程序。更可贵的是 Nodejs 的生态链非常的完整,有各种各样的功能库。你可以根据自己的需要通过安装工具 NPM 快速的安装,这也使它也得到了广大开发者的喜欢。Nodejs 现在是非常流行的 Web 服务器,它在服务器端使用 V8(JavaScript)引擎,通过它解析 JS 脚本来控制服务器的行为。这对于广大的 JS 同学来说真是太幸福了,在10年前还很难想像可以通过 JS 脚本语言来写服务器程序。当然,如果你想对Nodejs作能力拓展的话,还是要写C/C++库,然后加载到 Nodejs 中去。Nodejs的基本原理Nodejs的工作原理如上图所示, 其核心是 V8 引擎。通过该引擎,可以让 js 调用 C/C++方法 或 对象。相反,通过它也可能让 C/C++ 访问 javascript 方法和变量。Nodejs 首先将 JavaScript 写好的应用程序交给 V8 引擎进行解析,V8理解应用程序的语义后,再调用 Nodejs 底层的 C/C++ API将服务启动起来。 所以 Nodejs 的强大就在于 js 可以直接调用 C/C++ 的方法,使其能力可以无限扩展。以开发一个 HTTP 服务为例,Nodejs 打开侦听的服务端口后,底层会调用 libuv 处理该端口的所有 http 请求。其网络事件处理如下图所示: 当有网络请求过来时,首先会被插入到一个事件处理队列中。libuv会监控该事件队列,当发现有事件时,先对请求做判断,如果是简单的请求,就直接返回响应了;如果是复杂请求,则从线程池中取一个线程进行异步处理;线程处理完后,有两种可能:一种是已经处理完成,则向用户发送响应;另一种情况是还需要进一步处理,则再生成一个事件插入到事件队列中等待处理;事件处理就这样循环往复下去,永不停歇。两个 V8 引擎如上图所示,在我们使用 Nodejs之后实际存在了两个 V8 引擎。一个V8用于解析服务端的 JS 应用程序,它将服务启动起来。另一个 V8 是浏览器中的 V8 引擎,用于控制浏览器的行为。对于使用 Nodejs 的新手来说,很容易出现思维混乱,因为在服务端至少要放两个 JS 脚本。其中一个是服务端程序,控制 Nodejs 的行为,它由 Nodejs 的V8引擎解析处理;另一个是客户端程序,它是要由浏览器请求后,下发到浏览器,由浏览器中的 V8 引擎进行解析处理。如果分不清这个,那麻烦就大了。安装 Nodejs下面我们就来看看具体如何安装 Nodejs。安装 Nodejs 非常的简单: 在Ubuntu系统下执行:apt install nodejs或在Mac 系统下执行:brew install nodejs通过上面的步骤我们就将 Nodejs 安装好了。我这里安装的 Nodejs版本为:v8.10.0。安装NPM除了安装 Nodejs 之外,我们还要安装NPM(Node Package Manager),也就是 Nodejs 的包管理器。它就像Ubuntu下的 apt 或Mac 系统下的brew 命令类似,是专门用来管理各种依赖库的。在它们没有出现之前,我们要安装个包特别麻烦。以Linux为例,假设要安装一个工具,其基本步骤是:先将这个工具的源码下载下来。执行./configure 生成Makefile 文件。执行 make 命令对其进行编译。最后,执行 make install 将其安装到指定目录下。如果编译过程中发现有依赖的库,则要对依赖库执行前面的4步,也就是先将依赖库安装好,然后再来安装该工具。大家可以看到,以前在Linux下安装个程序或工具是多么的麻烦。Linux 有了apt 之后,一切都变得简单了。我们只要执行 apt install xxx 一条命令就好了,它会帮你完成上面的一堆操作。对于 Nodejs的安装包也是如此,NPM 就是相当于 Linux 下的 apt,它的出现大大提高了人们的工作效率。NPM 的安装像安装 Nodejs 一样简单:在Ubuntu下执行:apt install npm或在Mac下执行:brew install npmsocket.io此次,我们使用 Nodejs 下的 socket.io 库来实现 WebRTC 信令服务器。socket.io特别适合用来开发WebRTC的信令服务器,通过它来构建信令服务器特别的简单,这主要是因为它内置了房间 的概念。上图是 socket.io 与 Nodejs配合使用的逻辑关系图, 其逻辑非常简单。socket.io 分为服务端和客户端两部分。服务端由 Nodejs加载后侦听某个服务端口,客户端要想与服务端相连,首先要加载 socket.io 的客户端库,然后调用 io.connect();就与服务端连上了。需要特别强调的是 socket.io 消息的发送与接收。socket.io 有很多种发送消息的方式,其中最常见的有下面几种,是我们必须要撑握的:给本次连接发消息socket.emit()给某个房间内所有人发消息io.in(room).emit()除本连接外,给某个房间内所有人发消息socket.to(room).emit()除本连接外,给所以人发消息socket.broadcast.emit()消息又该如何接收呢?发送 command 命令S: socket.emit(‘cmd’);C: socket.on(‘cmd’,function(){…});送了一个 command 命令,带 data 数据S: socket.emit(‘action’, data);C: socket.on(‘action’,function(data){…});发送了command命令,还有两个数据S: socket.emit(action,arg1,arg2);C: socket.on(‘action’,function(arg1,arg2){…});有了以上这些知识,我们就可以实现信令数据通讯了。搭建信令服务器接下来我们来看一下,如何通过 Nodejs下的 socket.io 来构建的一个服务器:这是客户端代码,也就是在浏览器里执行的代码。index.html:<!DOCTYPE html><html> <head> <title>WebRTC client</title> </head> <body> <script src=’/socket.io/socket.io.js’></script> <script src=‘js/client.js’></script> </body></html>该代码十分简单,就是在body里引入了两段 JS 代码。其中,socket.io.js 是用来与服务端建立 socket 连接的。client.js 的作用是做一些业务逻辑,并最终通过 socket 与服务端通讯。首先,在server.js目录下创建 js 子目录,然后在 js目录下生成 client.js。下面是client.js的代码:var isInitiator;room = prompt(‘Enter room name:’); //弹出一个输入窗口const socket = io.connect(); //与服务端建立socket连接if (room !== ‘’) { //如果房间不空,则发送 “create or join” 消息 console.log(‘Joining room ’ + room); socket.emit(‘create or join’, room);}socket.on(‘full’, (room) => { //如果从服务端收到 “full” 消息 console.log(‘Room ’ + room + ’ is full’);});socket.on(’empty’, (room) => { //如果从服务端收到 “empty” 消息 isInitiator = true; console.log(‘Room ’ + room + ’ is empty’);});socket.on(‘join’, (room) => { //如果从服务端收到 “join" 消息 console.log(‘Making request to join room ’ + room); console.log(‘You are the initiator!’);});socket.on(’log’, (array) => { console.log.apply(console, array);});在该代码中:首先弹出一个输入框,要求用户写入要加入的房间。然后,通过 io.connect() 建立与服务端的连接,根据socket返回的消息做不同的处理:当收到房间满"full"时的情况;当收到房间空“empty"时的情况;当收到加入“join"时的情况;以上是客户端(也就是在浏览器)中执行的代码。下面我们来看一下服务端的处理逻辑:服务器端代码,server.js:const static = require(’node-static’);const http = require(‘http’);const file = new(static.Server)();const app = http.createServer(function (req, res) { file.serve(req, res);}).listen(2013);const io = require(‘socket.io’).listen(app); //侦听 2013io.sockets.on(‘connection’, (socket) => { // convenience function to log server messages to the client function log(){ const array = [’>>> Message from server: ‘]; for (var i = 0; i < arguments.length; i++) { array.push(arguments[i]); } socket.emit(’log’, array); } socket.on(‘message’, (message) => { //收到message时,进行广播 log(‘Got message:’, message); // for a real app, would be room only (not broadcast) socket.broadcast.emit(‘message’, message); //在真实的应用中,应该只在房间内广播 }); socket.on(‘create or join’, (room) => { //收到 “create or join” 消息 var clientsInRoom = io.sockets.adapter.rooms[room]; var numClients = clientsInRoom ? Object.keys(clientsInRoom.sockets).length : 0; //房间里的人数 log(‘Room ’ + room + ’ has ’ + numClients + ’ client(s)’); log(‘Request to create or join room ’ + room); if (numClients === 0){ //如果房间里没人 socket.join(room); socket.emit(‘created’, room); //发送 “created” 消息 } else if (numClients === 1) { //如果房间里有一个人 io.sockets.in(room).emit(‘join’, room); socket.join(room); socket.emit(‘joined’, room); //发送 “joined”消息 } else { // max two clients socket.emit(‘full’, room); //发送 “full” 消息 } socket.emit(’emit(): client ’ + socket.id + ’ joined room ’ + room); socket.broadcast.emit(‘broadcast(): client ’ + socket.id + ’ joined room ’ + room); });});在服务端引入了 node-static 库,使服务器具有发布静态文件的功能。服务器具有此功能后,当客户端(浏览器)向服务端发起请求时,服务器通过该模块获得客户端(浏览器)运行的代码,也就是上我面我们讲到的 index.html 和 client.js 并下发给客户端(浏览器)。服务端侦听 2013 这个端口,对不同的消息做相应的处理:服务器收到 message 消息时,它会直接进行广播,所有连接到该服务器的客户端都会收收广播的消息。服务端收到 “create or join”消息时,它会对房间里有人数进行统计,如果房间里没有人,则发送"created" 消息;如果房间里有一个人,发送"join"消息和“joined"消息;如果超过两个人,发送"full"消息。要运行该程序,需要使用 NPM 安装 socket.io 和 node-static,安装方法如下:进入到 server.js 所在的目录,然后执行下面的命令。npm install socket.ionpm install node-static启动服务器并测试通过上面的步骤我们就使用 socket.io 构建好一个服务器,现在可以通过下面的命令将服务启动起来了:node server.js如果你是在本机上搭建的服务,则可以在浏览器中输入 localhost:2013 ,然后新建一个tab 在里边再次输入localhost:2013 。此时,打开控制台看看发生了什么? 在Chrome下你可以使用快捷键 Command-Option-J或Ctrl-Shift-J的DevTools访问控制台。小结以上我向大家介绍了 Nodejs 的工作原理、Nodejs的安装与布署,以及如何使用 要sokcet.io 构建 WebRTC 信令消息服务器。socket.io 由于有房间的概念所以与WebRTC非常匹配,用它开发WebRTC信令服务器非常方便。另外,在本文中的例子只是一个简单例子并没有太多的实际价值。在后面的文章中我会以这个例子为基础,在其上面不断增加一些功能,最终你会看到一个完整的Demo程序。 ...

March 19, 2019 · 3 min · jiezi

【入门】WebRTC知识点概览 | 内有技术干货免费下载

什么是WebRTCWebRTC 即Web Real-TimeCommunication(网页实时通信)的缩写,是一个支持网页浏览器之间进行实时数据传输(包括音频、视频、数据流)的技术。经过多年的发展与改进,日臻成熟,作为浏览器网页端的通信技术,WebRTC与H5巧妙结合,使得网页端的音视频通信变的简单易行。WebRTC有哪些优点免费:WebRTC本身是开源的,使用WebRTC本身是免费的。此外WebRTC是可以不借助媒体服务器实现简单的点对点音视频通信,减少额外花费。无插件:不需要安装任何软件,大家只要打开浏览器,输入一个url,即可实现多人音视频通话。跨平台:由于是基于浏览器进行音视频通话,各个平台只要有浏览器即可。控制灵活:WebRTC没有指定具体的信令协议,具体的信令协议留给应用程序实现,这就方便了开发者根据自己的需求方便灵活的实现各种音视频业务场景。接合HTML5:HTML5自身的能力能够为WebRTC提供灵活快捷的音视频数据的二次处理,可以实现丰富的业务功能。易入门:WebRTC是’JavaScript’引擎库,允许web开发者只使用几个简单的api就能够基于浏览器轻易快捷开发出丰富的实时多媒体应用,无需关注多媒体的数字信号处理过程,只需要编写简单的JavaScript即可,大大的降低了音视频开发的门槛。WebRTC距离商用还有多少距离信令控制协议的开发:上面说明过WebRTC并没有实现信令协议,这既带来了灵活,也带来了挑战,想实现一套满足商业应用业务的信令并不容易。跨平台的挑战:即对浏览器使用不便,或者不支持浏览器(各种盒子或者嵌入式设备)的实际环境的兼容。音视频设备的适配:音视频设备支持的能力不同,需要自己的WebRTC产品做复杂的适配处理,才能满足自己的业务场景。浏览器限制:并非所有的浏览器都支持WebRTC,具体请参考浏览器兼容性;各个浏览器厂商工业实现上的兼容。对于WebRTC,各大浏览器厂商实现的并不完全一致,比如说Safari浏览器不支持VP8系列视频编码,一些安卓移动设备上Chrome无法使用H264视频编码,还有其他很多细节问题,想要实现各种平台,各种浏览器之间无障碍的互通,还需要很多工作要做;浏览器版本更迭的兼容,浏览器本身也是在不停的更新对WebRTC的工业实现,也不断更新对HTML5的使用,这些更新对于我们的WebRTC产品也是一大挑战。需要各种服务器的支持:现实情况中,WebRTC应用需要信令服务器、媒体服务器、中继服务器的支持,才能实现信令的有效稳定传输、NAT的穿越、媒体的合理路由和转发,进而保障稳定、高质量的音视频通话。而且针对大并发量的使用场景,需要合理的媒体处理框架设计,用于保证音视频服务的可靠性、稳定性。为什么选择云信专业:研发资历成熟,19年通信领域研发深耕,亿级产品线上验证,移动端方案优化7年以上;全球节点覆盖异地多机房服务集群,覆盖全球范围,架构灵活高并发自动水平扩容;消息必达策略采用动态智能DNS掉线快速重连机制,消息排重持续重连直至到达,保障通信的接通率;海量资源支持全球超500个CDN节点,超10000个分布式转码集群,千万播放并发,存储、宽带无上限。接入和使用灵活:网易云信提供即时通讯云和视频云技术的PaaS层服务,以快速集成SDK的模式为开发者提供稳定易用的技术支撑,客户可以方便快捷地接入,全面满足自己的业务需求。全平台支持:支持iOS、Android、Windows、Web、Linux、MacOS、微信小程序等主流平台观看、互动及互通,支持点对点、多人实时音视频通话和旁路直播等功能。IM信令:网易云通信IM服务基于网易19年的IM技术积累,致力于打造最稳定的即时通讯平台。 IM服务提供了一整套即时通讯基础能力,通过该平台服务就可以将即时通讯、实时网络能力快速集成至企业自身应用中。使用IM信令作为WebRTC产品的信令协议必定能满足用户的各种需求。WebRTC SDK的能力:云信SDK兼容各大浏览器,各种版本,对于用户而言所有的浏览器类型,所有的版本都是一致的,所有的差异由SDK统一解决,对用户不可见。WebRTC相关知识点关于WebRTC首先明确一些内容:WebRTC利用浏览器中的JavaScript API和HTML5WebRTC客户端之间可以进行点对点的媒体和数据传输webrtc使用sdp协议作为媒体协商协议webrtc使用ice作为nat穿越的手段WebRTC 标准APIgetUserMida:通过getUserMida的API能够通过设备的摄像头和话筒获得视频、音频的同步流;允许约束媒体能力获取的媒体流可以输出到video标签在web页面上展示;获取的媒体流可以输出到一个RTCPeerConnection中,用于编码、发送到对端;可以使用HTML5本身的能力对音频、视频做二次处理,比如混频、混频、变声、调色能,将处理后的媒体在推送给对端;可以本地录制获取到媒体流,也可以把获取到媒体流用于他出;RTCPeerConnection:RTCPeerConnection(免费下载《WebRTC 1.0: 浏览器间实时通讯》中文版)是WebRTC用于构建点对点之间稳定、高效的流传输的媒体终端;进行sdp交换协商媒体使用ice进行nat穿透dtls协商加密秘钥srtp加密媒体媒体编解码,媒体收发丢包补偿、回声抵消、带宽自动调整、动态抖动缓冲、噪声抑制与抑制等RTCDataChannel:RTCDataChannel(免费下载《WebRTC 1.0: 浏览器间实时通讯》中文版)使得浏览器之间(点对点)建立一个高吞吐量、低延时的信道,用于传输任意数据;利用RTCPeerConnection会话自定义可靠和不可靠通道dtls阻塞控制WebRTC点对点音视频通信过程使用getUserMida接口获取本地mic、camera上音频流和视频流本地初始化一个RTCPeerConnection实例将通过getUserMida接口获取的本地音频流和视频流,展示到html页面上,并且添加到RTCPeerConnection实例中通过RTCPeerConnection实例获取本端的sdp信息(本地媒体描述信息)通过信令协议把本地的sdp发送到对端通过RTCPeerConnection实例,获取本地媒体通道地址,然后通过信令协议发送到对端接收对端的sdp信息、媒体通道地址,然后设置到RTCPeerConnection实例中,这样就完成了媒体协商从RTCPeerConnection实例中获取对端的媒体流,可以展示到html页面上经过上面的步骤,双方就能进行点对点视频通话了,后续的nat穿透、dtls协商加密秘钥、srtp加密媒体、媒体编解码,媒体收发都由浏览器自动完成。Chrome屏幕共享功能的实现 上面说明获取摄像头的媒体流是通过getUserMida接口,而获取屏幕共享则是通过其他的方式; - 使用getDisplayMedia接口(chrome 72版本开始支持)使用方式同getUserMedia接口一致,代码如下:if (navigator.getDisplayMedia) {returnnavigator.getDisplayMedia({video: true});} else if(navigator.mediaDevices.getDisplayMedia) {return navigator.mediaDevices.getDisplayMedia({video:true});}通过插件的方式自己编写extension插件扩展,使用chrome.desktopCapture.chooseDesktopMedia接口(插件是经过了认证的,浏览器不会阻止其运行),调用这个接口时,浏览器弹出包含各种共享内容(包括屏幕、应用列表、chrome标签页)的弹窗。用户可以选择自己想要共享的内容,选定之后,该接口会返回相应的chromeMediaSourceId,然后使用getUserMeida接口把chromeMediaSourceId作为约束条件,就能够获取到共享的媒体流。插件代码如下:chrome.runtime.onMessageExternal.addListener((message,sender, sendResponse) => {const sources =message.sources;const tab =sender.tab;chrome.desktopCapture.chooseDesktopMedia(sources, tab, streamId => {if(!streamId) {sendResponse({type:’error’,message:‘Failed to get stream ID’});} else {sendResponse({type:‘success’,streamId:streamId});}});return true;});chrome.runtime.onInstalled.addListener(function(){chrome.declarativeContent.onPageChanged.removeRules(undefined,function(){chrome.declarativeContent.onPageChanged.addRules([{conditions: [newchrome.declarativeContent.PageStateMatcher({ pageUrl: { urlContains: ‘app.netease.im’}})],actions: [new chrome.declarativeContent.ShowPageAction()]}]);});});getUserMedia接口的使用如下:chrome.runtime.sendMessage(EXTENSION_ID, { sources:[‘window’, ‘screen’, ’tab’] }, {}, response => {if (response&& response.type === ‘success’) {constconstraint = {video: {mandatory: {chromeMediaSource: ‘desktop’,chromeMediaSourceId: response.streamId}}}returnnavigator.mediaDevices.getUserMedia(constraint)(constraint).then(stream => {console.log(‘获取到演示流:’,stream.id)})}})Chrome 72版本unified plan适配对WebRTC而言,Unified Plan、Plan B、Plan A是SDP中多路媒体流的协商方式,在72版本中Chrome替换了Plan B,默认使用Unified Plan。https://webrtc.github.io/samp…{ iceServers: [], iceTransportPolicy: all, bundlePolicy: balanced,rtcpMuxPolicy: require, iceCandidatePoolSize: 0, sdpSemantics:“unified-plan” },Plan B:sdp中,一个m行描述多路media stream,以msid作为区分;…a=group:BUNDLE audioa=msid-semantic: WMS stream-id-2 stream-id-1m=audio 9 UDP/TLS/RTP/SAVPF 111 103 104 9 0 8 106 105 13110 112 113 126…a=mid:audio…a=rtpmap:103 ISAC/16000…a=ssrc:10 cname:cnamea=ssrc:10 msid:stream-id-1 track-id-1a=ssrc:10 mslabel:stream-id-1a=ssrc:10 label:track-id-1a=ssrc:11 cname:cnamea=ssrc:11 msid:stream-id-2 track-id-2a=ssrc:11 mslabel:stream-id-2a=ssrc:11 label:track-id-2Unified Plan:sdp中,一个m行对应一个meida stream;…a=group:BUNDLE 0 1a=msid-semantic: WMSm=audio 9 UDP/TLS/RTP/SAVPF 111 103 104 9 0 8 106 105 13110 112 113 126…a=mid:0…a=sendrecva=msid:-…a=rtpmap:103 ISAC/16000…a=ssrc:10 cname:cnamea=ssrc:10 msid: track-id-1a=ssrc:10 mslabel:a=ssrc:10 label:track-id-1m=audio 9 UDP/TLS/RTP/SAVPF 111 103 104 9 0 8 106 105 13110 112 113 126…a=mid:1…a=sendrecva=msid:- track-id-2…a=rtpmap:103 ISAC/16000…a=ssrc:11 cname:cnamea=ssrc:11 msid: track-id-2a=ssrc:11 mslabel:a=ssrc:11 label:track-id-2一、点对点视频通话业务1、WebRTC产品中没有处理过sdp中的msid属性不用适配,此次的更新对你的产品没有影响2、WebRTC产品中有处理sdp中的msid属性需要适配,凡是针对msid的判断和修改都需要废弃,重新处理二、多流业务,使用了simulcast1、WebRTC产品中没有处理过sdp中的msid属性需要适配,调整接口使用,调整sdp的解析处理,增加多m行的处理2、WebRTC产品中有处理sdp中的msid属性需要适配,凡是针对msid的判断和修改都需要废弃,重新处理,调整接口使用,调整sdp的解析处理,增加多m行的处理WebRTC调试Chrome浏览器查看WebRTC状态方法:chrome:chrome://webrtc-internals浏览器中输入chrome://webrtc-internals,界面显示如下:WebRTC状态图WebRTC状态图说明: 最上面一排依次是:getUserMediaAPI、二个peerconnection API[if !supportLists]· [endif]点击查看getUserMedia API,简单说明如下:Caller origin: https://webrtc.github.ioCaller process id: 15364Audio ConstraintsVideo Constraints{width: {min: 300, max: 640}, height: {min: 200, max:480}}[if !supportLists]· [endif]Audio Constraints:表示从麦克风获取视屏流的参数;Video Constraints:表示从摄像头获取视屏流的参数;PeerConnection状态图PeerConnection状态图说明:[if !supportLists]· [endif]最上面的一行:表示peerconnection,大括号中的内容是peerconnection的配置参数,可以看到chrome已经用unified-plan替代了plan B;[if !supportLists]· [endif]左上角的Event:peerconnection的内部接口,对应的是内部接口[if !supportLists]o [endif]transceiverAdded:添加getUserMeida接口获取的媒体流[if !supportLists]o [endif]transceiverModified:接收对端的媒体流[if !supportLists]o [endif]createOffer:浏览器生成的本地sdp[if !supportLists]o [endif]setLocalDescription:设置本地sdp[if !supportLists]o [endif]setRemoteDescription:设置远端sdp[if !supportLists]o [endif]signalingstatechange:peerconnection的状态(免费下载《[WebRTC 1.0: 浏览器间实时通讯》中文版][6])icegatheringstatechange:本地ice候选地址收集的状态(免费下载《WebRTC 1.0: 浏览器间实时通讯》中文版)[if !supportLists]o [endif]icecandidate:候选地址的收集接口[if !supportLists]o [endif]iceconnectionstatechange:ICE连通性检查的状态(免费下载《WebRTC 1.0: 浏览器间实时通讯》中文版)[if !supportLists]· [endif]右上角的EventStatsTables:是媒体通道的具体信息,数据实时更新[if !supportLists]o [endif]bweforvideo(VideoBwe):视频带宽相关信息[if !supportLists]§ [endif]googActualEncBitrate:视频编码器实际编码的码率,通常这与目标码率是匹配的。[if !supportLists]§ [endif]googAvailableReceiveBandwidth:视频数据接收可用的带宽。[if !supportLists]§ [endif]googAvailableSendBandwidth:视频数据发送可用的带宽。[if !supportLists]§ [endif]googBucketDelay:Google为了处理大数据速率的策略表示,通常是很小的数值。[if !supportLists]§ [endif]googRetransmitBitrate:如果RTX被使用的话,表示重传的码率。[if !supportLists]§ [endif]googTargetEncBitrate:视频编码器的目标比特率。[if !supportLists]§ [endif]googTansmitBitrate:实际发送的码率,如果此数值与googActualEncBitrate有较大的出入,可能是fec的影响。[if !supportLists]o [endif]googCertificate:两端使用的DTLS证书、指纹和哈希算法等[if !supportLists]o [endif]googComponent:表示认证数据与连接之间的关系,展示当前活跃的候选项对,以及有关用语DTLS和SRTP加密的相关信息。[if !supportLists]o [endif]Conn-video-1-0(googCandidatePair):RTP通道相关信息[if !supportLists]§ [endif]googActiveConnection:当前的连接是否活跃[if !supportLists]§ [endif]bytesReceived:接收的字节数(rtp数据)[if !supportLists]§ [endif]bytesSent:发送的的字节数(rtp数据)[if !supportLists]§ [endif]packetsSent:发送的数据包数(rtp数据)[if !supportLists]§ [endif]requestsSent、responsesSent、requestsReceived、responsesReceived:STUN请求和应答数量[if !supportLists]§ [endif]googRtt:最近的STUN请求的往返时间[if !supportLists]§ [endif]googLocalAddress:本地的候选地址[if !supportLists]§ [endif]googRemoteAddress:远端的候选地址[if !supportLists]§ [endif]googTransportType:传输通道的类型,通常是udp,即使当前正在使用tcp的连接方式通过turn中继服务器转发媒体,只有当ICE-TCP被选用时,这里才会是tcp[if !supportLists]o [endif]Conn-video-1-1(googCandidatePair):RTCP通道相关[if !supportLists]o [endif]ssrc_2052494919_send(ssrc):音频发送通道相关信息[if !supportLists]§ [endif]audioInputLevel:mic采集的音频能量值[if !supportLists]§ [endif]audioOutputLevel:扬声器播出的音频能力值[if !supportLists]§ [endif]bytesSent:发送的音频数据字节数[if !supportLists]§ [endif]mediaType:媒体类型[if !supportLists]§ [endif]packetsSent:发送的音频包数[if !supportLists]§ [endif]ssrc:音频rtp包的ssrc[if !supportLists]§ [endif]googCodecName:音频编码名称[if !supportLists]§ [endif]googJitterReceived:收到了多少的抖动[if !supportLists]§ [endif]googRtt:是发送端从接受端发送过来的RTCPReceiver Report中得到的时间戳通过计算得到的往返时延[if !supportLists]o [endif]ssrc_4160516329_send(ssrc):视频发送通道相关信息[if !supportLists]§ [endif]bytesSent:发送视频包的自己数[if !supportLists]§ [endif]codecImplementationName:视频编码器的名称[if !supportLists]§ [endif]framesEncoded:累计编码出来的视频帧数[if !supportLists]§ [endif]mediaType:媒体类型[if !supportLists]§ [endif]packetsLost:丢包数[if !supportLists]§ [endif]packetsSent:发送的视频包数[if !supportLists]§ [endif]qpSum:QP数目[if !supportLists]§ [endif]ssrc:视频rtp包的ssrc[if !supportLists]§ [endif]googTrackId:描述视频数据轨迹,这个id可以在SDP中,以及本地或远端媒体流轨道中被找到[if !supportLists]§ [endif]googAdaptationChanges:发送端因为CPU的负载变化导致的分辨变高或者变低的次数,需要设置googCpuOveruseDetection[if !supportLists]§ [endif]googAvgEncodeMs:发送端平均编码时间,越小越好。[if !supportLists]§ [endif]googBandwidthLimitedResolution:是否因为带宽受限而降低发送的视频分辨率[if !supportLists]§ [endif]googCodecName:视频编码名称[if !supportLists]§ [endif]googCpuLimitedResolution:是否因为cpu不足而降低发送的视频分辨率[if !supportLists]§ [endif]googEncodeUsagePercent:发送端(平均每帧编码时间)/(平均每帧采集时间),反应编码效率[if !supportLists]§ [endif]googFirsReceived:收到的fir请求[if !supportLists]§ [endif]googFrameHeightSent、googFrameWidthSent:发送的视频分辨率[if !supportLists]§ [endif]googFrameRateInput、googFrameRateSent:视频帧率[if !supportLists]§ [endif]googHasEnteredLowResolution:是否已经降低了视频分辨率[if !supportLists]§ [endif]googNacksReceived:收到的nack请求[if !supportLists]§ [endif]googPlisReceived:收到的pli请求[if !supportLists]§ [endif]googRtt:是发送端从接受端发送过来的RTCPReceiver Report中得到的时间戳通过计算得到的往返时延[if !supportLists]§ [endif]transportId,是指向被用于传送RTP流的部分,可以从sdp总找到[if !supportLists]· [endif]左下角的部分:也是媒体通道的具体信息,以图表的形式展示,与右上角的EventStatsTables一一对应[if !supportLists]o [endif]bweforvideo(VideoBwe):视频带宽相关信息[if !supportLists]§ [endif]googActualEncBitrate:视频编码器实际编码的码率,通常这与目标码率是匹配的。[if !supportLists]§ [endif]googAvailableReceiveBandwidth:视频数据接收可用的带宽。[if !supportLists]§ [endif]googAvailableSendBandwidth:视频数据发送可用的带宽。[if !supportLists]§ [endif]googBucketDelay:Google为了处理大数据速率的策略表示,通常是很小的数值。[if !supportLists]§ [endif]googRetransmitBitrate:如果RTX被使用的话,表示重传的码率。[if !supportLists]§ [endif]googTargetEncBitrate:视频编码器的目标比特率。[if !supportLists]§ [endif]googTansmitBitrate:实际发送的码率,如果此数值与googActualEncBitrate有较大的出入,可能是fec的影响。[if !supportLists]o [endif]googCertificate:两端使用的DTLS证书、指纹和哈希算法等[if !supportLists]o [endif]googComponent:表示认证数据与连接之间的关系,展示当前活跃的候选项对,以及有关用语DTLS和SRTP加密的相关信息。[if !supportLists]o [endif]Conn-video-1-0(googCandidatePair):RTP通道相关信息[if !supportLists]§ [endif]googActiveConnection:当前的连接是否活跃[if !supportLists]§ [endif]bytesReceived:接收的字节数(rtp数据)[if !supportLists]§ [endif]bytesSent:发送的的字节数(rtp数据)[if !supportLists]§ [endif]packetsSent:发送的数据包数(rtp数据)[if !supportLists]§ [endif]requestsSent、responsesSent、requestsReceived、responsesReceived:STUN请求和应答数量[if !supportLists]§ [endif]googRtt:最近的STUN请求的往返时间[if !supportLists]§ [endif]googLocalAddress:本地的候选地址[if !supportLists]§ [endif]googRemoteAddress:远端的候选地址[if !supportLists]§ [endif]googTransportType:传输通道的类型,通常是udp,即使当前正在使用tcp的连接方式通过turn中继服务器转发媒体,只有当ICE-TCP被选用时,这里才会是tcp[if !supportLists]o [endif]Conn-video-1-1(googCandidatePair):RTCP通道相关[if !supportLists]o [endif]ssrc_2052494919_send(ssrc):音频发送通道相关信息[if !supportLists]§ [endif]audioInputLevel:mic采集的音频能量值[if !supportLists]§ [endif]audioOutputLevel:扬声器播出的音频能力值[if !supportLists]§ [endif]bytesSent:发送的音频数据字节数[if !supportLists]§ [endif]mediaType:媒体类型[if !supportLists]§ [endif]packetsSent:发送的音频包数[if !supportLists]§ [endif]ssrc:音频rtp包的ssrc[if !supportLists]§ [endif]googCodecName:音频编码名称[if !supportLists]§ [endif]googJitterReceived:收到了多少的抖动[if !supportLists]§ [endif]googRtt:是发送端从接受端发送过来的RTCPReceiver Report中得到的时间戳通过计算得到的往返时延[if !supportLists]o [endif]ssrc_4160516329_send(ssrc):视频发送通道相关信息[if !supportLists]§ [endif]bytesSent:发送视频包的自己数[if !supportLists]§ [endif]codecImplementationName:视频编码器的名称[if !supportLists]§ [endif]framesEncoded:累计编码出来的视频帧数[if !supportLists]§ [endif]mediaType:媒体类型[if !supportLists]§ [endif]packetsLost:丢包数[if !supportLists]§ [endif]packetsSent:发送的视频包数[if !supportLists]§ [endif]qpSum:QP数目[if !supportLists]§ [endif]ssrc:视频rtp包的ssrc[if !supportLists]§ [endif]googTrackId:描述视频数据轨迹,这个id可以在SDP中,以及本地或远端媒体流轨道中被找到[if !supportLists]§ [endif]googAdaptationChanges:发送端因为CPU的负载变化导致的分辨变高或者变低的次数,需要设置googCpuOveruseDetection[if !supportLists]§ [endif]googAvgEncodeMs:发送端平均编码时间,越小越好。[if !supportLists]§ [endif]googBandwidthLimitedResolution:是否因为带宽受限而降低发送的视频分辨率[if !supportLists]§ [endif]googCodecName:视频编码名称[if !supportLists]§ [endif]googCpuLimitedResolution:是否因为cpu不足而降低发送的视频分辨率[if !supportLists]§ [endif]googEncodeUsagePercent:发送端(平均每帧编码时间)/(平均每帧采集时间),反应编码效率[if !supportLists]§ [endif]googFirsReceived:收到的fir请求[if !supportLists]§ [endif]googFrameHeightSent、googFrameWidthSent:发送的视频分辨率[if !supportLists]§ [endif]googFrameRateInput、googFrameRateSent:视频帧率[if !supportLists]§ [endif]googHasEnteredLowResolution:是否已经降低了视频分辨率[if !supportLists]§ [endif]googNacksReceived:收到的nack请求[if !supportLists]§ [endif]googPlisReceived:收到的pli请求[if !supportLists]§ [endif]googRtt:是发送端从接受端发送过来的RTCPReceiver Report中得到的时间戳通过计算得到的往返时延[if !supportLists]§ [endif]transportId,是指向被用于传送RTP流的部分,可以从sdp总找到网易云信翻译了W3C推荐标准WebRTC 1.0: Real-time Communication Between Browsers,并提供《WebRTC1.0: 浏览器间实时通讯》中文版免费下载。本文是WebRTC工作组最新一次会议后的候选推荐标准,基于WebIDL定义了一组ECMAScript API,允许在实现了相关实时协议的浏览器或设备之间发送和接收媒体内容。同时也是对WebRTC的一个全面介绍,包括WebRTC中的各个术语,独有的概念,API的使用规范,详细的算法流程和一些注意点,并且对涉及的数据结构及其属性进行了剖析。在特定的使用场景下,草案的作者们还附上了示例代码。[if !supportLists]· [endif]对于WebRTC初学者,本文档可以作为学习教程,帮助你快速对WebRTC有全面且详细的了解,学习相关API的使用,其附带的示例代码也是很好的学习资料;[if !supportLists]· [endif]对于WebRTC资深开发者,本文档可以作为开发中的使用手册,根据所提供的函数调用链或是算法流程进行开发或bug定位;[if !supportLists]· [endif]对于高阶玩家,也可通过阅读本文档对WebRTC工作组反馈改进意见。限时免费下载,WebRTC开发者必备,机不可失哦~ ...

March 14, 2019 · 3 min · jiezi

WebRTC开发者必备 | 《WebRTC1.0: 浏览器间实时通讯》中文版免费下载

随着移动互联网的崛起与完善,WebRTC的应用场景相较于它刚诞生时已经有了极大的变化,以图片和视频为代表的流媒体技术走向普及,交互式网站也逐渐成为互联网的新常态,因此WebRTC API应该把当前以及未来的应用趋势都作为出发点来考虑。本文是WebRTC工作组最新一次会议后的候选推荐标准,基于WebIDL定义了一组ECMAScript API,允许在实现了相关实时协议的浏览器或设备之间发送和接收媒体内容。同时也是对WebRTC的一个全面介绍,包括WebRTC中的各个术语,独有的概念,API的使用规范,详细的算法流程和一些注意点,并且对涉及的数据结构及其属性进行了剖析。在特定的使用场景下,草案的作者们还附上了示例代码。本篇文档适合谁看?对于WebRTC初学者,本文档可以作为学习教程,帮助你快速对WebRTC有全面且详细的了解,学习相关API的使用,其附带的示例代码也是很好的学习资料;对于WebRTC资深开发者,本文档可以作为开发中的使用手册,根据所提供的函数调用链或是算法流程进行开发或bug定位;对于高阶玩家,也可通过阅读本文档对WebRTC工作组反馈改进意见。网易云信翻译了W3C推荐标准WebRTC 1.0: Real-time Communication Between Browsers,并提供《WebRTC1.0: 浏览器间实时通讯》中文版免费下载,点击这里,立即下载吧!目录抢先看点击这里,立即免费下载《WebRTC1.0: 浏览器间实时通讯》中文版吧!

March 14, 2019 · 1 min · jiezi

【Webkit Blog翻译】深入研究WebRTC | 内有福利

本文译自A Closer Look Into WebRTC”我们在最近的一篇WebKit博客中宣布了对High Sierra平台和iOS中Safari的WebRTC支持。现在,我们希望能够带领大家深入实现其中的一些细节,并且为您网站中的WebRTC应用带来一些建议。一个应用了WebRTC和媒体摄像头的网站可以获取并传播一些非常私人的信息。用户必须显式地对网站进行授权,并假设他们的图片和声音会被合理使用。WebKit为了利用技术保护用户的隐私权,要求网站满足一些特定的条件。除此之外,当用户的摄像头设备被使用时,Safari会提醒用户,并且用户可以控制网站对摄像头设备的访问权限。对于在App中使用了WebKit的开发者发来说,RTCPeerConnection和RTCDataChannel可以在任意网页视图中使用,但对摄像头和麦克风的访问目前受限于Safari。开发菜单Safari技术预览版34向开发者展示了一些选项,可以更容易的测试他们的WebRTC网站或将Safari集成到持续集成系统中,入口在开发>WebRTC子菜单中。我们将介绍每个选项,并将在下方解释它们是如何帮助你进行开发的。此外,WebKit将WebRTC的状态作为日志记录在了系统日志中,包括SDP邀请和应答,ICE候选项,WebRCT状态统计,传入及传出视频帧计数器等。媒体摄像头的安全源策略希望访问捕获设备的网站需要满足两个约束。首先,请求需要使用摄像头和麦克风的文档需要来自HTTPS域。由于在本地开发和测试时可能会很麻烦,因此可以通过在开发>WebRTC*菜单中选中"在不安全的站点上允许使用媒体摄像头"来旁路HTTPS限制。其次,当子帧请求使用摄像头设备时,通向主帧的帧链需要来自相同的安全源。用户可能无法识别与主帧相关的子帧的第三方来源,因此该约束避免了混淆用户授予其访问权限的用户。模拟网页摄像头在开发>WebRTC菜单中,可以选择"使用模拟摄像头设备"来替代真实的摄像头设备。如下所示,模拟循环一个bip-bop AV流。当用作传入流时,模拟的可预测数据可以轻松评估流媒体播放的各个方面,包括同步,延迟和输入设备的选择。模拟对于在持续集成系统中运行自动化测试也很有用。如果您正在使用并且想要避免来自getUserMedia的提示,可以通过Safari首选项…>网站面板将网站的摄像头和麦克风策略设置为允许。ICE候选项限制ICE候选项在WebRTC连接的早期阶段进行信息交换,以识别两个对等连接之间的所有可能的网络路径。为此,WebKit必须将每个对等连接的ICE候选项暴露给网站并共享它们。ICE候选项公开IP地址,特别是那些可以用于跟踪的主机IP地址。但是,在许多网络拓扑中,主机ICE候选项不必进行连接。无论是否用于交换视频或任意数据,Server Reflexive和TURN ICE候选项通常都足以确保连接。如果不访问摄像头设备,WebKit只会公开Server Reflexive和TURN ICE候选项,这些候选者会公开可能已经被网站收集的IP。授予访问权限后,WebKit将公开主机ICE候选项,从而最大限度地提高连接成功的可能性。我们做出此例外的原因是:我们认为用户通过授予对其摄像流的访问权限来表达对网站的高度信任。一些测试页面可能会对主机ICE候选项的可用性作出假设。要对此进行测试,请从开发>WebRTC菜单中启用"禁用ICE候选限制",然后重新加载页面。旧版WebRTC及媒体流API随着WebRTC标准化过程的推进(免费下载W3C推荐标准WebRTC 1.0: Real-time Communication Between Browsers中文版),RTCPeerConnection API以各种方式逐步改进。API从最初基于回调,到变为完全基于promise,从最初专注于将MediaStream,移动到专注于MediaStreamTrack。感谢WebRTC in WebKit团队的努力,RTCPeerConnection API的改进与这两个主要变化保持一致。我们已经在Safari技术预览版34上默认关闭了旧版WebRTC API,并计划在没有这些API的情况下在macOS High Sierra和iOS 11上发布Safari 11。保留遗留API限制了我们在WebRTC上更快推进的能力。任何希望为Safari提供支持的网站都可能需要进行其他调整,因此这是摆脱这些遗留API的好时机。现有网站仍然可以依赖这些遗留API,您可以通过在开发WebRTC菜单中启用"启用旧版WebRTC API"来达到目的。ui更准确地说,以下API仅在打开旧版API开关时可用,并提供了有关如何更新的建议:partial interface Navigator {// Switch to navigator.mediaDevices.getUserMediavoid getUserMedia(MediaStreamConstraints constraints, NavigatorUserMediaSuccessCallback successCallback, NavigatorUserMediaErrorCallback errorCallback);};partial interface RTCPeerConnection {// Switch to getSenders, and look at RTCRtpSender.tracksequence<MediaStream> getLocalStreams();// Switch to getReceivers, and look at RTCRtpReceiver.tracksequence<MediaStream> getRemoteStreams();// Switch to getSenders/getReceiversMediaStream getStreamById(DOMString streamId);// Switch to addTrackvoid addStream(MediaStream stream);// Switch to removeTrackvoid removeStream(MediaStream stream);// Listen to ontrack eventattribute EventHandler onaddstream;// Update to promise-only version of createOfferPromise<void> createOffer(RTCSessionDescriptionCallback successCallback, RTCPeerConnectionErrorCallback failureCallback, optional RTCOfferOptions options);// Update to promise-only version of setLocalDescriptionPromise<void> setLocalDescription(RTCSessionDescriptionInit description, VoidFunction successCallback, RTCPeerConnectionErrorCallback failureCallback);// Update to promise-only version of createAnswerPromise<void> createAnswer(RTCSessionDescriptionCallback successCallback, RTCPeerConnectionErrorCallback failureCallback);// Update to promise-only version of setRemoteDescriptionPromise<void> setRemoteDescription(RTCSessionDescriptionInit description, VoidFunction successCallback, RTCPeerConnectionErrorCallback failureCallback);// Update to promise-only version of addIceCandidatePromise<void> addIceCandidate((RTCIceCandidateInit or RTCIceCandidate) candidate, VoidFunction successCallback, RTCPeerConnectionErrorCallback failureCallback);};许多站点通过开源的adapter.js项目支持polyfill API。更新到最新版本是弥补API差异的一种方法,但我们建议切换到规范中列出的API。以下是如何使用最新API的几个示例。典型的仅接收/在线研讨的WebRTC调用可以像这样完成:var pc = new RTCPeerConnection();pc.addTransceiver(‘audio’);pc.addTransceiver(‘video’);var offer = await pc.createOffer();await pc.setLocalDescription(offer);// send offer to the other party…典型的音频-视频WebRTC调用也可以像以下方式完成:var stream = await navigator.mediaDevices.getUserMedia({audio: true, video: true});var pc = new RTCPeerConnection();var audioSender = pc.addTrack(stream.getAudioTracks()[0], stream);var videoSender = pc.addTrack(stream.getVideoTracks()[0], stream);var offer = await pc.createOffer();await pc.setLocalDescription(offer);// send offer to the other party…基于MediaStreamTrack的API很有意义,因为大多数处理都是在这一层完成的。假设捕获视频轨的640×480默认分辨率不够好,继续前面的示例,动态更改它可以按如下方式完成:videoSender.track.applyConstraints({width: 1280, height: 720});或者我们可能想要视频静音但保持音频流动:videoSender.track.enabled = false;等等,我们实际上想要对当前的视频轨应用一些很酷的滤镜效果,就像在这个例子中一样,所需要的只是一些不需要任何SDP重新协商的函数调用:videoSender.track.enabled = true;renderWithEffects(video, canvas);videoSender.replaceTrack(canvas.captureStream().getVideoTracks()[0]);访问摄像流Safari允许用户完全控制网站对其摄像设备的访问权限。首先,用户首次调用getUserMedia时,系统会提示用户授予网站访问摄像设备的权限。但与其他浏览器不同的是,Safari不要求用户选择特定设备; 相反,它提示请求访问某一特定类型的设备,如所有相机或麦克风。这减少了多次提示带来的困扰,并且可避免用户始终点击"允许"。可能发生这种情况的一种常见情形是在iOS设备的摄像头在前后之间切换。getUserMedia中已解析的promise将返回满足约束条件的设备,并且后续对getUserMedia的调用将避免向用户显示提示。如果要允许用户切换到其他设备,请务必提供UI以执行此操作。其次,用户可以决定通过Safari首选项始终允许或拒绝访问摄像头和麦克风。用户可以基于每个来源执行此操作,甚至可以为所有网站设置通用策略。第三,一旦网站为设备创建MediaStream,Safari UI和系统菜单栏中就会显示图标,表明正在使用摄像设备。用户可以点击或点击该图标以暂停使用中的摄像机和麦克风。在这里,WebKit将发送静音音频和黑色视频帧,您的网站可以通过监听MediaStreamTrack上的静音和取消静音事件来展示合适的UI。最后,为了避免未经允许的摄像,WebKit只允许一个选项捕获一次视频或音频。已使用的捕获设备将看到他们的MediaStreamTracks静音并在新选项卡获得访问权限时接收静音事件。指纹navigator.mediaDevices.enumerateDevices公开了可用的摄像设备列表,即使未授予对这些设备的访问权限,也可以通过网站查询。对于具有自定义相机和麦克风设置的用户,可以添加到用户的指纹表面。当访问尚未被请求或访问没有被明确拒绝时,WebKit通过返回与实际可用设备集不一定对应的默认设备列表,来避免暴露这些附加信息。此外,根据规范,设备缺少标签。一旦访问权限被授予,即可获得完整的设备列表及其标签。媒体摄像头和自动播放视频在之前的帖子一和二中,我们讨论了macOS和iOS上视频自动播放策略的变化。我们调整了两个平台上的策略以适应WebRTC应用程序,在这些应用程序中,通常需要自动播放包含音频的传入媒体流。为了解决这些问题,同时保留当前自动播放规则的好处,我们进行了以下更改:·如果网页已在捕获,则MediaStream支持的媒体将自动播放。·如果网页已播放音频,则MediaStream支持的媒体将自动播放。但仍然需要用户手势来激活音频回放。性能WebRTC是一个非常强大的特性,可以衍生许多应用程序。我们都知道,强大的力量带来了巨大的责任。设计WebRTC应用程序需要从一开始就考虑到效率。 CPU,内存和网络都可能严重影响用户体验。Web引擎和Web应用程序都应该解决此问题。在Web应用程序方面,已经有各种机制可供选择:选择正确的视频分辨率和帧速率,选择正确的视频编解码器配置文件,使用CVO,在源处将媒体轨静音,以及在客户端执行WebRTC统计数据的监视。反馈这就是我们深入研究WebRTC和媒体摄像的结果。我们随时欢迎您的反馈。提交错误,发送电子邮件至web-evangelist@apple.com,或发推并@webkit。顺便说一句,鼓励大家阅读STUN和TURN的RFC规范,以及WebRTC本身的规范。这些文件可能有点难以理解,但是您可以从理解甚至一小部分内容中学到很多东西,这将有助于您的生活更简单。免费下载:W3C推荐标准WebRTC 1.0: Real-time Communication Between Browsers中文版。 ...

March 14, 2019 · 1 min · jiezi

WebRTC 及点对点网络通信机制

原文请查阅这里,略有删减,本文采用知识共享署名 4.0 国际许可协议共享,BY Troland。这是 JavaScript 工作原理第十八章。概述何为 WebRTC ?首先,字面上已经给出了关于这一技术的大量信息,RTC 即为实时通信技术。WebRTC 填补了网页开发平台中的一个重要空白。在以往,只有诸如桌面聊天程序这样的 P2P 技术才能够实现实时通讯而网页不行。但是 WebRTC 的出现改变了这一状况。WebRTC 本质上允许网页程序创建点对点通信,我们将会在随后的章节中进行介绍。我们将讨论如下主题,以便向开发者全面介绍 WebRTC 的内部构造:点对点通信防火墙和 NAT 穿透信令,会话及协议WebRTC 接口点对点通信每个用户的网页浏览器必须按照如下步骤以实现通过网页浏览器进行的点对点通信:同意开始进行通信知道如何定位另一个点绕过安全和防火墙限制实时传输所有多媒体通信信息众所周知,基于浏览器的点对点通信的最大挑战之一即如何定位和建立与另一个网页浏览器进行通信的网络套接字以进行双向数据传输。我们将会克服建立与此种网络连接相关的困难。每当网页程序需要数据或者静态资源,会直接从相应的服务器获取,仅此而已。但是,如果若想要通过直接连接用户的浏览器来建立点对点的视频聊天就不可能,因为其它浏览器并不是一个已知的网页服务器,所以用户不知道需要建立视频聊天的 IP 地址。所以,需要更多的技术以建立 p2p 连接。防火墙和 NAT 穿透一般电脑是不会被分配一个静态公共 IP 地址的。原因是电脑是位于防火墙和网络访问转换设备(NAT) 后面的。一个 NAT 设备会把防火墙内的私有 IP 地址转换为一个公共 IP 地址。对于安全和有限的可用公共 IP 地址来说,NAT 设备是必须的。这也是为什么开发者的网页程序不能够把当前设备看成拥有一个静态公共 IP 地址的原因。让我们来了解下 NAT 设备的工作原理。当开发者处于一个企业网中然后加入了 WIFI,那么电脑将会被分配一个只存在于 NAT 后面的 IP 地址。假设是 172.0.23.4。然而,对于外部而言,用户的 IP 地址会是类似 164.53.27.98 这样的。那么,外部会把所有请求看作来自 164.53.27.98 而 NAT 设备会保证来自于目标用户电脑的请求的响应数据返回到相应的内部 172.0.23.4 IP 地址的电脑。这得归功于映射表。注意到除了 IP 地址,网络通信还需要通信端口。随着 NAT 设备参与其中,浏览器需要知道进行通信的目标浏览器对应的机器 IP 地址。这个就需要用到 NAT 会话穿透程序(STUN)和 NAT 穿透中继转发服务器。为使用 WebRTC 技术,开发者需要请求 STUN 服务器以获得其公共 IP 地址。这就好像你的电脑请求远程服务器,询问远程服务器发起查询的客户端 IP 地址。远程服务器会返回对应的客户端 IP 地址。假设这一过程进展顺利,那么开发者将会获得一个公共 IP 地址和端口,这样就可以告知其它点如何直接和你进行通信。同理,这些点也可以请求 STUN 或 TURN 服务器以获得公共 IP 地址然后告知其通信地址。信令,会话和协议前述网络信息检索过程只是更大的信令话题的一部分,在 WebRTC 中,它是基于 JavaScript 会话构建协议(JSEP)标准的。信令涉及网络检索和 NAT 穿透,会话创建及管理,通信安全,媒体功能元数据和调制及错误处理。为了让通信顺利进行,节点必须确定元数据本地媒体环境(比如分辨率和编码能力等)和收集可用的程序主机网络地址。WebRTC 接口里面没有集成反复传输这一重要信息的信令机制。WebRTC 标准并没有规定信令且没有在接口中实现是为了能够更加灵活地使用其它技术和协议。信令和处理信令的服务器是由 WebRTC 程序开发者控制的。假设开发者基于浏览器的 WebRTC 程序使用之前所说的 STUN 服务器获取其公共 IP 地址,那么,下一步即和其它点进行协商和建立网络会话连接。使用任意一个专门应用于多媒体通信的信令/通信协议初始化会话协商和通信连接。该协议负责管理会话和中断的规则。会话初始协议(SIP) 是协议之一。多亏了 WebRTC 信令的灵活性,SIP 并不是唯一可供使用的信令协议。所选的通信协议必须和被称为会话描述协议(SDP)的应用层协议兼容,SDP 被应用于 WebRTC。所有的多媒体指定元数据都是通过 SDP 协议进行数据传输的。任意试图和其它点进行通信的点(比如 WebRTC 程序)都会生成交互式连接建立协议(ICE)候选集。候选集表示一个可供使用的 IP 地址,端口及传输协议的集合。注意,一台电脑可以拥有多个网络接口(有线和无线等),因此可以拥有多个 IP 地址,每个接口分配一个 IP 地址。以下为 MDN 上描绘这一通信交换的图示:建立连接每个节点首先获取之前所说的公共 IP 地址。之后动态创建「信道」信令数据来检索其它节点并且支持点对点协商及创建会话。这些「信道」不能够被外部检索和访问到且只能通过唯一标识符来访问。需要注意的是由于 WebRTC 的灵活性且事实上信令创建程序并没有在标准中指定,使用的技术不同,「信道」的概念和使用会有些许异同。事实上,一些协议并不要求「通道」机制来进行通信。本篇文章将会假设存在「信道」。一旦两个或者更多的点连接到相同的「信道」上,节点就可以进行通信和协商会话信息。这一过程和发布/订阅模式有些许类似。大体上,初始点使用诸如会话初始协议(SIP)和 SDP 的信号协议发出一个「offer」的包。发起者等待连接到指定「通道」的接收者的「answer」应答。一旦接收到应答,会开始选择和协商由各个节点生成的最优交互连接建立协调候选(ICE)集。一旦选定了最优 ICE 候选集,特别是确认了所有节点通信所要求的元数据,网络路由(IP 地址和端口)及媒体信息。这样就会完全建立及激活节点间的网络套接字会话。紧接着,每个节点创建本地数据流和数据通道端点,然后,最后使用任意双向通信技术来传输多媒体数据。如果确认最优 ICE 候选的过程失败了,这样的情况经常发生于使用的防火墙和 NAT 技术,后备使用 TURN 服务器作为中继转发服务器。这一过程主要是使用一台服务器作为中间媒介,然后在节点间转发传输数据。请注意这不是真正的点对点通信,因为真正的点对点通信是节点之间直接进行双向数据传输。每当使用 TURN 作为后备通信的时候,每个节点将不必知道如何连接并传输数据给对方节点。相反,节点只需要知道在会话通信期间实时发送和接收多媒体数据的公共 TURN 服务器。需要重点理解的是这仅仅只是一个失败保护和最后手段。TURN 服务器需要相当健壮,拥有昂贵带宽和强大的处理能力及处理潜在的大量数据。因此,使用 TURN 服务器会明显增加额外的开销和复杂度。WebRTC 接口WebRTC 中包含三种主要接口:媒体捕捉和流-允许开发者访问诸如麦克风和网络摄像机的输入设备。该接口允许开发者获取麦克风或者网络摄像机媒体流。RTCPeerConnection-开发者实时传输获取的视频和音频流到另一个 WebRTC 端点。开发者使用这些接口连接本地机器和远程节点。该接口提供创建到远程节点的连接,维护和监视连接及关闭不再活跃的连接的方法。RTCDataChannel-该接口允许开发者传输任意数据。每个数据通道都和 RTCPeerConnection 有关。我们将分别介绍这三类接口。媒体捕捉和流媒体捕捉和流接口经常被称为媒体流接口或者流接口,该接口支持音频或者视频数据流数据,处理音视频流的方法,与数据类型相关的约束,异步获取数据时的成功和错误回调及 API 调用过程中触发的事件。MediaDevices 的 getUserMedia() 方法提示用户授权允许使用媒体输入设备,创建一个包含指定媒体类型轨道的媒体流。该媒体流,可包括诸如视频轨道(由诸如摄像机,视频录制设备,屏幕共享服务等硬件或者虚拟视频源所创建),音频轨道(与视频类似,由诸如麦克风,A/D 转换器等的物理或者虚拟音频源所创建)且有可能是其它类型轨道。该方法返回一个 Promise 并解析为 MediaStream 对象。当用户拒绝授权或者没有可用的匹配媒体资源,promise 会分别返回 PermissionDeniedError 或者 NotFoundError。可以通过 navigator 对象访问 MediaDevice 单例:navigator.mediaDevices.getUserMedia(constraints).then(function(stream) { /* 使用流 /}).catch(function(err) { / 处理错误 */});注意这里需要传入 constraints 对象以指定返回的媒体流类型。开发者可以进行各种配置,包括使用的摄像头(前置或后置),帧频率,分辨率等等。从版本 25 起,基于 Chromium 的浏览器已经允许通过 getUserMedia() 获取的音频数据赋值给音频或者视频元素(但需要注意的是媒体元素默认值为空)。可以把 getUserMedia作为网页音频接口的输入节点:function gotStream(stream) { window.AudioContext = window.AudioContext || window.webkitAudioContext; var audioContext = new AudioContext(); // 从流创建音频节点 var mediaStreamSource = audioContext.createMediaStreamSource(stream); // 把它和目标节点进行连接让自己倾听或由其它节点处理 mediaStreamSource.connect(audioContext.destination);}navigator.getUserMedia({audio:true}, gotStream);隐私限制由于该接口可能导致明显的隐私问题,规范在通知用户和权限管理方面对 getUserMedia() 方法有非常明确的规定。在打开诸如用户网页摄像头或者麦克风的媒体输入设备的时候getUserMedia() 必须总是获取用户的授权。浏览器可能提供每个域名授权一次的权限功能,但必须至少第一次询问授权,然后用户必须指定授权的权限。通知中的规则同样重要。除了可能存在其它硬件指示器,浏览器还必须显示一个窗口显示使用中的摄像头或者麦克风。即使当时设备没有进行录制,浏览器必须显示一个提示窗口提示已授权使用哪个设备作为输入设备。RTCPeerConnectionRTCPeerConnection 表示一个本地电脑和远程节点之间的 WebRTC 连接。它提供了连接远程节点,维护和监视连接及关闭不再活跃的连接的方法。如下为一张 WebRTC 图表展示 了 RTCPeerConnection 的角色:从 JavaScript 方面看 ,图中需要理解的主要方面即 RTCPeerConnection 把复杂的底层内部结构的复杂度抽象为一个接口给开发者。WebRTC 所使用的编码和协议为即使在不稳定的网络环境下仍然能够创建一个尽可能实时的通信而做了大量的工作:包丢失恢复回音消除网络自适应视频抖动缓冲自动增益控制噪声减少和压制图像「清洁」RTCDataChannel不仅仅是音视频,WebRTC 还支持实时传输其它类型的数据。RTCDataChannel 接口允许点对点交换任意数据。该接口有许多用途,包括:游戏实时文本聊天文件传输分布式网络该接口有几项功能,充分利用 RTCPeerConnection 并创建强大和灵活的点对点通信:使用RTCPeerConnection 创建会话包含优先级的多个并发通道可靠和不可靠消息传递语义内置安全(DTLS)和消息堵塞控制语法和已有的 WebSocket 类似,包含有 send() 方法和 message 事件:var peerConnection = new webkitRTCPeerConnection(servers, {optional: [{RtpDataChannels: true}]});peerConnection.ondatachannel = function(event) { receiveChannel = event.channel; receiveChannel.onmessage = function(event){ document.querySelector("#receiver").innerHTML = event.data; };};sendChannel = peerConnection.createDataChannel(“sendDataChannel”, {reliable: false});document.querySelector(“button#send”).onclick = function (){ var data = document.querySelector(“textarea#send”).value; sendChannel.send(data);};由于通信是直接在浏览器之间进行的,所以 RTCDataChannel 会比 WebSocket 更快即使是使用中继转发服务器(TURN)。WebRTC 实际应用在实际应用中,WebRTC 需要服务器,但这很简单,因此会发生如下步骤:用户各自检索节点然后交换诸如名字的详情。WebRTC 客户端程序(点)交换网络信息。点交换诸如视频格式和分辨率的媒体信息。WebRTC 客户端程序穿透 NAT 网关 和防火墙。换句话说,WebRTC 需要四种类型的服务端功能:用户检索和通信发信号NAT/防火墙穿透中继转发服务器以防点对点通信失败ICE 使用 STUN 协议及其扩展 TURN 协议来创建 RTCPeerConnection 连接来处理 NAT 穿透和其它网络变化。如前所述,ICE 是用来连接诸如两个视频聊天客户的节点协议。一开始,ICE 会试图使用最低的可能的网络延迟即使用 UDP 来直接连接节点。在这一过程中,STUN 服务器只有一个任务:让位于 NAT 之后的节点能够找到其公共地址和端口。开发者可以查看一下可用的 STUN 服务器(Google 也有一堆) 名单。检索连接候选若 UDP 失败,ICE 尝试 TCP,先 HTTP 后 HTTPS。如果直接连接失败-特殊情况下,由于企业 NAT 穿透和防火墙-ICE 使用中间(转发) TURN 服务器。换句话说,ICE 首先通过 UDP 使用 STUN 服务器来直接连接节点,若失败则后备使用 TURN 中继转发服务器。「检索连接候选者」指的是检索网络接口和端口的过程。安全性实时通信程序或者插件可能造成几种安全问题。例如:未加密媒体或者数据有可能会在浏览器之间或者浏览器和服务器之间被窃取。程序有可能在未经用户授权同意的情况下记录和分发音视频。可疑软件或者病毒有可能会随着表面上无害的插件或者程序一起安装。WebRTC 有几种方法用来解决如上问题:WebRTC 实现使用诸如 DTLS 和 SRTP 的安全协议。包括信令机制在内的所有 WebRTC 组件都是强制加密的。WebRTC 不是一个插件:其组件运行于浏览器沙箱之中且不是在一个单独的进程之中,不需要单独安装组件且随着浏览器升级而更新。摄像头和麦克风必须显式授权且当摄像头或者麦克风运行时,必须在用户窗口中有所显示。对于需要实现一些浏览器之间实时通信流功能的产品而言,WebRTC 是一个令人难以置信和强大的技术。参考资料:https://www.html5rocks.com/en…https://www.innoarchitech.com… ...

March 1, 2019 · 2 min · jiezi

JavaScript 是如何工作的:WebRTC 和对等网络的机制!

这是专门探索 JavaScript 及其所构建的组件的系列文章的第 18 篇。如果你错过了前面的章节,可以在这里找到它们:JavaScript 是如何工作的:引擎,运行时和调用堆栈的概述!JavaScript 是如何工作的:深入V8引擎&编写优化代码的5个技巧!JavaScript 是如何工作的:内存管理+如何处理4个常见的内存泄漏!JavaScript 是如何工作的:事件循环和异步编程的崛起+ 5种使用 async/await 更好地编码方式!JavaScript 是如何工作的:深入探索 websocket 和HTTP/2与SSE +如何选择正确的路径!JavaScript 是如何工作的:与 WebAssembly比较 及其使用场景!JavaScript 是如何工作的:Web Workers的构建块+ 5个使用他们的场景!JavaScript 是如何工作的:Service Worker 的生命周期及使用场景!JavaScript 是如何工作的:Web 推送通知的机制!JavaScript是如何工作的:使用 MutationObserver 跟踪 DOM 的变化!JavaScript是如何工作的:渲染引擎和优化其性能的技巧!JavaScript是如何工作的:深入网络层 + 如何优化性能和安全!JavaScript是如何工作的:CSS 和 JS 动画底层原理及如何优化它们的性能!JavaScript的如何工作的:解析、抽象语法树(AST)+ 提升编译速度5个技巧!JavaScript是如何工作的:深入类和继承内部原理+Babel和 TypeScript 之间转换!JavaScript是如何工作的:存储引擎+如何选择合适的存储API!JavaScript是如何工作的: Shadow DOM 的内部结构+如何编写独立的组件!概述WebRTC,名称源自网页即时通信(英语:Web Real-Time Communication)的缩写,是一个支持网页浏览器进行实时语音对话或视频对话的API。在此之前,P2P技术(如桌面聊天应用程序)可以做一些网络做不到的事情,WebRTC 填补了 Web 这一关键空白点。WebRTC 是一项实时通信技术,它允许浏览器或者 app 之间可以不借助中间媒介的情况下,建立浏览器之间点对点的连接,实现视频流和音频流或者其他任意数据的传输。本文中讨论这一点,还支讨论以下主题,以便让你全面了解 WebRTC 的内部结构:点对点通信 (Peer-To-Peer communication)防火墙和NAT穿透 (Firewalls and NAT Traversal)信令、会话和协议 (Signaling, Sessions, and Protocols)WebRTC APIs点对点通信为了通过 Web 浏览器与另一个对等点进行通信,每个 Web 浏览器必须经过以下步骤:是否同意进行通信彼此知道对方的地址绕过安全和防火墙保护实时传输所有多媒体通信基于浏览器的点对点通信相关的最大挑战之一是知道如何定位和建立与另一个 Web 浏览器的网络套接字连接,以便双向传输数据。当 Web 应用程序需要一些数据或资源时,它从某个服务器获取数据或资源,仅此而已。但是,如果想创建点对点视频聊天,通过直接连接到其他人的浏览器——你不知道对方地址,因为另一个浏览器不是已知的 Web服务器。因此,为了建立点对点连接,还需要做更多的工作。防火墙和 NAT 穿透 (Firewalls and NAT Traversal)NAT(Network Address Translation,网络地址转换)是1994年提出的。当在专用网内部的一些主机本来已经分配到了本地 IP 地址 (即仅在本专用网内使用的专用地址),但现在又想和因特网上的主机通信(并不需要加密)时,可使用 NAT 方法。NAT(Network Address Translation,网络地址转换)简单来说就是为了解决 IPV4 下的IP地址匮乏而出现的一种技术。举例,就是通常我们处在一个路由器之下,而路由器分配给我们的地址通常为191.168.0.21 、191.168.0.22如果有n个设备,可能分配到192.168.0.n,而这个IP地址显然只是一个内网的IP地址,这样一个路由器的公网地址对应了 n 个内网的地址,通过这种使用少量的公有 IP 地址代表较多的私有 IP 地址的方式,将有助于减缓可用的IP地址空间的枯竭。NAT技术会保护内网地址的安全性,所以这就会引发个问题,就是当我采用P2P之中连接方式的时候,NAT会阻止外网地址的访问,这时我们就得采用 NAT 穿透了。这就是 NAT (STUN) 的会话遍历实用程序和围绕 NAT (TURN)服务器使用中继进行遍历的原因。为了让WebRTC 技术能够正常工作,首先会向 STUN 服务器请求你的公开IP地址。可以把它想象成你的计算机向远程服务器进行查询,该服务器询问它接收查询的IP地址,然后远程服务器用它看到的 IP 地址进行响应。假设这个过程有效,并且你接收到你面向公众的 IP 地址和端口,那么你就能够告诉其他对等方如何直接连接到你。这些对等点还可以使用 STUN 或 TURN 服务器做同样的事情,并可以告诉你用什么地址与它们联系。STUN(Simple Traversal of UDP over NATs,NAT 的UDP简单穿越)是一种网络协议,它允许位于NAT(或多重NAT)后的客户端找出自己的公网地址,查出自己位于哪种类型的NAT之后以及NAT为某一个本地端口所绑定的Internet端端口。这些信息被用来在两个同时处于NAT 路由器之后的主机之间建立UDP通信。该协议由RFC 3489定义。目前RFC 3489协议已被RFC 5389协议所取代,新的协议中,将STUN定义为一个协助穿越NAT的工具,并不独立提供穿越的解决方案。它还有升级版本RFC 7350,目前正在完善中。TURN的全称为Traversal Using Relay NAT,即通过Relay方式穿透 NAT,TURN 应用模型通过分配TURNServer的地址和端口作为客户端对外的接受地址和端口,即私网用户发出的报文都要经过TURNServer进行Relay转发,这种方式应用模型除了具有STUN方式的优点外,还解决了STUN应用无法穿透对称NAT(SymmetricNAT)以及类似的Firewall设备的缺陷信令、会话和协议上述网络信息发现过程是较大的信令主题的一部分,其基于 WebRTC 情况下的 JavaScript 会话建立协议(JSEP)标准。 信令涉及网络发现和 NAT 穿透,会话创建和管理,通信安全性,媒体能力元数据和协调以及错误处理。为了使连接起作用,对等方必须获取元数据的本地媒体条件(例如,分辨率和编解码器功能),并收集应用程序主机的可能网络地址,用于来回传递这些关键信息的信令机制并未内置到 WebRTC API 中。信令不是由 WebRTC 标准指定的,也不是由其 Api 实现的,这样可以保持技术和协议的灵活性。信令和处理它的服务器由 WebRTC 应用程序开发人员处理。假设 WebRTC 浏览器的应用程序能够使用 STUN 确定其面向公共的IP地址,下一步是实际地与对等方协商并建立网络会话连接。初始会话协商和建立使用专门用于多媒体通信的信令/通信协议进行,该协议还负责管理会话的管理和终止规则。其中一个协议是会话启动协议(称为SIP)。请注意,由于WebRTC信令的灵活性,SIP不是唯一可以使用的信令协议。所选的信令协议还必须与一个称为会话描述协议(SDP)的应用层协议一起工作,该协议在WebRTC的情况下使用。所有特定于多媒体的元数据都使用SDP协议传递。尝试与另一个对等体通信的任何对等体(即,WebRTC-利用应用程序)生成一组交互式连接建立协议(ICE)候选者。 候选者代表要使用的IP地址,端口和传输协议的给定组合。 请注意,单台计算机可能具有多个网络接口(无线,有线等),因此可以为每个接口分配多个IP地址。这是一个来自MDN的图表,描述了这种交换。建立连接每个对等点首先建立它所描述的面向公共的IP地址。然后动态创建信令数据“通道”来检测对等点,并支持对等协商和会话建立。外部世界不知道或无法访问这些“通道”,因此需要一个惟一的标识符来访问它们。请注意,由 于WebRTC 的灵活性,以及该标准没有指定信令流程这一事实,考虑到所使用的技术,“通道”的概念和使用可能略有不同,事实上,有些协议不需要“通道”机制进行通信。这里假设在本文的实现中使用了“通道”。一旦两个或更多个对等体连接到相同的“信道”,则对等点能够通信并协商会话信息,此过程有点类似于发布/订阅模式。 基本上,发起对等体使用诸如会话发起协议 SIP 和 SDP 之类的信令协议发送“offer(请求)”,发起者等待从连接到给定“信道”的任何接收器接收“answer(应答)”。一旦收到答复,就会发生以下过程,确定并协商每个对等点收集的最佳交互连接建立协议(ICE)候选者。 一旦选择了最佳 ICE 候选者,基本上所有所需的元数据,网络路由(IP地址和端口)以及用于为每个对等体通信的媒体信息达成一致。 然后,完全建立并激活对等点之间的网络套接字会话。 接下来,由每个对等体创建本地数据流和数据信道端点,并且最终使用所采用的任何双向通信技术以双向方式传输多媒体数据。如果商定最佳 ICE 候选方案的过程失败(有时确实由于使用了防火墙和 NAT 技术而发生这种情况),那么可以使用 TURN 服务器作为中继。这个过程基本上使用一个充当中介的服务器,它在对等点之间中继任何传输的数据。请注意,这不是真正的对等通信,在这种通信中,对等点直接双向地向彼此传输数据。当使用 TURN 回退进行通信时,每个对等方不再需要知道如何相互联系和传输数据。 相反,它们需要知道公共 TURN 服务器在通信会话期间发送和接收实时多媒体数据。重要的是要明白,这绝对是一个失败的安全措施和最后的手段。TURN 服务器需要非常健壮,具有广泛的带宽和处理能力,并处理潜在的大量数据。因此,使用 TURN 服务器显然会带来额外的成本和复杂性。SIP(Session Initiation Protocol,会话初始协议)是由IETF(Internet Engineering TaskForce,因特网工程任务组)制定的多媒体通信协议。它是一个基于文本的应用层控制协议,用于创建、修改和释放一个或多个参与者的会话。广泛应用于CS(CircuitSwitched,电路交换)、NGN(Next Generation Network,下一代网络)以及IMS(IP Multimedia Subsystem,IP多媒体子系统)的网络中,可以支持并应用于语音、视频、数据等多媒体业务,同时也可以应用于Presence(呈现)、Instant Message(即时消息)等特色业务。可以说,有IP网络的地方就有SIP协议的存在。SDP 完全是一种会话描述格式(对应的RFC2327) ― 它不属于传输协议 ― 它只使用不同的适当的传输协议,包括会话通知协议(SAP)、会话初始协议(SIP)、实时流协议(RTSP)、MIME 扩展协议的电子邮件以及超文本传输协议(HTTP)。SDP协议是也是基于文本的协议,这样就能保证协议的可扩展性比较强,这样就使其具有广泛的应用范围。SDP 不支持会话内容或媒体编码的协商,所以在流媒体中只用来描述媒体信息。媒体协商这一块要用RTSP来实现.WebRTC APIsMediaStream — MediaStream用来表示一个媒体数据流,允许你访问输入设备,如麦克风和 Web摄像机,该 API 允许从其中任意一个获取媒体流。RTCPeerConnection — RTCPeerConnection 对象允许用户在两个浏览器之间直接通讯 ,你可以通过网络将捕获的音频和视频流实时发送到另一个 WebRTC 端点。使用这些 Api,你可以在本地机器和远程对等点之间创建连接。它提供了连接到远程对等点、维护和监视连接以及在不再需要连接时关闭连接的方法。RTCDataChannel — 表示一个在两个节点之间的双向的数据通道,每个数据通道都与RTCPeerConnection 相关联。MediaStream (别名getUserMedia)MediaStream API 代表媒体流的同步。比如,从摄像头和麦克风获取的媒体流具有同步视频和音频轨道。MediaDevices.getUserMedia() 会提示用户给予使用媒体输入的许可,媒体输入会产生一个MediaStream,里面包含了请求的媒体类型的轨道。此流可以包含一个视频轨道(来自硬件或者虚拟视频源,比如相机、视频采集设备和屏幕共享服务等等)、一个音频轨道(同样来自硬件或虚拟音频源,比如麦克风、A/D转换器等等),也可能是其它轨道类型。它返回一个 Promise 对象,成功后会 resolve 回调一个 MediaStream 对象。若用户拒绝了使用权限,或者需要的媒体源不可用,promise 会 reject 回调一个 PermissionDeniedError 或者 NotFoundError 。可以通过 navigator 对象访问 MediaDevice 单例,如下所示:通常你可以使用 navigator.mediaDevices 来获取 MediaDevices ,例如: navigator.mediaDevices.getUserMedia(constraints).then(function(stream) { /* 使用这个stream stream /}).catch(function(err) { / 处理error /});请注意,constraints 参数是一个包含了video 和 audio两个成员的MediaStreamConstraints 对象,用于说明请求的媒体类型。必须至少一个类型或者两个同时可以被指定。如果浏览器无法找到指定的媒体类型或者无法满足相对应的参数要求,那么返回的Promise对象就会处于rejected[失败]状态,NotFoundError作为rejected[失败]回调的参数。 从版本25开始,基于 Chromium 的浏览器允许将来自 getUserMedia() 的音频数据传递给音频或视频元素(但请注意,默认情况下,媒体元素将被静音)。getUserMedia 还可以用作 Web 音频 API 的输入节点:function gotStream(stream) { window.AudioContext = window.AudioContext || window.webkitAudioContext; var audioContext = new AudioContext(); // Create an AudioNode from the stream var mediaStreamSource = audioContext.createMediaStreamSource(stream); // Connect it to destination to hear yourself // or any other node for processing! mediaStreamSource.connect(audioContext.destination);}navigator.getUserMedia({audio:true}, gotStream);约束getUserMedia() 是一个可能涉及重大隐私问题的 API,规范将其用于用户通知和权限管理的非常特定的需求。getUserMedia() 在打开任何媒体收集输入(如网络摄像头或麦克风)之前,必须始终获得用户许可。浏览器可能提供每个域一次的权限特性,但它们必须至少在第一次请求,如果用户选择这样做,则必须特别授予正在进行的权限。同样重要的是关于通知的规则。浏览器需要显示一个指示器,该指示器显示正在使用的摄像机或麦克风,超出可能存在的任何硬件指示器。它们还必须显示一个指示符,表明已授予使用设备进行输入的权限,即使该设备目前没有进行主动记录RTCPeerConnectionRTCPeerConnection 它代表了本地端机器与远端机器的一条连接。该接口提供了创建,保持,监控,关闭连接的方法的实现。的作用是在浏览器之间建立数据的“点对点”(peer to peer)通信.下面是 WebRTC 架构图,展示了 RTCPeerConnection 的作用:从 JavaScript 的角度来看,从这个图中要理解的主要事情是 RTCPeerConnection 为 Web 开发人员提供了一个抽象,从复杂的内部结构中抽象出来。使用WebRTC的编解码器和协议做了大量的工作,方便了开发者,使实时通信成为可能,甚至在不可靠的网络:丢包隐藏回声抵消带宽自适应动态抖动缓冲自动增益控制噪声抑制与抑制图像清洗RTCDataChannel除了视频和音频,webRTC 还可以传输其他数据,RTCDataChannel API支持对等交换任意数据。应用场景:游戏远程桌面应用程序实时文本聊天Web文件传输API充分利用了 RTCPeerConnection 强大和灵活的点对点通信利用 RTCPeerConnection 会话。 多通道同步通道。可靠和不可靠的传递语义(delivery semantics)。内置安全(DTLS)和阻塞控制。* 能够使用或不使用音频或视频。语法类似于已知的 WebSocket,使用 send() 方法和 message 事件:var peerConnection = new webkitRTCPeerConnection(servers, {optional: [{RtpDataChannels: true}]});peerConnection.ondatachannel = function(event) { receiveChannel = event.channel; receiveChannel.onmessage = function(event){ document.querySelector("#receiver").innerHTML = event.data; };};sendChannel = peerConnection.createDataChannel(“sendDataChannel”, {reliable: false});document.querySelector(“button#send”).onclick = function (){ var data = document.querySelector(“textarea#send”).value; sendChannel.send(data);};通信直接在浏览器之间进行,因此即使需要中继(TURN)服务器,RTCDataChannel 也可以比 WebSocket快得多。现实世界中的WebRTC实际应用中,WebRTC 需要服务器,无论多简单,下面四步是必须的:用户通过交换名字之类的信息发现对方。WebRTC 客户端应用交换网络信息。客户端交换媒体信息包括视频格式和分辨率。WebRTC 客户端穿透 NAT 网关和服务器。换句话说,WebRTC 需要四种类型的服务器端功能:用户发现和通信信令NAT/防火墙穿透中继服务器,防止端到端的通信失败可以说基于 STUN 和TURN协议的 ICE 框架,使得 RTCPeerConnection 处理 NAT 穿透和其他网络难题成为可能。 ICE 框架用于端到端的连接,比如说两个视频聊天客户端。起初,ICE 尝试通过 UDP 直接连接两端,这样可以保证低延迟。在这个过程中,STUN 服务器有一个简单的任务:使 NAT 后边的端能找到它的公网地址和端口(谷歌有多个STUN服务器,其中一个用在了apprtc.appspot.com例子)。 如果 UDP 传输失败,ICE 会尝试 TCP:首先是 HTTP,然后才会选择 HTTPS。如果直接连接失败,通常因为企业的 NAT 穿透和防火墙,此时 ICE 使用中继(Relay)服务器。换句话说,ICE 首先使用STUN 和 UDP 直接连接两端,失败之后返回中继服务器。‘finding cadidates’ 就是寻找网络接口和端口的过程。 安全实时通信应用或插件会在许多方面忽视了安全性:浏览器之间、浏览器与服务器之间的音视频或其他数据没有加密。应用在用户没有察觉的情况下录制和分发音视频。恶意软件或病毒可能入侵了正常的插件或应用。WebRTC 的许多特性可以避免这些问题:WebRTC 采用类似 DTLS 和 SRTP 的安全协议。* 所有WebRTC组件都必须进行加密,包括信令机制。* WebRTC 不是一个插件:它的组件运行在浏览器沙盒中,而不是在一个单独的进程中,组件不需要单独安装,并且在浏览器更新时都会更新。摄像头和麦克风的访问必须经过明确准许,当摄像头和麦克风运行时,界面上会清楚的显示出来。WebRTC是一种非常有趣和强大的技术,用于在浏览器之间进行某种形式的实时流。原文:https://blog.sessionstack.com…代码部署后可能存在的BUG没法实时知道,事后为了解决这些BUG,花了大量的时间进行log 调试,这边顺便给大家推荐一个好用的BUG监控工具 Fundebug。你的点赞是我持续分享好东西的动力,欢迎点赞!一个笨笨的码农,我的世界只能终身学习!更多内容请关注公众号《大迁世界》! ...

January 28, 2019 · 2 min · jiezi

用机器学习提升WebRTC视频质量评估的正确姿势

原文 :http://webrtcbydralex.com/ind…如何确保WebRTC视频通话或视频流的质量良好呢?可以从统计API中获取所有可能的指标,但仍然无法接近答案。原因很简单。首先,报告的大部分统计数据都是关于网络的,而不是视频质量。然后,众所周知,并且尝试过的人也知道,虽然这些影响了通话的感知质量,但它们并不直接相关,这意味着您无法根据这些指标猜测或计算视频质量。最后,通话质量是一个非常主观的问题,而这些问题是计算机难以直接计算的。在受控环境中,例如在实验室中,或在进行单元测试时,人们可以使用参考指标进行视频质量评估,即在发送方标记带有ID的帧,然后捕获接收方的帧,匹配ID (以补偿抖动,延迟或其他网络引起的问题)并测量两个图像之间的某种差异。谷歌的 “ 全栈测试 ” 可以解决许多编解码器和网络损伤的问题,可以作为单元测试套件的一部分运行。但是如何在生产和实时中做到这一点呢?对于大多数WebRTC PaaS用例,参考框架(https://chromium.googlesource…)不可用(服务提供商以任何方式访问客户内容都是非法的)。当然,服务的用户可以在发送方和接收方来记录流,并离线计算质量得分。但是,这不允许对突然的质量下降采取行动或做出反应。它只会有助于事后分析。那么如何在不需要额外录音、上传、下载…的情况下实时检测到质量下降并采取行动呢?在我的案例中,或者在某些特定情况下,哪个WebRTC PaaS提供了最佳视频质量呢?对大多数人来说,这是一个无法回答的问题。如何在检测网络的同时实时、自动实现4×4比较,或者这种Zoom与WebRTC(https://jitsi.org/news/a-simp…)的比较呢?CoSMo R&D推出了一种新的基于人工智能的视频评估工具,与其KITE测试引擎和相应的网络仪表模块相结合,实现了这一壮举。介绍1992年,康奈尔大学(Cornell University)的CU-SeeMe开始进行第一次互联网上实时通信(RTC)实验。随着Skype在2003年8月的推出,RTC在互联网上迅速普及。从2011年开始,WebRTC技术使得RTC可以直接在web浏览器和移动应用程序上使用。根据2017年6月发布的思科视觉网络指数【1】,实时视频流量(流媒体,视频会议)应从2016年互联网视频流量的3%(每月1.5 exabyte)急剧增长到2021年的13%(每月24 exabyte)。对于任何处理视频的应用程序,终端用户的体验质量(QoE)是非常重要的。行业中已经有许多工具和指标来自动评估视频应用程序的QoE。例如,Netflix开发了视频多方法评估融合(VMAF)度量【2】,通过使用不同的视频编码器和编码设置来度量交付的质量。这个度量有助于常规和客观地评估几十个编码设置下的数千个视频编码的质量。但它需要原始参考非失真视频来计算压缩后的视频质量得分。该方法很好地适用于非失真视频预先录制内容的视频流,但不适用于RTC,因为RTC通常无法提供原始视频。可以从源端记录原始视频,但是不能实时地进行视频质量评估。此外,在实时通信期间录制实况视频会带来法律和安全问题。由于这些原因,执行视频质量评估的实体(例如第三方平台即服务)可能不能被授权存储视频文件。因此,RTC的特殊情况不能通过需要参考视频的度量来解决。因此,有必要使用无需参考指标的评估方法。这些指标称为无参考视频质量评估(NR-VQA)指标。I. 视频质量指标视频质量评估技术可分为三类。首先,存在全参考(FR)技术,其需要完全访问参考视频。在FR方法中,我们发现了传统的视频质量方法:信噪比(SNR),峰值信噪比(PSNR)【3】,均方误差(MSE),结构相似性(SSIM)【4】,视觉信息保真度(VIF)【5】,VSNR【6】或视频质量度量工具(VQM)【7】。这些指标众所周知且易于计算,但它们并不能很好地反映用户体验的质量 【8、9】。然后存在缩减参考(RR)技术,其需要从参考视频提取的一组粗略特征。最后,无参考(NR)技术不需要关于参考视频的任何信息。实际上,他们根本不需要任何参考视频。对NR视频质量指标的全面而详细的评论已于2014年发布【10】。最近对音频和视频质量评估方法的调查已于2017年发布【11】。 度量被分为两组:基于像素的方法(NR-P),其根据从基于像素的特征导出的统计来计算,以及比特流方法(NR-B),其从编码的比特流计算。II. 先前为WebRTC视频质量评估所做的努力在文献【12】中已经提出了通过WebRTC向许多观众评估广播视频质量的第一个举措。对于这个实验,作者使用SSIM索引【4】作为视频质量的衡量标准。测试的目的是测量有多少观众可以加入观看广播,同时保持可接受的图像质量。在准确评估用户体验时,结果并不确定。随着加入广播的观众数量的增加,SSIM测量值仍保持令人惊讶的稳定,其值为[0.96,0.97]。然后突然,当客户端数量达到大约175时,SSIM下降到接近0的值。当从1到175的观众增加时,用户体验不可能在没有质量损失的情况下保持可接受。此外,测试使用的是伪客户端,只实现了WebRTC中负责negotiation和传输的部分,而不是WebRTC媒体处理管道,这对于评估广播实验的视频质量是不现实的。在文献【13】中,作者评估了在有损网络上压缩和传输受损的视频上的各种NR指标(0到10%丢包率)。研究的八个NR度量是复杂性(帧中存在的对象或元素的数量),运动,块效应(相邻块之间的不连续性),急动(帧的非流畅和非平滑呈现),平均模糊,模糊比,平均噪音和噪音比。由于这些NR指标中没有一个能够准确评估此类受损视频的质量,因此他们建议使用机器学习技术将若干NR指标与两个网络测量(比特率和数据包丢失水平)相结合,以提供改进NR度量标准能够提供与视频质量度量(VQM)相当的视频评级,这是一种可靠的FR度量,可提供与人类感知的良好相关性。在本次实验中,他们使用了从实时质量视频数据库获得的十个视频。这些视频使用H.264在8个不同级别进行压缩,并且通过网络传输时受到了损害,网络丢失了12个包。他们根据FR度量标准视频质量度量(VQM)【14】给出的分数评估了他们的结果质量,但没有针对NR度量。在文献【15】中,作者依靠许多基于比特流的特征来评估接收视频的损伤以及这些损伤如何影响感知视频质量。论文【16】提出了音频和视频指标的组合来评估视听质量。评估已在两个不同的数据集上进行。首先,他们展示了FR指标组合的结果。作者选择的FR音频指标是音频质量的感知评估(PEAQ)【17】和ViSQOL【18】。至于FR视频指标,他们使用视频质量度量(VQM)【7】,峰值信噪比(PSNR)和SSIM【4】 。然后他们展示了NR指标组合的结果。NR音频指标是SESQA和降低的SESQA(RSESQA)【19】。对于NR视频指标,他们使用了块状模糊度量【20】,盲/无参考图像空间质量评估器(BRISQUE)【21】,盲图像质量指数(BIQI)【22】 和自然图像质量评估器( NIQE)【23】。两个数据集的最佳组合是RSESQA的块状模糊。最近在移动宽带网络上评估WebRTC视频流体验质量的实验已在文献【24】中发表。各种分辨率的不同视频(从720×480到1920×1080)通过Chrome浏览器和Kurento Media Server之间的WebRTC进行视频通话的输入。WebRTC视频的质量由28人主观评估,得分从1(质量差)到5(优质)。然后,作者使用了几个指标,这些指标均基于原始视频和WebRTC视频之间计算的错误,以客观地评估WebRTC视频的质量。不幸的是,作者没有清楚地报告主观评估与计算的客观测量之间是否存在相关性。III. NARVAL:基于神经网络的视频质量评价无参考指标的聚合III.1 方法论这项工作主要有两个部分:第一,从代表视频会议用例的视频中提取特征(与例如Netflix使用的预先录制的内容),然后训练模型以预测给定的分数视频。我们使用了六个公开可用的视频质量数据集,其中包含视频通信期间可能出现的各种失真,以训练和评估我们模型的性能。对于特征提取部分,我们选择了在不同图像质量数据集上发布和评估的度量和特征。在我们的数据库的视频上计算它们之后,我们存储了数据以便能够在训练部分中重复使用它们。然后可以处理数据以用于我们的训练模型,例如取得视频上的特征的均值。第二部分,我们使用了不同的回归模型,主要是输入和层变化的神经网络,也支持向量回归。我们为每个模型测试了多个参数组合,并且仅针对每个模型类别保持最佳。除了最基本的神经网络之外,还使用了卷积,循环和时间延迟神经网络。NARVAL TRAINING:密集深度神经网络图我们使用5倍拟合在数据库上训练我们的模型,然后多次重复训练。由于每个数据库包含多个失真,我们不能随意拆分折叠,因此我们尝试选择5个折叠,这样所有失真都存在于一个折叠中,并且我们对所有测试保持相同的分布。然后,只考虑折叠的平均值。另一种创建折叠的方法是制作一个视频,它的变形是一个折叠。使用这种方法,折叠会更小,验证折叠对模型来说是全新的。III.2 结果首先针对训练集(即具有已知分数的集合)进行验证,以查看我们计算的视频质量是否与已知值匹配,如下所示。NARVAL TRAINING:3D卷积网络图为了进行健全性检查,我们再次计算了NARVAL在相同参考视频上的SSIM和WMAF分数所提供的分数。我们可以看到,虽然不完全相同,但得分表现出相同的行为。有趣的是,它还说明了图像处理社区中已知的结果,但在WebRTC社区中显然是违反直觉的:感知视频质量不会随比特率/带宽线性降低。您可以在下图中看到,要将质量降低10%,您需要将带宽减少6到10倍!结论实际上,这意味着您现在可以使用NARVAL在没有参考帧或视频的情况下计算视频质量!它为现有用例中更简单的实现打开了大门,并为许多新的用例打开了大门,在这些用例中,可以在流式传输管道的任何给定点进行质量评估。完整的研究报告可从CoSMo获得。CoSMo还为两个实现提供许可证:一个用于研究和原型设计的Python实现,以及一个用于速度和SDK嵌入的C / C ++实现。最终,视频质量评估将被提议作为一种服务,与 Citrix的AQA服务建立在POLQA之上。参考文献[1] – Visual Networking Index, Cisco, 2017.[2] – Toward A Practical Perceptual Video Quality Metric, Netflix, 2016.[3] – Objective video quality measurement using a peak-signal-to-noise-ratio (PSNR) full reference technique, American National Standards Institute, Ad Hoc Group on Video Quality Metrics, 2001.[4] – Image Quality Assessment: From Error Visibility to Structural Similarity, Wang et al., 2004.[5] – Image information and visual quality, Sheik et al., 2006.[6] – VSNR: A Wavelet-Based Visual Signal-to-Noise Ratio for Natural Images,chandler et al., 2007.[7] – A new standardized method for objectively measuring video quality, Margaret H. Pinson and Stephen Wolf, 2004.[8] – Mean Squared Error: Love It or Leave It? A new look at Signal Fidelity Measures, Zhou Wang and Alan Conrad Bovik, 2009.[9] – Objective Video Quality Assessment Methods: A Classification, Review, and Performance Comparison, Shyamprasad Chikkerur et al., 2011.[10] – No-reference image and video quality assessment: a classification and review of recent approaches, Muhammad Shahid et al., 2014.[11] – Audio-Visual Multimedia Quality Assessment: A Comprehensive Survey,Zahid Akhtar and Tiago H. Falk, 2017.[12] – WebRTC Testing: Challenges and Practical Solutions, B. Garcia et al., 2017.[13] – Predictive no-reference assessment of video quality, Maria Torres Vega et al., 2017.[14] – A new standardized method for objectively measuring video quality, Margaret H. Pinson and Stephen Wolf, 2004.[15] – A No-Reference bitstream-based perceptual model for video quality estimation of videos affected by coding artifacts and packet losses, Katerina Pandremmenou et al., 2015.[16] – Combining audio and video metrics to assess audio-visual quality, Helard A. Becerra Martinez and Mylene C. Q. Farias, 2018.[17] – PEAQ — The ITU Standard for Objective Measurement of Perceived Audio Quality, Thilo Thiede et al., 2000.[18] – ViSQOL: The Virtual Speech Quality Objective Listener, Andrew Hines et al., 2012.[19] – The ITU-T Standard for Single-Ended Speech Quality Assessment, Ludovic Malfait et al., 2006.[20] – No-reference perceptual quality assessment of {JPEG} compressed images, Zhou Wang et al, 2002.[21] – Blind/Referenceless Image Spatial Quality Evaluator, Anish Mittal et al., 2011.[22] – A Two-Step Framework for Constructing Blind Image Quality Indices, Anush Krishna Moorthy and Alan Conrad Bovik, 2010.[23] – Making a “Completely Blind” Image Quality Analyzer, Anish Mittal et al., 2013.[24] – Quality of Experience Estimation for WebRTC-based Video Streaming, Yevgeniya Sulema et al., 2018.[25] – Real-time communication testing evolution with WebRTC 1.0, Alexandre Gouaillard and Ludovic Roux, 2017.[26] – Comparative study of WebRTC Open Source SFUs for Video Conferencing, Emmanuel Andre et al., 2018本文来自CosMos Software创始人Alex. Gouaillard的博客,他同时为WebRTC、QUIC等标准组织工作。LiveVideoStack对原文进行了摘译。网易云信,你身边的即时通讯和音视频技术专家,了解我们,请戳网易云信官网想要阅读更多行业洞察和技术干货,请关注网易云信博客更多精彩内容,关注网易云信知乎机构号哦~ ...

January 21, 2019 · 3 min · jiezi

小议WebRTC拥塞控制算法:GCC介绍

网络拥塞是基于IP协议的数据报交换网络中常见的一种网络传输问题,它对网络传输的质量有严重的影响,网络拥塞是导致网络吞吐降低,网络丢包等的主要原因之一,这些问题使得上层应用无法有效的利用网络带宽获得高质量的网络传输效果。特别是在通信领域,网络拥塞导致的丢包,延迟,抖动等问题,严重的影响了通信质量,如果不能很好的解决这些问题,一个通信产品就无法在现实环境中正常使用。在这方面WebRTC中的网络拥塞控制算法给我们提供了一个可供参考的实现,本篇文章会尽量详细的介绍WebRTC中的拥塞控制算法—GCC的实现方式。相关阅读推荐《聊聊WebRTC网关服务器1:如何选择服务端端口方案》《聊聊WebRTC网关服务器2:如何选择PeerConnection方案?》WebRTC简介WebRTC是一个Web端的实时通信解决方案,它可以做到在不借助外部插件的情况下,在浏览器中实现点对点的实时通信。WebRTC已经由W3C和IETF标准化,最早推出和支持这项技术的浏览器是Chrome, 其他主流浏览器也正在陆续支持。Chrome中集成的WebRTC代码已全部开源,同时Chrome提供了一套LibWebRTC的代码库,使得这套RTC架构可以移植到其他APP当中,提供实时通信功能。GCC算法概述本文主要介绍的是WebRTC的拥塞控制算法,WebRTC的传输层是基于UDP协议,在此之上,使用的是标准的RTP/RTCP协议封装媒体流。RTP/RTCP本身提供很多机制来保证传输的可靠性,比如RR/SR, NACK,PLI,FIR, FEC,REMB等,同时WebRTC还扩展了RTP/RTCP协议,来提供一些额外的保障,比如Transport-CCFeedback, RTP Transport-wide-cc extension,RTP abs-sendtime extension等,其中一些后文会详细介绍。GCC算法主要分成两个部分,一个是基于丢包的拥塞控制,一个是基于延迟的拥塞控制。在早期的实现当中,这两个拥塞控制算法分别是在发送端和接收端实现的,接收端的拥塞控制算法所计算出的估计带宽,会通过RTCP的remb反馈到发送端,发送端综合两个控制算法的结果得到一个最终的发送码率,并以此码率发送数据包。下图便是展现的该种实现方式:从图中可以看到,Loss-Based Controller在发送端负责基于丢包的拥塞控制,它的输入比较简单,只需要根据从接收端反馈的丢包率,就可以做带宽估算;上图右侧比较复杂,做的是基于延迟的带宽估计,这也是本文后面主要介绍的部分。在最近的WebRTC实现中,GCC把它的两种拥塞控制算法都移到了发送端来实现,但是两种算法本身并没有改变,只是在发送端需要计算延迟,因而需要一些额外的feedback信息,为此WebRTC扩展了RTCP协议,其中最主要的是增加了Transport-CC Feedback,该包携带了接收端接收到的每个媒体包的到达时间。基于延迟的拥塞控制比较复杂,WebRTC使用延迟梯度来判断网络的拥塞程度,延迟梯段的概念后文会详细介绍;其算法分为几个部分:到达时间滤波器过载检测器速率控制器在获得两个拥塞控制算法分别结算到的发送码率之后,GCC最终的发送码率取的是两种算法的最小值。下面我们详细介绍WebRTC的拥塞控制算法GCC。(一)基于丢包的带宽估计基于丢包的拥塞控制比较简单,其基本思想是根据丢包的多少来判断网络的拥塞程度,丢包越多则认为网络越拥塞,那么我们就要降低发送速率来缓解网络拥塞;如果没有丢包,这说明网络状况很好,这时候就可以提高发送码率,向上探测是否有更多的带宽可用。实现该算法有两点:一是获得接收端的丢包率,一是确定降低码率和提升码率的阈值。WebRTC通过RTCP协议的Receive Report反馈包来获取接收端的丢包率。Receive Report包中有一个lost fraction字段,包含了接收端的丢包率,如下图所示。另外,WebRTC通过以下公式来估算发送码率,式中 As(tk) 即为 tk 时刻的带宽估计值,fl(tk)即为 tk 时刻的丢包率:简单来说,当丢包率大于10%时则认为网络有拥塞,此时根据丢包率降低带宽,丢包率越高带宽降的越多;当丢包率小于2%时,则认为网络状况很好,此时向上提高5%的带宽以探测是否有更多带宽可用;2%到10%之间的丢包率,则会保持当前码率不变,这样可以避免一些网络固有的丢包被错判为网络拥塞而导致降低码率,而这部分的丢包则需要通过其他的如NACK或FEC等手段来恢复。(二)基于延迟梯度的带宽估计WebRTC实现的基于延迟梯度的带宽估计有两种版本:最早一种是在接受端实现,评估的带宽结果通过RTCP REMB消息反馈到发送端。在此种实现中,为了准确计算延迟梯度,WebRTC添加了一种RTP扩展头部abs-send-time, 用来表示每个RTP包的精确发送时间,从而避免发送端延迟给网络传播延迟的估计带来误差。这种模式也是RFC和google的paper中描述的模式。在新近的WebRTC的实现中,所有的带宽估计都放在了发送端,也就说发送端除了做基于丢包的带宽估计,同时也做基于延迟梯度的带宽估计。为了能够在接受端做基于延迟梯度的带宽估计,WebRTC扩展了RTP/RTCP协议,其一是增加了RTP扩展头部,添加了一个session级别的sequence number, 目的是基于一个session做反馈信息的统计,而不紧紧是一条音频流或视频流;其二是增加了一个RTCP反馈信息transport-cc-feedback,该消息负责反馈接受端收到的所有媒体包的到达时间。接收端根据包间的接受延迟和发送间隔可以计算出延迟梯度,从而估计带宽。关于如何根据延迟梯度推断当前网络状况, 后面会分几点详细展开讲, 总体来说分为以下几个步骤:到达时间滤波器过载检测器速率控制器其过程就是,到达时间滤波器根据包间的到达时延和发送间隔,计算出延迟变化,这里会用到卡尔曼滤波对延迟变化做平滑以消除网络噪音带来的误差;延迟变化会作为过载检测器的输入,由过载检测器判断当前网络的状态,有三种网络状态返回overuse/underuse/normal,检测的依据是比较延迟变化和一个阈值,其中该阈值非常关键且是动态调整的。最后根据网络状态的变化,速率控制器根据一个带宽估计公式计算带宽估计值。(三)到达时间滤波器前面多次提到WebRTC使用延迟梯度来判断网络拥塞状况,那什么是延迟梯度,为什么延迟梯度可以作为判断网络拥塞的依据,我们在这里详细介绍,首先来看以下,延迟梯度是怎样计算出来的:延迟梯度的计算如上图所示,用两个数据包的到达时间间隔减去他们的发送时间间隔,就可以得到一个延迟的变化,这里我们称这个延迟的变化为单向延迟梯度(one way delay gradient),其公式可记为:那么为什么延迟梯度可以用来判断网络拥塞的呢,如下面两图所示:左边这幅图的场景是理想状况下的网络传输,没有任何拥塞,按我们上面提到的公式(2)来计算,这种场景下,所计算到的延迟梯度应该为0。而右边这幅图的场景则是发送拥塞时的状况,当包在t2时刻到达时,该报在网络中经历过一次因拥塞导致的排队,这导致他的到达时间比原本要完,此时计算出的延迟梯度就为一个较大的值,通过这个值,我们就能判断当前网络正处在拥塞状态。在WebRTC的具体实现中,还有一些细节来保证延迟梯度计算的准确性,总结如下:由于延迟梯度的测量精度很小,为了避免网络噪音带来的误差,利用了卡尔曼滤波来平滑延迟梯度的测量结果。WebRTC的实现中,并不是单纯的测量单个数据包彼此之间的延迟梯度,而是将数据包按发送时间间隔和到达时间间隔分组,计算组间的整体延迟梯度。分组规则是:1) 发送时间间隔小于5ms的数据包被归为一组,这是由于WebRTC的发送端实现了一个平滑发送模块,该模块的发送间隔是5ms发送一批数据包。2) 到达时间间隔小于5ms的数据包被归为一组,这是由于在wifi网络下,某些wifi设备的转发模式是,在某个固定时间片内才有机会转发数据包,这个时间片的间隔可能长达100ms,造成的结果是100ms的数据包堆积,并在发送时形成burst,这个busrt内的所有数据包就会被视为一组。为了计算延迟梯度,除了接收端要反馈每个媒体包的接受状态,同时发送端也要记录每个媒体包的发送状态,记录其发送的时间值。在这个情况下abs-send-time扩展不再需要。transport-cc-feedback消息该消息是对RTCP的一个扩展,专门用于在GCC中反馈数据包的接受情况。这里有两点需要注意:该消息的发送速率如何确定,按RFC[2]中的说明,可以是收到每个frame发送一次,另外也指出可以是一个RTT的时间发送一次,实际WebRTC的实现中大约估计了一个发送带宽的5%这样一个发送速率。如果这个数据包丢失怎么办,RFC[2]和WebRTC实现中都是直接忽略,这里涉及的问题是,忽略该包对计算延迟梯度影响不大,只是相当于数据包的分组跨度更大了,丢失的包对计算没有太大影响,但另一个问题是,发送端需要计算接受端的接受速率,当feedback丢失时,会认为相应的数据包都丢失了,这会影响接受速率的计算,这个值在后续计算估计带宽中会用到,从而导致一定误差。具体消息格式如下:如上图所示,红框之前的字段是RTCP包的通用字段,红框中的字段为transport-cc的具体内容,其中前四个字段分别表示:base sequence number:当前包携带的媒体包的接受信息是从哪个包开始的packet status count:当前包携带了几个媒体包的接受信息reference time:一个基准时间,计算该包中每个媒体包的到达时间都要基于这个基准时间计算fb pkt. count:第几个transport-cc包在此之后,是两类信息:多个packet chunk字段和多个recv delta字段。其中pcaket chunk具体含义如下:如下两图所示, 表示媒体包到达状态的结构有两种编码方式, 其中 T 表示chunk type;0表示RunLength Chunk, 1表示Status Vector Chunk.1)Run LengthChunk这种表示方式是用于,当我们连续收到多个数据包,他们都有相同的到达状态,就可以用这种编码方式。其中S表示的是到达状态,Run Length表示有多少个连续的包属于这一到达状态。到达状态有三种:00 Packet not received01 Packet received, small delta (所谓small detal是指能用一个字节表示的数值)10 Packet received, large ornegative delta (large即是能用两个字节表示的数值)2) Status Vector Chunk这种表示方式用于每个数据包都需要自己的状态表示码,当然还是上面提到的那三种状态。但是这里的S就不是上面的意思,这里的S指的是symbol list的编码方式,s = 0时,表示symbollist的每一个bit能表示一个数据包的到达状态,s = 1时表示每两个bit表示一个数据包的状态。s = 0 时0 Packet not received1 Packet received , small detals = 1 时 同 Run Length Chunk最后,对于每一个状态为Packet received 的数据包的延迟依次填入|recv delta|字段,到达状态为1的,recv delta占用一个字节,到达状态为2的,recv delta占用两个字节可以看出以上编码的目的是为了尽量减少该数据包的大小,因为每个媒体包都需要反馈他的接受状态。(四)过载检测器到达时间滤波器计算出每组数据包的延迟梯度之后,就要据此判断当前的网络拥塞状态,通过和某个阈值的比较,高过某个阈值就认为时网络拥塞,低于某个阈值就认为网路状态良好,因此如何确定阈值就至关重要。这就是过载检测器的主要工作,它主要有两部分,一部分是确定阈值的大小,另一部分就是依据延迟梯度和阈值的判断,估计出当前的网络状态,一共有三种网络状态: overuse underuse normal,我们先看网络状态的判断。网络状态判断判断依据入下图所示:其中表示的是计算出的延迟梯,表示的是一个判断阈值,这个阈值是自适应的, 后面还会介绍他是怎么动态调整的,这里先只看如何根据这两个值判断当前网络状态。从上图可以看出,这里的判断方法是:这样计算的依据是,网络发生拥塞时,数据包会在中间网络设备中排队等待转发,这会造成延迟梯度的增长,当网络流量回落时,网络设备快速消耗(转发)其发送队列中的数据包,而后续的包排队时间更短,这时延迟梯度减小或为负值。这里了需要说明的是:在实际WebRTC的实现中,虽然每个数据包组(前面提到了如何分组)的到达都会触发这个探测过程,但是使用的m(ti)这个值并不是直接使用每组数据到来时的计算值,而是将这个值放大了60倍。这么做的目的可能是m(ti)这个值通常情况下很小,理想网络下基本为0,放大该值可以使该算法不会应为太灵敏而波动太大。在判断是否overuse时,不会一旦超过阈值就改变当前状态,而是要满足延迟梯度大于阈值至少持续100ms,才会将当前网络状态判断为overuse。自适应阈值上节提到的阈值值,它是判断当前网络状况的依据,所以如何确定它的值也就非常重要了。虽然理想状况下,网络的延迟梯度是0,但是实际的网络中,不同转发路径其延迟梯度还是有波动的,波动的大小也是不一样的,这就导致如果设置固定的太大可能无法探测到拥塞,太小又太敏感,导致速率了变化很大。同时,另外一个问题是,实验中显示固定的值会导致在和TCP链接的竞争中,自己被饿死的现象(TCP是基于丢包的拥塞控制),因此WebRTC使用了一种自适应的阈值调节算法,具体如下:(1) 自适应算法上面的公式就是GCC提出的阈值自适应算法,其中:每组数据包会触发一次探测,同时更新一次阈值,这就是距上次更新阈值时的时间间隔。是一个变化率,或者叫增长率,当然也有可能是负增长,增长的基值是:当前的延迟梯度和上一个阈值的差值—。其具体的取值如下:其中:ku = 0.01; kd = 0.00018从这个式子中可以看出,当延迟梯度减小时,阈值会以一个更慢的速率减小; 延迟梯度增加时,阈值也会以一个更慢的速度增加;不过相对而言,阈值的减小速度要小于增加速度。(五)速率控制器速率控制器主要实现了一个状态机的变迁,并根据当前状态来计算当前的可用码率,状态机如下图所示:速率控制器根据过载探测器输出的信号(overuse underusenormal)驱动速率控制状态机, 从而估算出当前的网络速率。从上图可以看出,当网络拥塞时,会收到overuse信号,状态机进入“decrease”状态,发送速率降低;当网络中排队的数据包被快速释放时,会受到underuse信号,状态机进入“hold”状态。网络平稳时,收到normal信号,状态机进入“increase”状态,开始探测是否可以增加发送速率。在Google的paper[3]中,计算带宽的公式如下:其中= 1.05, =0.85。从该式中可以看到,当需要Increase时,以前一次的估算码率乘以1.05作为当前码率;当需要Decrease时,以当前估算的接受端码率(Rr(ti))乘以0.85作为当前码率;Hold状态不改变码率。最后,将基于丢包的码率估计值和基于延迟的码率估计值作比较,其中最小的码率估价值将作为最终的发送码率。以上便是WebRTC中的拥塞控制算法的主要内容,其算法也一直还在演进当中,每个版本都有会有一些改进加入。其他还有一些主题这里没有覆盖到,比如平滑发送,可以避免突发流量; padding包等用来探测带宽的策略。应该说WebRTC的这套机制能覆盖大部分的网络场景,但是从我们测试来看有一些特殊场景,比如抖动或者丢包比较高的情况下,其带宽利用率还是不够理想,但总体来说效果还是很不错的。另外,想要获取更多产品干货、技术干货,记得关注网易云信博客。 ...

January 21, 2019 · 1 min · jiezi

WebRTC实操经验分享:如何快速构建音视频通话APP?

语音和视频通信的嵌入对于现在的互联网产品发展的重要性已经毋庸置疑,WebRTC事实上是一种通用的技术框架标准,它可以在浏览器之间不需要中介的情况下,实现任意数据流交换。这使得web应用程序和移动应用程序能够直接传输P2P音频/视频呼叫,而不需要第三方集成。据Transparency Market Research调研显示,到2025年,WebRTC市场价值预计将达到815.2亿美元。WebRTC虽然冠以“web”之名,但并不受限于传统互联网应用或浏览器的终端运行环境。实际上无论终端运行环境是浏览器、桌面应用、移动设备(Android或iOS)还是IoT设备,只要IP连接可到达且符合WebRTC规范就可以互通。这一点释放了大量智能终端(或运行在智能终端上的app)的实时通信能力,打开了许多对于实时交互性要求较高的应用场景的想象空间,譬如在线教育、视频会议、视频社交、远程协助、远程操控等等都是其合适的应用领域。回到构建webrtc android的场景,iOS视频聊天应用程序使用JavaScript,在web应用程序中发挥健壮和高性能的作用,并实时检测缺陷。虽然有多种编程语言,但Linux和Firebase中的数据库和操作系统(如peer.js、node.js)被用于构建用于Android、IOS和Web的WebRTC视频/语音聊天应用程序。js是创建WebRTC信令服务器的主要服务器端框架。让我们仔细看看将JavaScript推到其他语言之上的参数。为什么在构建WebRTC视频/语音聊天应用程序时选择JavaScript(Node.js)作为核心语言而不是其他编程语言?考虑到Node.js是在服务器端运行JavaScript的核心框架,这肯定会启动调用进程,并且它也被称为“JavaScript运行时构建”这是一个在跨多个分布式设备上运行的实时应用程序中数据密集型的完美模型。这种轻量级和高效的运行环境是为Android、IOS和Web开发WebRTC视频呼叫移动应用程序的一个环境。某些参数吸引开发人员依赖Node.js构建在多个平台上无缝执行的视频聊天应用程序。1 Real-Time Web APP:以前,低级sockets和协议对开发人员来说是真正的混乱,现在node.js提供的额外好处是以闪电般的速度构建一个实时web应用程序,如webrtc语音/视频聊天应用程序,并阻止多用户实时应用程序。这种事件驱动的体系结构有潜力满足服务器端和客户端的绝对、更快的同步,而这就是用JavaScript编写的。2 同时提出请求:因为node.js是一个兼容的服务器端框架,可以配置为服务器端代理并提供非阻塞IO它可以管理大量的同时连接。在WebRTC视频聊天应用程序不会在设备内提交过多RAM的情况下,该系统可以同时处理请求,并以比Python和Ruby等其他语言更快的会话速度排队并以更快的速度执行传入请求。除了开发WebRTC视频聊天应用程序之外,选择将视频呼叫的第三方整合到网站/应用程序和视频呼叫集成提供商之外,也可以创建一个最终在Android/iOS&Web上运行得非常优秀的视频聊天应用程序。这里无缝插入一条网易云信的广告,欢迎来网易云信看看30分钟构建音视频通话能力。因此,可以使用多种编程语言来构建WebRTC视频聊天应用程序,但只有JavaScript等特定语言能够提供用户所期望的确切的视频/语音聊天应用程序。在全球WebRTC信令市场上,Node.js是构建理想的支持WebRTC的视频聊天应用程序的理想选择,该应用程序能够提供卓越的性能、创建API、处理并发请求和要求扩展性,以在Android、IOS和Web中开发成功的WebRTC视频/语音聊天应用程序。另外,想要获取更多产品干货、技术干货,记得关注网易云信博客。

January 21, 2019 · 1 min · jiezi

Jitsi开发环境配置

webpack热编译devServer//TODO

January 14, 2019 · 1 min · jiezi

Jitsi快捷安装

官方教程quick-install翻译教程(只能在ubuntu14.04以上版本运行)安装步骤如下:开放端口ufw allow in sshufw allow in 80/tcpufw allow in 443/tcpufw allow in 10000:20000/udpufw allow in 4443/tcpufw allow in 5280/tcpufw statusiptables -L -n安装node(自带npm)tar -xvf node-v10.8.0-linux-x64.tar.xzmv node-v10.8.0-linux-x64 /usr/local/nodeln -s /usr/local/node/bin/node /usr/bin/nodeln -s /usr/local/node/bin/npm /usr/bin/npmnode -vnpm -v安装nginxsudo apt-get install nginx添加软件库echo “deb https://download.jitsi.org stable/” >> /etc/apt/sources.list添加官方KEYwget -qO - https://download.jitsi.org/jitsi-key.gpg.key | sudo apt-key add -更新包列表sudo apt-get update安装Jitsi-meetsudo apt-get -y install jitsi-meet卸载apt-get purge jigasi jitsi-meet jitsi-meet-web-config jitsi-meet-prosody jitsi-meet-web jicofo jitsi-videobridge注意事项安装的时候尽量填写域名或者配置host,以避免非固定ip导致各种配置文件不对应。比如,prosody的bosh,如果ip安装的ip对不上,就会导致通信失败。配置JicofoVedioBridge,否则穿墙失败不能通信。org.ice4j.ice.harvest.NAT_HARVESTER_LOCAL_ADDRESS=内网iporg.ice4j.ice.harvest.NAT_HARVESTER_PUBLIC_ADDRESS=外网ip

January 14, 2019 · 1 min · jiezi

webRtc及组件之间通信

应公司项目需求。 需要在原先完整项目的基础上将音视频通话部分与项目进行分离, 形成单独的组件。 实现在项目中传入url, 后弹出model框进行两端音视频通话。通话功能通话功能的流程是通过页面上的某个按钮执行init()方法。 因为用了腾讯云的音视频技术。 所以需要在腾讯云服务器创建房间, 还有公司本地服务器创建房间做通话两端的中间人角色。import rtc from ‘path’;rtc.init( obj, // 创建房间基本信息字段 ‘p1’, // 获取腾讯云信息 ‘p2’, // 本地服务器创建房间 ‘p3’, // 心跳接口 ‘p4’, // 退出本地服务器房间 heart, // 心跳回调 根据返回值查看视频过程 eventcb, // 腾讯云服务器 发生事件回调 可不传 1, // 是否需要混流 可不传 ‘p5’, // 混流接口 可不传);在页面中引入rtc组件并执行init()方法, 传入路径,监听通话过程的回调等。在rtc组件中:const rtc = { … // 保存信息变量 init(obj, u1, u2, u3, u4, heart, eventcb, isMixed = 0, u5 = ‘’) { … // 全局保存传入字段 axios.post(u1, Qs.stringify(params)).then((res) => { const opt = { … // 房间信息 }; const RTC = that.create(opt); Object.keys(that.events).forEach((key) => { if (!eventcb) { that.eventcb = function (rs) { return rs.tip; }; } else { that.eventcb = eventcb; } RTC.on(key, that.events[key]); }); }); }}init()方法中通过传入的路径, 首先调用后台初始化接口, 获取创建房间必要的参数信息。 同时将信息存入全局变量中。 执行create()。 开始在服务器及腾讯云服务器创建房间。 在create中 return RTC; 说明房间创建成功。 events 定义了腾讯云事件通知, 遍历key, value, RTC.on 进行监听. eventcb为传入的事件回调。create(opt) { const self = this; const RTC = new WebRTCAPI(opt, function () { const params = { … // 创建本地服务器房间 }; axios.post(self.u2, Qs.stringify(params)).then((res) => { const createOpt = { … // 创建腾讯服务器房间 }; RTC.createRoom(createOpt, function() { console.log(‘创建房间’); self.heartbeat(); }) }); }); return RTC; },heartbeat( ) 递归调用心跳函数, 对通话过程进行监听, 比如一端退出房间通过与后台商定的code值, 即使在本地服务器退出房间等。events: { onRemoteStreamUpdate(data) { … // 远端流 新增/更新 if (!rtc.connect) { rtc.connect = 1; // 开始通话 rtc.instance.$emit(‘connection’, rtc.connect); } rtc.eventcb(….); 回调返回信息 }, onRemoteStreamRemove(data) { … // 远端流断开 rtc.eventcb(….); }, onRelayTimeout(data) { … // server 超时断开 rtc.eventcb(….); } },eventcb 如果传入能确保在执行init( )方法的页面得到通话过程中的事件执行信息。组件通信init( )与rtc.js 可以通过回调传参的方式进行通信, 但rtc.js 与 通话面板之间无法通过这种方式进行信息传递。 比如需要在rtc.js 通知 model通话开始, 这时需要开始计时等。 vuex, bus无法在这种情况下使用. 所以通过 Vue.extend( ) , 在Vue构造器上创建子类。 注册到全局。 使用vm.$emit 及 vm.$om 发布订阅事件import rtcContainer from ‘./view.rtc’;init( … ) { … const callPanel = Vue.extend(rtcContainer); this.instance = new callPanel({ propsData: { // 传值 } }).$mount(); document.body.appendChild(this.instance.$el);}如果$mount( )不传值,没有挂载节点, 也会生成callpanel实例。这是一个坑,而后将其挂载到body上。 在需要的地方$emit发布事件.结语做完这些初步完成以项目为基础的组件抽离,代码太次,正在优化。 ...

December 18, 2018 · 2 min · jiezi

Hola~ 一款基于Electron的聊天软件

Hola前言本项目旨在从零到壹,制作一款界面精美的聊天软件。Github 地址因为已工作,所以可能没有多少时间来继续跟进这个项目了,项目可优化的点已在下文列出,欢迎大家 Fork 或 Star。ps: 征 logo 一枚。因为本人是开发,设计功底欠缺,所以软件 logo 设计的有点丑,如果有大神有更好的 logo,欢迎 email。技术栈开发环境操作系统:macOS High Sierra v10.13.1编辑器:Visual Studio Code v1.19.1npm:v5.3.0Node:v8.4.0客户端UI设计:Sketch软件框架:Electron界面实现:Vue.js + Vuex + Vue-Router + Webpack通信模块:socket.io-client视频聊天:原生 WebRTC服务端服务器:Node.js后端框架:Koa2通信模块:socket.io数据库:Redis 和 MongoDB软件效果图实现功能[x] 登录注册模块(<手机号+验证码>形式的登录注册)[x] 聊天区模块[x] 最近联系人列表[x] 历史消息(暂未做上拉加载)[x] 私聊[x] 文本消息[x] 图片消息[x] 视频聊天[x] 群聊[x] 文本消息[x] 图片消息[x] 联系人模块[x] 联系人列表[x] 好友资料展示[x] 群组资料展示[x] 删好友,退出或解散群组[x] 功能区模块[x] 添加好友/群组[x] 创建群组[x] 设置区模块[x] 个人资料设置[x] 软件设置[x] 国际化[x] 中文[x] 英文项目目录.├── LICENSE ├── README.md├── client # 客户端代码├── docs # 各种文档(需求文档、UI文档、流程图、数据库设计等)├── preview.png # 软件预览图└── server # 服务端代码反思 & 展望该项目为我大学毕业设计的项目,因时间紧迫,只实现了基本的聊天、加删好友等功能,很多功能还未实现,所以软件还是有很多的瑕疵。为此,我特意思考了很长时间,将待改进的细节或新的功能总结如下:[ ] 历史消息做成上拉瀑布流加载的效果[ ] 为消息注明消息时间、发送状态、已读未读等状态[ ] 为最近联系人列表添加最后一条消息的展示[ ] 为最近联系人添加未读消息个数的统计[ ] 添加好友或加入群组时要进行确认[ ] 为软件的新消息使用系统原生通知窗口通知[ ] 为软件增加原生菜单[ ] 升级输入框,从而可以向输入框直接插入剪切板中的图片[ ] 自己搭建文件服务器,图片服务器(或者使用第三方比如七牛云、阿里云的相关服务)[ ] 为 WebRTC 实现后备方案,搭建 Relay Server,以增强视频聊天的稳定性[ ] 增加网络断开处理的相关逻辑[ ] 了解数据加密相关知识,为消息作加密处理[ ] 为软件做跨平台处理,兼容性方面有待加强[ ] 实现软件自动更新[ ] 接入智能机器人聊天[ ] 实现本地存储历史消息(nedb)[ ] 为软件加入聊天情况分析(比如每天发了多少条消息,与谁聊天最频繁等)扩展阅读初探 Electron - 理论篇初探 Electron - 升华篇XCel 项目总结 - Electron 与 Vue 的性能优化【译】Electron 自动更新的完整教程(Windows 和 OSX)Getting Started with WebRTC通俗易懂:一篇掌握即时通讯的消息传输安全原理即时通讯安全篇(三):常用加解密算法与通讯安全讲解socket.io断线后重连和消息离线存储如何实现Socket.IO stream运用google-protobuf的IM消息应用开发(前端篇)Can one hack “paste image” support into a textarea in Firefox?在线和离线事件 ...

November 5, 2018 · 1 min · jiezi