如何为高质量的 Opus 音频设置 SDP

Posted

技术标签:

【中文标题】如何为高质量的 Opus 音频设置 SDP【英文标题】:How to set up SDP for High quality Opus audio 【发布时间】:2016-02-12 11:15:51 【问题描述】:

我一直在尝试通过 WebRTC 传输一些高质量的音频流。 Opus,主要宣传的编解码器似乎很完美,因为它可以支持高达 510kbit/s,远远超过需要。 问题是,设置 Webrtc SDP 并不像看起来那么明显。感谢 Muaz Khan 的出色工作,我能够将其强制为 128kbit/s。 基本上代码是这样的:

 function setBandwidth(sdp) 
 var sdpLines = sdp.split('\r\n');


// Find opus payload.
var opusIndex = findLine(sdpLines, 'a=rtpmap', 'opus/48000');
var opusPayload;
if (opusIndex) 
    opusPayload = '109';

sdpLines[opusIndex]='a=rtpmap:'+opusPayload+' opus/48000/2';


   var mediaIndex = findLine(sdpLines, 'm=audio');
sdpLines[mediaIndex]=(sdpLines[mediaIndex].slice(0,(sdpLines[mediaIndex].indexOf("RTP/SAVPF")+10))).concat(opusPayload); 
 var abIndex = findLine(sdpLines, 'a=mid:');
  sdpLines[abIndex]='a=mid:audio\r\nb=AS:300000';

// Find the payload in fmtp line.
  var fmtpLineIndex = findLine(sdpLines, 'a=fmtp:' + opusPayload.toString());

if (fmtpLineIndex == null) 
    sdpLines[opusIndex] = sdpLines[opusIndex].concat('\r\n'+'a=fmtp:' + opusPayload.toString()+ ' minptime=10; useinbandfec=1; maxaveragebitrate='+128*1024+'; stereo=1; sprop-stereo=1 ; cbr=1');
     sdp = sdpLines.join('\r\n');

    return sdp;


// Append stereo=1 to fmtp line.
// added maxaveragebitrate here; about 50 kbits/s
// added stereo=1 here for stereo audio
// x-google-min-bitrate=50; x-google-max-bitrate=50
sdpLines[fmtpLineIndex] = sdpLines[fmtpLineIndex].concat('; maxaveragebitrate='+128*1024+'; stereo=1; sprop-stereo=1 ; cbr=1');


sdp = sdpLines.join('\r\n');
return sdp;

现在一切都设置好了,firefox 和 chrome 都为发送者和接收者显示正确的值,通信打开,音乐播放!

adding answer-sdp v=0
o=mozilla...THIS_IS_SDPARTA-42.0 502631676322875352 0 IN IP4 0.0.0.0
s=-
t=0 0
a=fingerprint:sha-256.....
a=ice-options:trickle
a=msid-semantic:WMS *
m=audio 9 RTP/SAVPF 109 
c=IN IP4 0.0.0.0
a=recvonly
a=extmap:1 urn:ietf:params:rtp-hdrext:s-s-rc-audio-level
a=ice-pwd:c56d106030599efe08cfa2a4f9b3ad5a
a=ice-ufrag:93982a76
a=mid:audio
b=AS:300000
a=rtcp-mux
a=rtpmap:109 opus/48000/2
a=fmtp:109 minptime=10; useinbandfec=1; maxaveragebitrate=131072; stereo=1; sprop-stereo=1 ; cbr=1
a=setup:active
a=s-s-rc:1948755120 cname:208483df-13c9-e347-ba4a-c71604df3ad9

但是质量很差。 Chrome 在 chrome://webrtc-internals/ 上显示大约 30kbit/s,声音严重失真,音量可变... 关于这个问题的任何线索?

【问题讨论】:

【参考方案1】:

您需要在SDP上设置stereomaxaveragebitrate属性:

let answer = await peer.conn.createAnswer(offerOptions);
answer.sdp = answer.sdp.replace('useinbandfec=1', 'useinbandfec=1; stereo=1; maxaveragebitrate=510000');
await peer.conn.setLocalDescription(answer);

这将输出一个看起来像这样的字符串:

a=fmtp:111 minptime=10;useinbandfec=1; stereo=1; maxaveragebitrate=510000

这给了我 520kb/s 的立体声比特率,即每通道 260kps。您获得的实际比特率会因网络速度和信号强度而异。

更多 SDP 属性记录在:https://www.rfc-editor.org/rfc/rfc7587

【讨论】:

【参考方案2】:

质量差的主要原因是浏览器的音频处理。 您需要将音频约束传递给 GetUserMedia 对象:

'channelCount':'exact': 2, 'echoCancellation':false, 'autoGainControl':false, 'noiseSuppression':false

【讨论】:

【参考方案3】:

我创建了一个SDP parser。您输入 SDP 描述,获取一个 JSON 对象,然后再次对其进行序列化。

这样,将 SDP 作为对象处理比作为批量文本处理要容易得多。

【讨论】:

嘿!看起来不错!我会尝试一下。似乎 main/source/js/ 中缺少一个文件,因为我找不到 sdpparser.js 文件。我真的很想了解我做错了什么! 该文件没有丢失,它是从 pegjs 语法自动生成的。你试过 npm 吗? 我不明白!我的错。我使用 pegjs 生成 .js,我会给你反馈! 很高兴它成功了!我会将其包含在文档中。非常感谢您的反馈。 我发布了 v0.0.2,其中也包含了生成的文件和依赖项。我还修改了文档。

以上是关于如何为高质量的 Opus 音频设置 SDP的主要内容,如果未能解决你的问题,请参考以下文章

实时音频编解码之十一Opus编码

如何在 WebRTC 音频通话中控制单声道/立体声?

如何为 HTML5 视频设置音频延迟(不同步)

如何为音频处理设置高优先级线程

实时音频编解码之十四 Opus编码-SILK编码-长时预测

实时音频编解码之十四 Opus编码-SILK编码-长时预测