You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Flutter WebRTC中如何配置PCMU编码音频的位宽等参数?

解决Flutter WebRTC适配PCMU摄像头音频参数问题

针对你遇到的PCMU编码摄像头需额外配置位宽、每帧采样数等参数的问题,可从以下几个方向实现:

1. 强制音频采集约束匹配PCMU标准参数

PCMU(G.711μ)的标准参数为:8kHz采样率、8bit位宽、单声道、每帧20ms(对应160采样数)。调用getUserMedia时直接指定这些约束,让WebRTC采集符合要求的音频:

final Map<String, dynamic> mediaConstraints = {
  'audio': {
    'sampleRate': 8000,
    'sampleSize': 8,
    'channelCount': 1,
    'echoCancellation': false,
    'noiseSuppression': false,
    'autoGainControl': false,
  },
  'video': {
    // 你的视频采集约束
    'width': 1280,
    'height': 720,
    'frameRate': 30,
  }
};

// 获取媒体流
MediaStream stream = await navigator.mediaDevices.getUserMedia(mediaConstraints);

2. 修改SDP显式声明音频参数

部分摄像头需要SDP中明确标注帧时长(对应每帧采样数)和编码参数,可在生成Offer/Answer后修改SDP:

String modifyAudioSdp(String originalSdp) {
  List<String> lines = originalSdp.split('\r\n');
  int audioMediaLineIdx = lines.indexWhere((line) => line.startsWith('m=audio'));
  
  if (audioMediaLineIdx != -1) {
    // 确保PCMU的rtpmap正确(payload type通常为0)
    bool hasPcmuRtpmap = lines.any((line) => line == 'a=rtpmap:0 PCMU/8000');
    if (!hasPcmuRtpmap) {
      lines.insert(audioMediaLineIdx + 1, 'a=rtpmap:0 PCMU/8000');
    }
    
    // 添加ptime指定帧时长20ms,对应每帧160采样数
    bool hasPtime = lines.any((line) => line.startsWith('a=ptime:'));
    if (!hasPtime) {
      lines.insert(audioMediaLineIdx + 2, 'a=ptime:20');
    }
  }
  
  return lines.join('\r\n');
}

// 使用示例:生成Offer后修改SDP
RTCSessionDescription offer = await peerConnection.createOffer();
RTCSessionDescription modifiedOffer = RTCSessionDescription(
  modifyAudioSdp(offer.sdp!),
  offer.type,
);
await peerConnection.setLocalDescription(modifiedOffer);

3. 锁定PCMU为唯一首选编码

通过setCodecPreferences确保WebRTC只使用PCMU编码,避免其他编码干扰参数匹配:

// 获取音频发送器
RTCRtpSender? audioSender = peerConnection.getSenders().firstWhere(
  (sender) => sender.track?.kind == 'audio',
  orElse: () => throw StateError('No audio sender found'),
);

// 获取支持的编码列表,筛选PCMU
RTCRtpParameters params = await audioSender.getParameters();
List<RTCRtpCodec> pcmuCodecs = params.codecs.where(
  (codec) => codec.mimeType.toLowerCase() == 'audio/pcmu',
).toList();

// 设置首选编码为PCMU
if (pcmuCodecs.isNotEmpty) {
  await audioSender.setCodecPreferences(pcmuCodecs);
}

4. fallback:自定义音频转码(若硬件不支持约束)

如果移动端硬件强制不支持8kHz采样率,可通过原生插件或音频处理库将采集到的高采样率音频转码为PCMU格式,再替换WebRTC默认的音频轨道发送。核心是将音频数据转成8kHz、8bit、单声道的PCMU流。

内容的提问来源于stack exchange,提问作者viki

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.27 13:45:16