• java voice / webrtc / WebRTC / Web RealTime Communication


    s

    s

    https://zhuanlan.zhihu.com/p/86751078

    什么是WebRTC

    WebRTC是一个由Google发起的实时通讯解决方案,其中包含视频音频采集,编解码,数据传输,音视频展示等功能,我们可以通过技术快速地构建出一个音视频通讯应用。 虽然其名为WebRTC,但是实际上它不光支持Web之间的音视频通讯,还支持Android以及IOS端,此外由于该项目是开源的,我们也可以通过编译C++代码,从而达到全平台的互通。

    WebRTC架构

     

     

    架构组件

    Your Web App

    Web开发者开发的程序,Web开发者可以基于集成WebRTC的浏览器提供的web API开发基于视频、音频的实时通信应用。

    Web API

    面向第三方开发者的WebRTC标准API(Javascript),使开发者能够容易地开发出类似于网络视频聊天的web应用,需要注意的是可能在不同浏览器中API接口名会不太一样, 所以推荐使用这个JS适配器来协调各个浏览器的不同接口。 这些API可分成Media API、 RTCPeerConnection、Peer-to-peer Data API三类:

    Media API

    MediaStream:MediaStream用来表示一个媒体数据流。 MediaStreamTrack:在浏览器中表示一个媒体源。

    RTCPeerConnection

    RTCPeerConnection:一个RTCPeerConnection对象允许用户在两个浏览器之间直接通讯。 SDP: 用来描述当前连接者想要传输的内容,支持的协议类型,支持的编解码类型等。 RTCIceCandidate:表示一个ICE协议的候选者,简单的说,就是目标节点的IP以及端口。 RTCIceServer:表示一个ICE Server,其主要用于当前主机的IP发现,通过和ICE Server通讯,我们会得到一组可供连接使用的IP:Port候选值,双方通过交换ICE候选值来建立起连接。

    Peer-to-peer Data API

    DataChannel:数据通道( DataChannel)接口表示一个在两个节点之间的双向的数据通道,该通道可以设置成可靠传输或非可靠传输 。

    WebRTC Native C++ API

    本地C++ API层,使浏览器厂商容易实现WebRTC标准的Web API,抽象地对数字信号过程进行处理。

    Transport / Session

    传输部分可基于TCP/UDP,会话层组件采用了libjingle库的部分组件实现

    AudioEngine

    音频引擎是包含一系列音频多媒体处理的框架,包括从视频采集卡到网络传输端等整个解决方案。

    VideoEngine

    视频引擎是包含一系列视频处理的整体框架,从摄像头采集视频到视频信息网络传输再到视频显示整个完整过程的解决方案。

    通讯内容的确立

    首先,两个客户端(Alice & Bob)想要创建连接,一般来说需要有一个双方都能访问的服务器来帮助他们交换连接所需要的信息。有了交换数据的中间人之后,他们首先要交换的数据是SessionDescription(SD),这里面描述了连接双方想要建立怎样的连接。

     

    SD 从哪来

    一般来说,在建立连接之前连接双方需要先通过API来指定自己要传输什么数据(Audio,Video,DataChannel),以及自己希望接受什么数据,然后Alice调用CreateOffer()方法,获取offer类型的SessionDescription,通过公共服务器传递给Bob,同样地Bob通过调用CreateAnswer(),获取answer类型的SessionDescription,通过公共服务器传递给Alice。 在这个过程中无论是哪一方创建Offer(Answer)都无所谓,但是要保证连接双方创建的SessionDescription类型是相互对应的。Alice=Answer Bob=Offer | Alice=Offer Bob=Answer

    SD 包含什么内容

    //版本
    v=0
    //<username> <sess-id> <sess-version> <nettype> <addrtype> <unicast-address>
    o=- 3089712662142082488 2 IN IP4 127.0.0.1
    //会话名
    s=-
    //会话的起始时间和结束时间,0代表没有限制
    t=0 0
    //表示音频传输和data channel传输共用一个传输通道传输的媒体,通过id进行区分不同的流
    a=group:BUNDLE audio data
    //WebRTC Media Stream
    a=msid-semantic: WMS
    //m=audio说明本会话包含音频,9代表音频使用端口9来传输,但是在webrtc中现在一般不使用,如果设置为0,代表不传输音频
    //使用UDP来传输RTP包,并使用TLS加密, SAVPF代表使用srtcp的反馈机制来控制通信过程
    //111 103 104 9 0 8 106 105 13 110 112 113 126表示支持的编码,和后面的a=rtpmap对应
    m=audio 9 UDP/TLS/RTP/SAVPF 111 103 104 9 0 8 106 105 13 110 112 113 126
    //表示你要用来接收或者发送音频使用的IP地址, webrtc使用ice传输,不使用这个地址, 关于ICE是什么后面会讲到
    c=IN IP4 0.0.0.0
    //用来传输rtcp的地址和端口,webrtc中不使用
    a=rtcp:9 IN IP4 0.0.0.0
    //ice协商过程中的安全验证信息
    a=ice-ufrag:ubhd
    a=ice-pwd:l82NnsGm5i7pucQRchNdjA6B
    //支持trickle,即sdp里面只描述媒体信息, ice候选项的信息另行通知
    a=ice-options:trickle
    //dtls协商过程中需要的认证信息
    a=fingerprint:sha-256 CA:83:D0:0F:3B:27:4C:8F:F4:DB:34:58:AC:A6:5D:36:01:07:9F:2B:1D:95:29:AD:0C:F8:08:68:34:D8:62:A7
    a=setup:active
    //前面BUNDLE行中用到的媒体标识
    a=mid:audio
    //指出要在rtp头部中加入音量信息
    a=extmap:1 urn:ietf:params:rtp-hdrext:ssrc-audio-level
    //当前客户端只接受数据,不发送数据,recvonly,sendonly,inactive,sendrecv
    a=recvonly
    //rtp,rtcp包使用同一个端口来传输
    a=rtcp-mux
    //下面都是对m=audio这一行的媒体编码补充说明,指出了编码采用的编号,采样率,声道等
    a=rtpmap:111 opus/48000/2
    a=rtcp-fb:111 transport-cc
    //对opus编码可选的补充说明,minptime代表最小打包时长是10ms,useinbandfec=1代表使用opus编码内置fec特性
    a=fmtp:111 minptime=10;useinbandfec=1
    a=rtpmap:103 ISAC/16000
    a=rtpmap:104 ISAC/32000
    a=rtpmap:9 G722/8000
    a=rtpmap:0 PCMU/8000
    a=rtpmap:8 PCMA/8000
    a=rtpmap:106 CN/32000
    a=rtpmap:105 CN/16000
    a=rtpmap:13 CN/8000
    a=rtpmap:110 telephone-event/48000
    a=rtpmap:112 telephone-event/32000
    a=rtpmap:113 telephone-event/16000
    a=rtpmap:126 telephone-event/8000
    //下面就是对Data Channel的描述,基本和上面的audio描述类似,使用DTLS加密,使用SCTP传输
    m=application 9 DTLS/SCTP 5000
    c=IN IP4 0.0.0.0
    //可以是CT或AS,CT方式是设置整个会议的带宽,AS是设置单个会话的带宽。缺省带宽是千比特每秒
    b=AS:30
    a=ice-ufrag:ubhd
    a=ice-pwd:l82NnsGm5i7pucQRchNdjA6B
    a=ice-options:trickle
    a=fingerprint:sha-256 CA:83:D0:0F:3B:27:4C:8F:F4:DB:34:58:AC:A6:5D:36:01:07:9F:2B:1D:95:29:AD:0C:F8:08:68:34:D8:62:A7
    a=setup:active
    //前面BUNDLE行中用到的媒体标识
    a=mid:data
    //使用端口5000,一个消息的大小是1024比特
    a=sctpmap:5000 webrtc-datachannel 1024

    以上就是一个SessionDescription的例子,虽然没有video的描述,但是video和audio的描述是十分类似的。 SDP中有关于IP和端口的描述,但是WebRTC技术并没有使用这些内容,那么双方是怎么建立"直接"连接的呢?建立起连接最关键的IP和端口是从哪里来的呢?这就需要ICE框架来完成这部分工作。

    连接的建立

    相关概念

    ICE

    互动式连接建立(Interactive Connectivity Establishment)提供的是一种框架,使各种NAT穿透技术(STUN,TURN...)可以实现统一。该技术可以让客户端成功地穿透远程用户与网络之间可能存在的各类防火墙。

    NAT

    网路地址转换(Network Address Translation)可为你的装置提供公用IP地址。路由器具备公用IP地址,而连上路由器的所有装置则具备私有IP地址。接着针对请求,从装置的私有IP对应到路由器的公用IP与专属的通讯端口。如此一来,各个装置不需占用专属的公用IP,亦可在网路上被清楚识别。

    STUN

    NAT 的UDP简单穿越(Simple Traversal of UDP over NATs)是一种网络协议,它允许位于NAT(或多重NAT)后的客户端找出自己的公网地址,查出自己位于哪种类型的NAT之后以及NAT为某一个本地端口所绑定的Internet端端口。这些信息被用来在两个同时处于NAT路由器之后的主机之间建立UDP通信。

    即使通过 STUN 服务器取得了公用 IP 地址,也不一定能建立连线。因为不同的NAT类型处理传入的UDP分组的方式是不同的。四种主要类型中有三种是可以使用STUN穿透:完全圆锥型NAT、受限圆锥型NAT和端口受限圆锥型NAT。但大型公司网络中经常采用的对称型 NAT(又称为双向NAT)则不能使用,这类路由器会通过 NAT 布署所谓的「Symmetric NAT」限制。也就是说,路由器只会接受你之前连线过的节点所建立的连线。这类网络就需要TURN技术。

    TURN

    中继NAT实现的穿透(Traversal Using Relays around NAT)就是通过TURN服务器开启连线并转送所有数据,进而绕过Symmetric NAT的限制。你可通过TURN服务器建立连线,再告知所有端点传送封包至该服务器,最后让服务器转送封包给你。这个方法更耗时且更占频宽,因此在没有其他替代方案时才会使用这个方法。

     

    连接建立过程

    介绍完ICE框架中各个独立部分的含义之后,在让我们来看一看整个框架是如何工作的。

    转自:https://www.cnblogs.com/vipzhou/p/7994927.html

    WebRTC介绍及简单应用


    WebRTC,即Web Real-Time Communication,web实时通信技术。简单地说就是在web浏览器里面引入实时通信,包括音视频通话等。

    • WebRTC实时通信技术介绍
    • 如何使用
    • 媒体介绍
    • 信令
    • STUN和TURN介绍
    • 对等连接和提议/应答协商
    • 数据通道
    • NAT和防火墙穿透
    • 简单应用
    • 其它

    WebRTC实时通信技术介绍

    WebRTC实现了基于网页的语音对话或视频通话,目的是无插件实现web端的实时通信的能力。

    WebRTC提供了视频会议的核心技术,包括音视频的采集、编解码、网络传输、展示等功能,并且还支持跨平台,包括linux、windows、mac、android等。

    1. WebRTC三角形

    image

    2. WebRTC梯形

    image

    3. WebRTC的多方会话

    WebRTC支持多个浏览器参与的多方会话或会议会话,要建立这类会话有如下两种模式:

    image

    image

    4. WebRTC新功能特性

    image


    如何使用WebRTC

    WebRTC易于使用,只需极少步骤便可建立媒体会话。有些消息在浏览器和服务器之间流动,有些则直接在两个浏览器(成为对等端)之间流动。

    1、建立WebRTC会话

    建立WebRTC连接需要如下几个步骤:

    • 获取本地媒体(getUserMedia()MediaStream API
    • 在浏览器和对等端(其它浏览器或终端)之间建立对等连接(RTCPeerConnection API
    • 将媒体和数据通道关联至该连接
    • 交换会话描述(RTCSessionDescription

    image

    • 浏览器M从Web服务器请求网页
    • Web服务器向M返回带有WebRTC js的网页
    • 浏览器L从Web服务器请求网页
    • Web服务器向L返回带有WebRTC js的网页
    • M决定与L通信,通过M自身的js将M的会话描述对象(offer,提议)发送至Web服务器
    • Web服务器将M的会话描述对象发送至L上的js
    • L上的js将L的会话描述对象(answer,应答)发送至Web服务器
    • Web服务器转发应答至M上的js
    • M和L开始交互,确定访问对方的最佳方式
    • 完成后,M和L开始协商通信密钥
    • M和L开始交换语音、视频或数据

    WebRTC三角形会话具体的调用流程:

    image

    说明:
        SDP对象的传输可能是一个来回反复的过程,并且该过程采用的协议并未标准化

    WebRTC梯形会话方式具体的调用流程:

    image

    说明:
        此场景中,浏览器M和L直接交换媒体,只是它们运行的Web服务器不用而已。每个浏览器的会话描述对象都会映射至Jingle[XEP-0166]session-initiate消息和session-accept方法。
        

    媒体介绍

    先来看下WebRTC中的本地媒体:

    1、WebRTC中的媒体

    • 轨道(MediaStreamTrack,代表设备或录制内容可返回的单一类型的媒体,唯一关联一个“源”,WebRTC不能直接访问或控制“源”,对“源”的一切控制都通过轨道实施;一个“源”可能对应多个轨道对象)
    • 流(MediaStream,轨道对象的集合)

    轨道和流的示意如下:

    image

    2、捕获本地媒体

    如下代码展示了本地媒体的简单获取,并展示:

    // 注意getUserMedia()在各浏览器中的区别  
    // Opera --> getUserMedia  
    // Chrome --> webkitGetUserMedia  
    // Firefox --> mozGetUserMedia  
    navigator.getUserMedia = navigator.getUserMedia || navigator.webkitGetUserMedia || navigator.mozGetUserMedia;  
      
    // 只获取video:  
    var constraints = {audio: false, video: true};  
    var video = document.querySelector("video");  
      
    function successCallback(stream) {  
        // Note: make the returned stream available to console for inspection  
        window.stream = stream;  
          
    if (window.URL) {  
            // Chrome浏览器
            video.srcObject = stream;  
        } else {  
            // Firefox和Opera: 可以直接把视频源设置为stream  
            video.src = stream;  
        }  
        // 播放  
        video.play();  
    }  
      
    function errorCallback(error){  
        console.log("navigator.getUserMedia error: ", error);  
    }  
      
    navigator.getUserMedia(constraints, successCallback, errorCallback);

    运行效果如下:

    image

    完整代码查看:https://github.com/caiya/webrtc-demo.git

    end

    end

  • 相关阅读:
    2017.08.07 python爬虫实战之使用代理爬取糗事百科
    2017.08.05 Python网络爬虫实战之获取代理
    2017.08.04 Python网络爬虫之Scrapy爬虫实战二 天气预报的数据存储问题
    2017.08.04 Python网络爬虫之Scrapy爬虫实战二 天气预报
    2017.07.28 Python网络爬虫之爬虫实战 重新梳理------今日影视爬虫(使用Scrapy爬取ajax动态页面)
    2017.07.28 Python网络爬虫之爬虫实战 今日影视2 获取JS加载的数据
    RabbitMQ之工作队列
    pt-online-schema-change和默认值关系
    flex词法解析
    Makefile持续学习二
  • 原文地址:https://www.cnblogs.com/lindows/p/15963528.html
Copyright © 2020-2023  润新知