最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - How to set up SDP for High quality Opus audio - Stack Overflow

programmeradmin2浏览0评论

I have been trying to transmit some high quality audio stream through WebRTC. Opus, the main advertised codec seems perfect since it can support up to 510kbit/s, way more than needed. The problem is, setting up the Webrtc SDP is way less obvious than it seems. Thanks to Muaz Khan great work, I have been able to force it to 128kbit/s. Basically the code looks like that:

 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;
}

So now everything is set, both firefox and chrome display the right value for sender and receiver, the munication opens, the music is played!

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:ssrc-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=ssrc:1948755120 cname:{208483df-13c9-e347-ba4a-c71604df3ad9}

But the quality is terrible. Chrome shows about 30kbit/s on chrome://webrtc-internals/ and the sound is heavily distorted with variable volume... Any leads on the issue?

I have been trying to transmit some high quality audio stream through WebRTC. Opus, the main advertised codec seems perfect since it can support up to 510kbit/s, way more than needed. The problem is, setting up the Webrtc SDP is way less obvious than it seems. Thanks to Muaz Khan great work, I have been able to force it to 128kbit/s. Basically the code looks like that:

 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;
}

So now everything is set, both firefox and chrome display the right value for sender and receiver, the munication opens, the music is played!

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:ssrc-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=ssrc:1948755120 cname:{208483df-13c9-e347-ba4a-c71604df3ad9}

But the quality is terrible. Chrome shows about 30kbit/s on chrome://webrtc-internals/ and the sound is heavily distorted with variable volume... Any leads on the issue?

Share Improve this question asked Nov 11, 2015 at 11:08 Ben BanksBen Banks 1292 silver badges11 bronze badges
Add a ment  | 

3 Answers 3

Reset to default 5

You need to set stereo and maxaveragebitrate attibutes on the SDP:

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);

This will output a string which looks something like this:

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

This gave me a bitrate of 520kb/s for stereo, which is 260kps per channel. Actual bitrate you get will vary based on the speed of your network and strength of your signal.

There are more SDP attributes documented at: https://www.rfc-editor/rfc/rfc7587

I created a SDP parser. You feed the SDP description, get a JSON object and then serialize it again.

This way it's much easier to process the SDP as an object than as bulk text.

Main reason for bad quality is the browser's audio processing. You need to pass audio constraints to the GetUserMedia object:

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

发布评论

评论列表(0)

  1. 暂无评论