WebRTC中如何设置视频的码流

WebRTC原生就是为了p2p通话而设计的,视频的码流会尽量匹配你的带宽。你会发现,当两个客户端在局域网内
通话时,视频的码流会非常大,有时会达到两三兆。在有些业务场景下,你可能不希望要这么大的视频码流,比如会占用
你的服务器很大的带宽。如果我们能够灵活的控制视频码流,这对节省服务器带宽会非常有用。
      在WebRTC生成的SDP中,与视频编码相关的部分如下:
a=rtpmap:100 VP8/90000
a=rtcp-fb:100 ccm fir
a=rtcp-fb:100 nack
a=rtcp-fb:100 nack pli
a=rtcp-fb:100 goog-remb
a=rtcp-fb:100 transport-cc
a=rtpmap:101 VP9/90000
a=rtcp-fb:101 ccm fir
a=rtcp-fb:101 nack
a=rtcp-fb:101 nack pli
a=rtcp-fb:101 goog-remb
a=rtcp-fb:101 transport-cc
a=rtpmap:107 H264/90000
a=rtcp-fb:107 ccm fir
a=rtcp-fb:107 nack
a=rtcp-fb:107 nack pli
a=rtcp-fb:107 goog-remb
a=rtcp-fb:107 transport-cc
a=fmtp:107 level-asymmetry-allowed=1;packetization-mode=1;profile-level-id=42e01f

如果你希望控制VP8编码的码流,你可以把SDP修改成如下

a=rtcp-fb:100 transport-cc
a=fmtp:100 x-google-max-bitrate=2800;x-google-min-bitrate=1200;x-google-start-bitrate=200000 这一行是新加的
a=rtpmap:101 VP9/90000

如果你希望控制VP9编码的码流,你可以把SDP修改成如下
a=rtcp-fb:101 transport-cc
a=fmtp:101 x-google-max-bitrate=2800;x-google-min-bitrate=1200;x-google-start-bitrate=200000 这一行是新加的
a=rtpmap:107 H264/90000

如果你希望控制H264编码的码流,你可以把SDP修改成如下

a=fmtp:107 level-asymmetry-allowed=1;packetization-mode=1;profile-level-id=42e01f;x-google-max-bitrate=2800;x-google-min-bitrate=1200;x-google-start-bitrate=200000

下面我来解释码流控制相关的三个参数:
x-google-max-bitrate:视频码流最大值,当网络特别好时,码流最大能达到这个值,如果不设置这个值,网络好时码流会非常大
x-google-min-bitrate:视频码流最小值,当网络不太好时,WebRTC的码流每次5%递减,直到这个最小值为,如果没有设置这个值,网络不好时,视频质量会非常差
x-google-start-bitrate:视频编码初始值 ,当网络好时,码流会向最大值递增,当网络差时,码流会向最小值递减

在PeerConnection调用setRemoteDescription前修改SDP就会生效,本人已经在WebRTC56版本中实验成功。

作者:onlycoder_net
来源:CSDN
原文:https://blog.csdn.net/onlycoder_net/article/details/76702729
版权声明:本文为博主原创文章,转载请附上博文链接!

Webrt中H264编码相关问题

编译WebRTC后,默认是没有把H264编码编进来的。WebRTC中H264编码采用的是openh264,解码默认采用的是
ffmpeg,移动版本android,ios默认采用的是系统的h264硬件编码,如果你的手机支持H264硬件编码的话,WebRTC
就会默认支持H264.

1.如何在桌面版本中开启H264编码
  使用gn生成ninja文件时,加入以下两个选项就可以生成 ffmpeg_branding=”Chrome” rtc_use_h264=true,比如我
要编译Linux版本,使用以下命令 gn gen out/linux –args=’target_os=”linux” target_cpu=”x64″ is_component_build=false 
is_debug=false ffmpeg_branding=”Chrome” rtc_use_h264=true’,再输入ninja -C out/linux video_loopback,就会在out/linux
目录下生成video_loopback可执行文件,你进入到out/linux目录下,输入./video_loopback –codec=H264就可以看到效果了,
这个在WebRTC56版本,ubuntu14.04环境下测试。

2.如何在安卓版本中调试h264硬件编解码

       WebRTC是通过jni调用Android系统中的MediaCodec api来实现硬件编解码的,我通过分析代码发现,硬件解码的实现在org.webrtc.

MediaCodecVideoDecoder中实现的,目前WebRTC官方只调试过高通,三星等大厂商的芯片,像其它的比如海思,联发科,全志之类等
芯片,你要想把这些芯片的H264硬件解码调出来,就需要自己修改WebRTC的java代码了,在MediaCodecVideoDecoder.java中有以下代码

  private static final String[] supportedVp8HwCodecPrefixes = {“OMX.qcom.”, “OMX.Nvidia.”, “OMX.Exynos.”, “OMX.Intel.”};
  private static final String[] supportedVp9HwCodecPrefixes = {“OMX.qcom.”, “OMX.Exynos.”};
  private static final String[] supportedH264HwCodecPrefixes = {“OMX.qcom.”, “OMX.Intel.”, “OMX.Exynos.”};

以下代码的意思就是VP8硬件解码只支持高通,英伟达,三星,英特尔,VP9硬件解码只支持高通和三星,H264硬件解码只支持高通,英特尔,三星。
比如我知道海思的芯片支持H264硬件解码,我只需要修改一行就可以调试出来。
private static final String[] supportedH264HwCodecPrefixes = {“OMX.qcom.”, “OMX.Intel.”, “OMX.Exynos.”,”OMX.hisi.”};

说完解码我们再来看编码,硬件编码在的MediaCodec api来实现硬件编解码的,我通过分析代码发现,硬件解码的实现在org.webrtc.
MediaCodecVideoEncoder中,关键代码如下,
private static final MediaCodecProperties qcomH264HwProperties = new MediaCodecProperties(
      “OMX.qcom.”, Build.VERSION_CODES.KITKAT, BitrateAdjustmentType.NO_ADJUSTMENT);
private static final MediaCodecProperties exynosH264HwProperties = new MediaCodecProperties(
      “OMX.Exynos.”, Build.VERSION_CODES.LOLLIPOP, BitrateAdjustmentType.FRAMERATE_ADJUSTMENT);
private static final MediaCodecProperties[] h264HwList =
      new MediaCodecProperties[] {qcomH264HwProperties, exynosH264HwProperties};

以下代码的意思是WebRTC默认只支持高通和三星的芯片才有H264硬件编码,我现在想把海思的H264硬件编码也加进来,需要修成成以下这样:
private static final MediaCodecProperties qcomH264HwProperties = new MediaCodecProperties(
      “OMX.qcom.”, Build.VERSION_CODES.KITKAT, BitrateAdjustmentType.NO_ADJUSTMENT);
  private static final MediaCodecProperties exynosH264HwProperties = new MediaCodecProperties(
      “OMX.Exynos.”, Build.VERSION_CODES.LOLLIPOP, BitrateAdjustmentType.FRAMERATE_ADJUSTMENT);
  private static final MediaCodecProperties hihsH264HwProperties = new MediaCodecProperties(
    “OMX.hisi.”, Build.VERSION_CODES.KITKAT, BitrateAdjustmentType.NO_ADJUSTMENT);
  private static final MediaCodecProperties[] h264HwList =
      new MediaCodecProperties[] {qcomH264HwProperties, exynosH264HwProperties,hihsH264HwProperties};

我模仿高通的编码加了一行,并加入到h264HwList数组中,这样海思的H264硬件编码也在WebRTC中调试出来了。

作者:onlycoder_net
来源:CSDN
原文:https://blog.csdn.net/onlycoder_net/article/details/76703812
版权声明:本文为博主原创文章,转载请附上博文链接!

WebRTC通话过程中如何避免其它进程音量下降

在Windows下,WebRTC通话过程中,会把其它进程的音量自动下降,比如音乐播放器。
如何避免这种情况呢?其实很简单,只要修改一下注册表就可以了,用Qt的实现方法如下:

void disableCommunicationReduce()
{
        static const QString key = “HKEY_CURRENT_USER\SOFTWARE\Microsoft\Multimedia\Audio”;
        QSettings settings(key, QSettings::NativeFormat);
        settings.setValue(“UserDuckingPreference”, 3);

}

作者:onlycoder_net
来源:CSDN
原文:https://blog.csdn.net/onlycoder_net/article/details/76781141
版权声明:本文为博主原创文章,转载请附上博文链接!

WebRTC原生开发和混合开发优缺点分析对比

WebRTC的出现,让企业快速开发出一个支持全平台的音视频程序成为可能。在WebRTC之前,企业想要开发出一个全平台的音视频程序,难度,工作量非常大。使用WebRTC后,音视频程序中一些通用的模块比如音视频采集,播放模块,rtp,rtcp协议模块,都可以直接复用WebRTC现成的,不用自己再重复造轮子。这些模块开发难度不是很大,但是工作量非常大。使用WebRTC后,企业可以专注于优化流程,解决bug,实现业务需求。

目前,开发WebRTC程序有两种途径
原生开发,自己下载WebRTC代码,每个平台自己编译。在WebRTC API基础上自己再做封装和二次开发。
调用WebRTC javascript接口,WebRTC程序必须运行在支持WebRTC的浏览器中,用到的技术有javascript,html,css。windows,android,ios,linux可以共用一套代码。

在下面的文章中,我们将详细阐述WebRTC原生开发和混合开发之间的主要区别。

WebRTC 原生开发
WebRTC代码是用C++开发的,如果采用原生开发,团队中必须要有人对C++精通。而且如果要想能看懂和修改WebRTC代码,只是会C++是远远不够的,还要对流媒体技术很熟悉。WebRTC涉及的rfc文档有20多个,如果没有理论知识做支撑,WebRTC代码真的不是哪么容易可以看懂的。开发windows端,android端,ios端WebRTC程序,需要用到的技术和人员配置大概如下:

windows端,界面采用Qt或者DirectUI,直接使用C++接口调用WebRTC的功能,人员至少需要一个Windows客户端开发人员和WebRTC SDK开发人员。
android端,界面采用android原生界面,使用jni技术调用WebRTC功能,人员配置方面至少需要一个安卓开发人员和WebRTC 安卓SDK开发人员。
Ios端,界面采用ios原生技术,使用oc调用WebRTC功能,人员配置方面至少需要一个ios开发人员和一个WebRTC SDK开发人员

综上所述,可以发现如果采用原生技术开发,需要的开发人员还是比较多的,涉及的技术点也多,相应的测试人员的工作量也大,想要把三个端的客户端全部做好,难度还是挺大的。

目前,WebRTC桌面版本稳定性和兼容性做的还比较好。移动版本由于移动版本的chrome使用的人比较少,Google在这方面投入还不够多,兼容性和稳定性还有很多要提高的地方。如果你的应用程序手机型号比较复杂,哪只能使用原生开发了,你可以在WebRTC官方版本之上把兼容性和稳定性做的更好。

安卓版本只有在安卓4.4以后的WebView才支持WebRTC功能,Ios版本的的chrome根本不支持WebRTC功能,据说Ios11版本的safari会支持WebRTC,但是在兼容性方面和chrome的WebRTC会有些兼容性问题。所有你的用户还有比较老的手机的话,哪你也只能采用原生开发了。

        原生开发时,编译出来的WebRTC开发包大小在3M左右,而采用混合开发的话,App最后打包出来的大小都是在30M以上,所以如果你的应用程度如果对程序安装包大小有要求的话,也只能采用原生开发。
       最后,如果你的应该程序还要加上H265之类的视频编码,或者对视频,音频输入源有特殊要求的话,都只能采用原生开发。
WebRTC混合应用开发

采用混合应用工发WebRTC程序,就是用javascript调用WebRTC接口,使用html,css来做显示界面。目前使用Html5来开发App和桌面程序也慢慢流行起来,比如React native技术。混合应用开发的好处就是一套代码可以兼容
windows,mac,ipad,ios,android,浏览器,一个全栈前端开发人员就可以全部搞定,开发工期比较短,难度也相对低一点。使用混合应用开发的缺点就是不能定制WebRTC底层,你只能使用WebRTC标准功能,如果WebRTC底层有bug,你也没有办法修改,还有一个缺点就是安装包比较大。
    采用html5来开发WebRTC还有一个优势就是你可以在手机QQ,微信安卓版本中直接跳转,这意味用户不用安装任何程序,直接可以从微信或者手机QQ转你你的程序,这对于推广还是比较有利的。

结论
采用原生开发还是混合开发,没有决对的好坏之分。这要根据你团队研发人员的情况和目标客户情况灵活对待。
1.如果团队前端实力比较强,哪你就使用混合开发模式。
2.如果App面向的是的用户量非常大,手机型号还不好固定,哪只能采用原生开发。
3.如果目标客户是企业客户,对安装包大小不在意,手机型号也好固定。哪可以采用混合开发。
4.如果要对接监控摄像头之类的非标准音视频设备,或者要采用VP8,VP9之外的其它视频编码,哪只能

   采用原生开发了。

作者:onlycoder_net
来源:CSDN
原文:https://blog.csdn.net/onlycoder_net/article/details/76796892
版权声明:本文为博主原创文章,转载请附上博文链接!

Safari即将支持WebRTC

自从开始做WebRTC开发以来,经常被别人问到,safari浏览器能支持WebRTC吗?我也很希望safari能支持WebRTC,这样就不用写原生WebRTC应用或者Safari浏览器插件了。
很高兴的是,近期Apple公司宣布,WebRTC将会进入Safari和iOS 11。事实上,如果你是苹果的注册开发者,你就可以尝试使用支持WebRTC的测试版Safari浏览器。我提前试用了下测试版本的safari,写了一个最简单的WebRTC小程序在上面运行了一下。下面我把我遇到的几个总是和大家分享一下:
safari和safari相连接很快就成功了,但是当safari和chrome,firefox相连接时,设置Offer sdp或者设置answer sdp时会发生以下异常:TypeError: Attempted to assign to readonly property.
与chrome相比,getStats 接口也有点不一样。如果在Chrome中如果没有传选择器参数,你还可以得到许多数据,但是在Safari中做同样的事情会抛出以下错误:Argument 1 (‘selector’) to RTCPeerConnection. getStats must be an instance of MediaStreamTrack
在chrome中,我们可以在一个PeerConnection中同时创建多个Datachannels,但是在Safari中是行不通的。当然这个问题我们是可以通过其它方式绕开的,但是我还是希望Safari的接口能和chrome保持一致。

这就是我暂时发现Safari测试版本中的几个小问题,如果你们也在试用Safari,有什么新的发现,可以和我交流一下。

WebRTC中如何设置视频的码流

WebRTC原生就是为了p2p通话而设计的,视频的码流会尽量匹配你的带宽。你会发现,当两个客户端在局域网内
通话时,视频的码流会非常大,有时会达到两三兆。在有些业务场景下,你可能不希望要这么大的视频码流,比如会占用
你的服务器很大的带宽。如果我们能够灵活的控制视频码流,这对节省服务器带宽会非常有用。
      在WebRTC生成的SDP中,与视频编码相关的部分如下:
a=rtpmap:100 VP8/90000
a=rtcp-fb:100 ccm fir
a=rtcp-fb:100 nack
a=rtcp-fb:100 nack pli
a=rtcp-fb:100 goog-remb
a=rtcp-fb:100 transport-cc
a=rtpmap:101 VP9/90000
a=rtcp-fb:101 ccm fir
a=rtcp-fb:101 nack
a=rtcp-fb:101 nack pli
a=rtcp-fb:101 goog-remb
a=rtcp-fb:101 transport-cc
a=rtpmap:107 H264/90000
a=rtcp-fb:107 ccm fir
a=rtcp-fb:107 nack
a=rtcp-fb:107 nack pli
a=rtcp-fb:107 goog-remb
a=rtcp-fb:107 transport-cc
a=fmtp:107 level-asymmetry-allowed=1;packetization-mode=1;profile-level-id=42e01f

如果你希望控制VP8编码的码流,你可以把SDP修改成如下

a=rtcp-fb:100 transport-cc
a=fmtp:100 x-google-max-bitrate=2800;x-google-min-bitrate=1200;x-google-start-bitrate=200000 这一行是新加的
a=rtpmap:101 VP9/90000

如果你希望控制VP9编码的码流,你可以把SDP修改成如下
a=rtcp-fb:101 transport-cc
a=fmtp:101 x-google-max-bitrate=2800;x-google-min-bitrate=1200;x-google-start-bitrate=200000 这一行是新加的
a=rtpmap:107 H264/90000

如果你希望控制H264编码的码流,你可以把SDP修改成如下

a=fmtp:107 level-asymmetry-allowed=1;packetization-mode=1;profile-level-id=42e01f;x-google-max-bitrate=2800;x-google-min-bitrate=1200;x-google-start-bitrate=200000

下面我来解释码流控制相关的三个参数:
x-google-max-bitrate:视频码流最大值,当网络特别好时,码流最大能达到这个值,如果不设置这个值,网络好时码流会非常大
x-google-min-bitrate:视频码流最小值,当网络不太好时,WebRTC的码流每次5%递减,直到这个最小值为,如果没有设置这个值,网络不好时,视频质量会非常差
x-google-start-bitrate:视频编码初始值 ,当网络好时,码流会向最大值递增,当网络差时,码流会向最小值递减

在PeerConnection调用setRemoteDescription前修改SDP就会生效,本人已经在WebRTC56版本中实验成功。

WebRTC56版本SDP详细解析

v=0
//sdp版本号,一直为0,rfc4566规定
o=- 7017624586836067756 2 IN IP4 127.0.0.1
// RFC 4566 o=
//username如何没有使用-代替,7017624586836067756是整个会话的编号,2代表会话版本,如果在会话
//过程中有改变编码之类的操作,重新生成sdp时,sess-id不变,sess-version加1
s=-
//会话名,没有的话使用-代替
t=0 0
//两个值分别是会话的起始时间和结束时间,这里都是0代表没有限制
a=group:BUNDLE audio video data
//需要共用一个传输通道传输的媒体,如果没有这一行,音视频,数据就会分别单独用一个udp端口来发送
a=msid-semantic: WMS h1aZ20mbQB0GSsq0YxLfJmiYWE9CBfGch97C
//WMS是WebRTC Media Stream简称,这一行定义了本客户端支持同时传输多个流,一个流可以包括多个track,
//一般定义了这个,后面a=ssrc这一行就会有msid,mslabel等属性
m=audio 9 UDP/TLS/RTP/SAVPF 111 103 104 9 0 8 106 105 13 126
//m=audio说明本会话包含音频,9代表音频使用端口9来传输,但是在webrtc中一现在一般不使用,如果设置为0,代表不
//传输音频,UDP/TLS/RTP/SAVPF是表示用户来传输音频支持的协议,udp,tls,rtp代表使用udp来传输rtp包,并使用tls加密
//SAVPF代表使用srtcp的反馈机制来控制通信过程,后台111 103 104 9 0 8 106 105 13 126表示本会话音频支持的编码,后台几行会有详细补充说明
c=IN IP4 0.0.0.0
//这一行表示你要用来接收或者发送音频使用的IP地址,webrtc使用ice传输,不使用这个地址
a=rtcp:9 IN IP4 0.0.0.0
//用来传输rtcp地地址和端口,webrtc中不使用
a=ice-ufrag:khLS
a=ice-pwd:cxLzteJaJBou3DspNaPsJhlQ
//以上两行是ice协商过程中的安全验证信息
a=fingerprint:sha-256 FA:14:42:3B:C7:97:1B:E8:AE:0C2:71:03:05:05:16:8F:B9:C7:98:E9:60:43:4B:5B:2C:28:EE:5C:8F3:17
//以上这行是dtls协商过程中需要的认证信息
a=setup:actpass
//以上这行代表本客户端在dtls协商过程中,可以做客户端也可以做服务端,参考rfc4145 rfc4572
a=mid:audio
//在前面BUNDLE这一行中用到的媒体标识
a=extmap:1 urn:ietf:params:rtp-hdrext:ssrc-audio-level
//上一行指出我要在rtp头部中加入音量信息,参考 rfc6464
a=sendrecv
//上一行指出我是双向通信,另外几种类型是recvonly,sendonly,inactive
a=rtcp-mux
//上一行指出rtp,rtcp包使用同一个端口来传输
//下面几行都是对m=audio这一行的媒体编码补充说明,指出了编码采用的编号,采样率,声道等
a=rtpmap:111 opus/48000/2
a=rtcp-fb:111 transport-cc
//以上这行说明opus编码支持使用rtcp来控制拥塞,参考https://tools.ietf.org/html/draft-holmer-rmcat-transport-wide-cc-extensions-01
a=fmtp:111 minptime=10;useinbandfec=1
//对opus编码可选的补充说明,minptime代表最小打包时长是10ms,useinbandfec=1代表使用opus编码内置fec特性
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:126 telephone-event/8000
a=ssrc:18509423 cname:sTjtznXLCNH7nbRw
//cname用来标识一个数据源,ssrc当发生冲突时可能会发生变化,但是cname不会发生变化,也会出现在rtcp包中SDEC中,
//用于音视频同步
a=ssrc:18509423 msid:h1aZ20mbQB0GSsq0YxLfJmiYWE9CBfGch97C 15598a91-caf9-4fff-a28f-3082310b2b7a
//以上这一行定义了ssrc和WebRTC中的MediaStream,AudioTrack之间的关系,msid后面第一个属性是stream-d,第二个是track-id
a=ssrc:18509423 mslabel:h1aZ20mbQB0GSsq0YxLfJmiYWE9CBfGch97C
a=ssrc:18509423 label:15598a91-caf9-4fff-a28f-3082310b2b7a
m=video 9 UDP/TLS/RTP/SAVPF 100 101 107 116 117 96 97 99 98
//参考上面m=audio,含义类似
c=IN IP4 0.0.0.0
a=rtcp:9 IN IP4 0.0.0.0
a=ice-ufrag:khLS
a=ice-pwd:cxLzteJaJBou3DspNaPsJhlQ
a=fingerprint:sha-256 FA:14:42:3B:C7:97:1B:E8:AE:0C2:71:03:05:05:16:8F:B9:C7:98:E9:60:43:4B:5B:2C:28:EE:5C:8F3:17
a=setup:actpass
a=mid:video
a=extmap:2 urn:ietf:params:rtp-hdrext:toffset
a=extmap:3 http://www.webrtc.org/experiments/rtp-hdrext/abs-send-time
a=extmap:4 urn:3gpp:video-orientation
a=extmap:5 http://www.ietf.org/id/draft-hol … de-cc-extensions-01
a=extmap:6 http://www.webrtc.org/experiments/rtp-hdrext/playout-delay
a=sendrecv
a=rtcp-mux
a=rtcp-rsize
a=rtpmap:100 VP8/90000
a=rtcp-fb:100 ccm fir
//ccm是codec control using RTCP feedback message简称,意思是支持使用rtcp反馈机制来实现编码控制,fir是Full Intra Request
//简称,意思是接收方通知发送方发送幅完全帧过来
a=rtcp-fb:100 nack
//支持丢包重传,参考rfc4585
a=rtcp-fb:100 nack pli
//支持关键帧丢包重传,参考rfc4585
a=rtcp-fb:100 goog-remb
//支持使用rtcp包来控制发送方的码流
a=rtcp-fb:100 transport-cc
//参考上面opus
a=rtpmap:101 VP9/90000
a=rtcp-fb:101 ccm fir
a=rtcp-fb:101 nack
a=rtcp-fb:101 nack pli
a=rtcp-fb:101 goog-remb
a=rtcp-fb:101 transport-cc
a=rtpmap:107 H264/90000
a=rtcp-fb:107 ccm fir
a=rtcp-fb:107 nack
a=rtcp-fb:107 nack pli
a=rtcp-fb:107 goog-remb
a=rtcp-fb:107 transport-cc
a=fmtp:107 level-asymmetry-allowed=1;packetization-mode=1;profile-level-id=42e01f
//h264编码可选的附加说明
a=rtpmap:116 red/90000
//fec冗余编码,一般如果sdp中有这一行的话,rtp头部负载类型就是116,否则就是各编码原生负责类型
a=rtpmap:117 ulpfec/90000
//支持ULP FEC,参考rfc5109
a=rtpmap:96 rtx/90000
a=fmtp:96 apt=100
//以上两行是VP8编码的重传包rtp类型
a=rtpmap:97 rtx/90000
a=fmtp:97 apt=101
a=rtpmap:99 rtx/90000
a=fmtp:99 apt=107
a=rtpmap:98 rtx/90000
a=fmtp:98 apt=116
a=ssrc-group:FID 3463951252 1461041037
//在webrtc中,重传包和正常包ssrc是不同的,上一行中前一个是正常rtp包的ssrc,后一个是重传包的ssrc
a=ssrc:3463951252 cname:sTjtznXLCNH7nbRw
a=ssrc:3463951252 msid:h1aZ20mbQB0GSsq0YxLfJmiYWE9CBfGch97C ead4b4e9-b650-4ed5-86f8-6f5f5806346d
a=ssrc:3463951252 mslabel:h1aZ20mbQB0GSsq0YxLfJmiYWE9CBfGch97C
a=ssrc:3463951252 label:ead4b4e9-b650-4ed5-86f8-6f5f5806346d
a=ssrc:1461041037 cname:sTjtznXLCNH7nbRw
a=ssrc:1461041037 msid:h1aZ20mbQB0GSsq0YxLfJmiYWE9CBfGch97C ead4b4e9-b650-4ed5-86f8-6f5f5806346d
a=ssrc:1461041037 mslabel:h1aZ20mbQB0GSsq0YxLfJmiYWE9CBfGch97C
a=ssrc:1461041037 label:ead4b4e9-b650-4ed5-86f8-6f5f5806346d
m=application 9 DTLS/SCTP 5000
c=IN IP4 0.0.0.0
a=ice-ufrag:khLS
a=ice-pwd:cxLzteJaJBou3DspNaPsJhlQ
a=fingerprint:sha-256 FA:14:42:3B:C7:97:1B:E8:AE:0C2:71:03:05:05:16:8F:B9:C7:98:E9:60:43:4B:5B:2C:28:EE:5C:8F3:17
a=setup:actpass
a=mid:data

a=sctpmap:5000 webrtc-datachannel 1024

WebRTC中OPUS编码相关设置和分析

新版本的WebRTC默认是采用OPUS编码,OPUS编码是silk编码和celt编码的合成,silk编码是skype公司开源的一个编码,
特别适合语音通信,它根据人的声音做了很多优化,但不是适合传输高质量的音乐。celt编码相反更适合传输高质量的音乐。
OPUS编码在采样率很高的情况下,音质还是非常不错的,以下这个连接地址有很多opus的音频样例,大家可以在线听听。
http://www.opus-codec.org/examples/

       根据阅读官方文档知道OPUS编码支持8000,16000,32000,48000等几种编码,支持单声道,双声道,支持6kb-510kb编码率。如果我们想改变WebRTC的声音
编码参数,我们应该如何做呢?
       1.首先我会先去看看WebRTC有没有引出相关的接口,结果查看了PeerConnection,MediaStream,AudioTrack等等相关的类后,根本没有发现相关接口。
       2.根据以往经验,如果WebRTC没有提供直接的接口来调,往往还可以通过修改SDP参数和达到我们的目的。我把生成的Offer SDP打印出来后,发现了比较可疑的地
         方,”fmtp:111 minptime=10;useinbandfec=1″,这一行是设置opus编码参数的地方。我再以“useinbandfec”为关键字在WebRTC中代码中搜索,
       在mediaconstants.cc代码,找到以下相关代码
         // draft-spittka-payload-rtp-opus-03.txt
             const char kCodecParamPTime[] = “ptime”;
             const char kCodecParamMaxPTime[] = “maxptime”;
             const char kCodecParamMinPTime[] = “minptime”;
             const char kCodecParamSPropStereo[] = “sprop-stereo”;
             const char kCodecParamStereo[] = “stereo”;
             const char kCodecParamUseInbandFec[] = “useinbandfec”;
             const char kCodecParamUseDtx[] = “usedtx”;
             const char kCodecParamMaxAverageBitrate[] = “maxaveragebitrate”;
             const char kCodecParamMaxPlaybackRate[] = “maxplaybackrate”;
       3.我依葫芦画瓢,在我自己写的demo代码中把sdp中的”fmtp:111 minptime=10;useinbandfec=1″ 这一行替换成”fmtp:111 minptime=10;useinbandfec=1;maxaveragebitrate =8000″,编译成功运行后,发现参数生效了,发送一路语音占用的带宽由于5K变成了3K左右,这就证明参数生效了。

      4.在网络挺别差的情况下,我们可能希望声音的码流再变小一点,对音质的要求反而不是哪么高了,音频采样率为8000HZ就够了。要实现这个功能的话把”fmtp:111 minptime=10;useinbandfec=1″ 这一行替换成”fmtp:111 minptime=10;useinbandfec=1;maxaveragebitrate =6000;maxplaybackrate=8000″就行了

     5.如果要传音乐,哪我们必需强制OPUS切换到CELT编码。要实现这个功能的话把”fmtp:111 minptime=10;useinbandfec=1″ 这一行替换成”fmtp:111 minptime=10;useinbandfec=1;maxaveragebitrate =64000;maxplaybackrate=48000;stereo=1″就行了

以下功能在WebRTC56版本中试验成功,修改SDP的时机在 SetRemoteDescription 之前,把对方传过来的SDP字符串给替换了,再调用SetRemoteDescription方法

如何在没有https环境下使用webrtc

新版本的webrtc使用需要Https,但是在内网开发调试时,要配置Https环境比较麻烦,哪有没有
办法绕过https的限制呢?下面的方法是教你如何在http下使用webrtc

1,点桌面上的Chrome图票,右键->属性,把目票输入框中的内容换成以下内容

“C:\Program Files (x86)\Google\Chrome\Application\chrome.exe” –unsafely-treat-insecure-origin-as-secure=”http://ip:port” –user-data-dir=本地目录
把字符串中的ip:port换成你自己的服务器的ip加端口,本地目录换成你自己本地一个文件夹

2,再重启chrome就可以了

WebRTC自适应网络带宽之联播方案

假设在一个多个用户参与的视频直播系统中,大部分用户的网络都是非常好,但是只有一两个用户用的是3G,4G上网,网络质量不太好。这种情况下对于发布方应该如何处理呢?一种比较容易想到的方案就是降低发布方的视频码流,这样不管网络好还是网络不好的用户都可以流畅观看视频了,这种方案有个致命缺陷,大部分网络好的用户被少数几个网络差的用户给拖累了。

如上图所示,发布方只能发布低于0.5M的码流了,白白浪费的其它用户的10M带宽。

哪有没有什么方案能照顾到网络好的用户和网络差的用户呢?当然是有的,还不只一种,我们现在先来介绍其中的一种,联播(Simulcast)技术。顾名思义,联播就是发布方同时发布几路不同码流的视频到服务器(SFU)上来,SFU根据接收方的网络状态转发相应的码流给接收用户,上面这种情况如果用联播技术来解决的话,可以给出以下架构图:

上图中发布方同时发布9M视频码流和0.4M的视频码流,这样就可以同时兼兼顾到网络好的用户和网络差的用户了。在这里有些同学可能要问为什么不直接发布10M的码流和0.5M的码流呢?哪是因为我们平时说的多少M的码流只是编码好后的裸数据,在网络传输中还要加上rtp头之类的数据,所有在实际应用中,编码出来的码流一般都要比你的实际网络带宽低一些。

联播技术在WebRTC中是如何实现的呢?WebRTC默认是没有开启联播功能的。想要使用联播功能,首先第一步我们要把他开启起来,我们把生成的Offer SDP修改一下就好了:
原生的Offer SDP中有这么一段:

a=ssrc-group:FID 3383221279 2661971602
a=ssrc:3383221279 cname:Yy4JddEmmT7fHiQO
a=ssrc:3383221279 msid:b5da8a66-f103-4828-a9ef-85b08903b9c2 62c5c8ff-ad5e-444e-bf2f-135554e4caa3
a=ssrc:3383221279 mslabel:b5da8a66-f103-4828-a9ef-85b08903b9c2
a=ssrc:3383221279 label:62c5c8ff-ad5e-444e-bf2f-135554e4caa3
a=ssrc:2661971602 cname:Yy4JddEmmT7fHiQO
a=ssrc:2661971602 msid:b5da8a66-f103-4828-a9ef-85b08903b9c2 62c5c8ff-ad5e-444e-bf2f-135554e4caa3
a=ssrc:2661971602 mslabel:b5da8a66-f103-4828-a9ef-85b08903b9c2
a=ssrc:2661971602 label:62c5c8ff-ad5e-444e-bf2f-135554e4caa3

我们修改成这样

a=ssrc:3383221279 cname:Yy4JddEmmT7fHiQO
a=ssrc:3383221279 msid:b5da8a66-f103-4828-a9ef-85b08903b9c2 62c5c8ff-ad5e-444e-bf2f-135554e4caa3
a=ssrc:3383221279 mslabel:b5da8a66-f103-4828-a9ef-85b08903b9c2 62c5c8ff-ad5e-444e-bf2f-135554e4caa3
a=ssrc:3383221279 label:b5da8a66-f103-4828-a9ef-85b08903b9c2 62c5c8ff-ad5e-444e-bf2f-135554e4caa3
a=ssrc:728565452 cname:Yy4JddEmmT7fHiQO
a=ssrc:728565452 msid:b5da8a66-f103-4828-a9ef-85b08903b9c2 62c5c8ff-ad5e-444e-bf2f-135554e4caa3
a=ssrc:728565452 mslabel:b5da8a66-f103-4828-a9ef-85b08903b9c2 62c5c8ff-ad5e-444e-bf2f-135554e4caa3
a=ssrc:728565452 label:b5da8a66-f103-4828-a9ef-85b08903b9c2 62c5c8ff-ad5e-444e-bf2f-135554e4caa3
a=ssrc:700454278 cname:Yy4JddEmmT7fHiQO
a=ssrc:700454278 msid:b5da8a66-f103-4828-a9ef-85b08903b9c2 62c5c8ff-ad5e-444e-bf2f-135554e4caa3
a=ssrc:700454278 mslabel:b5da8a66-f103-4828-a9ef-85b08903b9c2 62c5c8ff-ad5e-444e-bf2f-135554e4caa3
a=ssrc:700454278 label:b5da8a66-f103-4828-a9ef-85b08903b9c2 62c5c8ff-ad5e-444e-bf2f-135554e4caa3
a=ssrc-group:SIM 3383221279 728565452 700454278

注意红色标记的这行,在WebRTC代码中,这表示同时发布三个视频流,后面跟的是三个视频流的SSRC,我们用wireshark抓包看看有没有生效

从图中可以看到payload为102的数据包有三个不同的ssrc,代表联播生效了。

在WebRTC代码simulcast.cc中有这样的代码

const SimulcastFormat kSimulcastFormats[] = {
{1920, 1080, 3, 5000, 4000, 800},
{1280, 720, 3, 2500, 2500, 600},
{960, 540, 3, 900, 900, 450},
{640, 360, 2, 700, 500, 150},
{480, 270, 2, 450, 350, 150},
{320, 180, 1, 200, 150, 30},
{0, 0, 1, 200, 150, 30}
};

我来介绍一下这些代码的意思,第一行表示你摄像头最大分辨率为19201080时,会产生3个视频流,第一路流分辨率为19201080,最大码流为5000kpbs,起始码流为4000kpb,最小码流为800kbps,第二路流为960540,最大码流为900kpbs,起始码流为900kbps,最小码流为600kbps,第三路视频为480270,最大码流为450kbps,起始码流为350kpbs,最小码流为150kbps。其余分辨率以此内推。

当你是使用的是Native客户端时,你可以自己修改这些值,配置不同的码流。如果只是用的网页版本,哪就没有办法了,只能用上述已经配置好的码流了。

作者:rtc8_com
来源:CSDN
原文:https://blog.csdn.net/onlycoder_net/article/details/77189613
版权声明:本文为博主原创文章,转载请附上博文链接!