有没有办法在WebRTC PeerConnection中选择编解码器?

时间:2014-01-28 10:27:13

标签: webrtc codec getusermedia

嘿我想知道在WebRTC中创建商品/答案时是否有任何方法可以选择编解码器。目前没有多少视频编解码器可供选择,但有Opus,PCMU,PCMA等音频编解码器。

2 个答案:

答案 0 :(得分:7)

总的来说,是的。以下是在建立连接时如何选择Opus编解码器的示例。 您应该从createAnswer或createOffer的回调函数中调用'preferOpus'。

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

  for (var i = 0; i < sdpLines.length; i++) {
    if (sdpLines[i].search('m=audio') !== -1) {
      var mLineIndex = i;
      break;
    }
  }

  if (mLineIndex === null) return sdp;

  for (i = 0; i < sdpLines.length; i++) {
    if (sdpLines[i].search('opus/48000') !== -1) {
      var opusPayload = extractSdp(sdpLines[i], /:(\d+) opus\/48000/i);
      if (opusPayload) 
        sdpLines[mLineIndex] = setDefaultCodec(sdpLines[mLineIndex], opusPayload);
      break;
    }
  }

  sdpLines = removeCN(sdpLines, mLineIndex);

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

var extractSdp = function(sdpLine, pattern) {
  var result = sdpLine.match(pattern);
  return (result && result.length == 2)? result[1]: null;
};

var setDefaultCodec = function(mLine, payload) {
  var elements = mLine.split(' ');
  var newLine = new Array();
  var index = 0;
  for (var i = 0; i < elements.length; i++) {
    if (index === 3) newLine[index++] = payload;
    if (elements[i] !== payload) newLine[index++] = elements[i];
  }
  return newLine.join(' ');
};

var removeCN = function(sdpLines, mLineIndex) {
  var mLineElements = sdpLines[mLineIndex].split(' ');
  for (var i = sdpLines.length-1; i >= 0; i--) {
    var payload = extractSdp(sdpLines[i], /a=rtpmap:(\d+) CN\/\d+/i);
    if (payload) {
      var cnPos = mLineElements.indexOf(payload);
      if (cnPos !== -1) mLineElements.splice(cnPos, 1);
      sdpLines.splice(i, 1);
    }
  }
  sdpLines[mLineIndex] = mLineElements.join(' ');
  return sdpLines;
};

答案 1 :(得分:0)

选择Opus只会使您半途而废。使用编解码器的事件,由于它主要是为语音设计的,因此可能默认为单声道且约为42 kb / s。

如果您不使用语音输入,并且想要保持一致的音乐,则可以使用约束来禁用音频处理功能:

navigator.mediaDevices.getUserMedia({
  audio: {
    autoGainControl: false,
    channelCount: 2,
    echoCancellation: false,
    latency: 0,
    noiseSuppression: false,
    sampleRate: 48000,
    sampleSize: 16,
    volume: 1.0
  }
});

然后将SDP设置为stereo,并增加maxaveragebitrate

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。实际比特率取决于您的网络速度和信号强度。

您可以在以下网址了解更多有关其他可用属性的信息:https://tools.ietf.org/html/rfc7587