You need to enable JavaScript to run this app. Android 11升级后MediaCodec/MediaMuxer录制MP4无声音,报缺少编解码专有数据
优惠活动
大模型
产品
解决方案
定价
更多

Android 11升级后MediaCodec/MediaMuxer录制MP4无声音,报缺少编解码专有数据

问题背景
  • 项目基于MediaCodec+MediaMuxer实现MP4录制:以设备麦克风作为音频输入源,OpenGL渲染的音频可视化场景(如声谱图)作为视频源
  • 兼容性异常:Android 11系统升级前全机型运行正常,升级后谷歌Pixel 3/4、三星Galaxy S20等多品牌机型统一出现录制文件无音频的问题
  • 已排除的异常项:
    • 录制全程无运行时崩溃、无抛出未捕获异常
    • 跨多设备播放录制文件均确认无音频内容,排除播放端兼容问题
    • 视频内的音频可视化动效与实际采集的音频节奏匹配,排除麦克风采集、音频输入链路异常
    • 日志确认视频轨编码、封装全程正常,仅音频轨封装环节报错
现有录制逻辑配置
// 视频编码配置
public static final String VIDEO_MIME_TYPE = MediaFormat.MIMETYPE_VIDEO_AVC;
public static final int VIDEO_FRAME_RATE = 30; 
public static final int VIDEO_IFRAME_INTERVAL = 5;
public static final String AUDIO_MIME_TYPE = MediaFormat.MIMETYPE_AUDIO_AAC;

// 麦克风采集配置
public static final int RECORDER_SAMPLE_RATE = 44100;
public static final int RECORDER_CHANNELS = 1;
public static final int RECORDER_AUDIO_ENCODING = AudioFormat.ENCODING_PCM_16BIT;

// 音频编码配置
public static final String ENCODER_AUDIO_FORMAT = MediaFormat.MIMETYPE_AUDIO_AAC;
public static final int ENCODER_AAC_PROFILE = MediaCodecInfo.CodecProfileLevel.AACObjectLC;
public static final int AUDIO_BIT_RATE = 128000; 
public static final int AUDIO_SAMPLE_RATE = 44100;
public static final int AUDIO_SAMPLES_PER_FRAME = 1024;
public static final int AUDIO_FRAMES_PER_BUFFER = 25;
public static final int AUDIO_BYTES_PER_ELEMENT = 2;

// 视频编码器初始化
MediaFormat videoFormat = MediaFormat.createVideoFormat(VIDEO_MIME_TYPE, width, height);
videoFormat.setInteger(MediaFormat.KEY_COLOR_FORMAT, MediaCodecInfo.CodecCapabilities.COLOR_FormatSurface);
videoFormat.setInteger(MediaFormat.KEY_BIT_RATE, bitRate);
videoFormat.setInteger(MediaFormat.KEY_FRAME_RATE, VIDEO_FRAME_RATE);
videoFormat.setInteger(MediaFormat.KEY_I_FRAME_INTERVAL, VIDEO_IFRAME_INTERVAL);
videoEncoder = MediaCodec.createEncoderByType(VIDEO_MIME_TYPE);
videoEncoder.configure(videoFormat, null, null, MediaCodec.CONFIGURE_FLAG_ENCODE);
inputSurface = videoEncoder.createInputSurface();
videoEncoder.start();

// 音频编码器初始化
audioEncoder = MediaCodec.createEncoderByType(AUDIO_MIME_TYPE);
MediaFormat audioFormatConfig = MediaFormat.createAudioFormat(ENCODER_AUDIO_FORMAT, AUDIO_SAMPLE_RATE, RECORDER_CHANNELS);
audioFormatConfig.setInteger(MediaFormat.KEY_AAC_PROFILE, ENCODER_AAC_PROFILE);
audioFormatConfig.setInteger(MediaFormat.KEY_BIT_RATE, AUDIO_BIT_RATE);
audioFormatConfig.setInteger(MediaFormat.KEY_CHANNEL_COUNT, RECORDER_CHANNELS);
audioEncoder.configure(audioFormatConfig, null, null, MediaCodec.CONFIGURE_FLAG_ENCODE);
audioEncoder.start();

// Muxer初始化
mMuxer = new MediaMuxer(outputFile, MediaMuxer.OutputFormat.MUXER_OUTPUT_MPEG_4);
mMuxer.setOrientationHint(orientationHint);

// 原有Muxer启动触发逻辑
else if (encoderStatus == MediaCodec.INFO_OUTPUT_FORMAT_CHANGED) {
    MediaFormat videoOutputFormat = videoEncoder.getOutputFormat();
    MediaFormat audioOutputFormat = audioEncoder.getOutputFormat();
    videoTrackIndex = mMuxer.addTrack(videoOutputFormat);
    audioTrackIndex = mMuxer.addTrack(audioOutputFormat);
    mMuxer.start();
}
关键异常日志

停止录制环节捕获的核心错误日志:

2021-03-08 14:52:12.670 20015-20259/com.xx.xx E/MPEG4Writer: Missing codec specific data
2021-03-08 14:52:12.670 20015-20259/com.xx.xx E/MPEG4Writer: 0 frames to dump timeStamps in Audio track 
2021-03-08 14:52:12.671 20015-20241/com.xx.xx D/MPEG4Writer: Audio track stopped. Status:-1007. Stop source 
2021-03-08 14:52:12.671 20015-20241/com.xx.xx W/MPEG4Writer: Condition trackErr == OK failed Audio track stopped with an error

日志同时记录视频轨累计编码69帧、封装正常,音频轨累计编码87帧但封装时因缺少专属编解码数据(CSD)直接终止。

问题根因与排查修复方向
  • 核心时序冲突:Android 11系统调整了MediaCodec编码器的格式回调时序,视频编码器触发INFO_OUTPUT_FORMAT_CHANGED回调时,音频编码器往往尚未完成初始化流程、尚未触发自身的格式变更回调。原有逻辑在视频轨格式就绪时,直接同步拉取音频编码器的输出格式,此时拿到的格式缺少必需的CSD编解码专属数据,直接传入MediaMuxer.addTrack会导致音频轨封装失败。
  • 修复逻辑参考:
    • 为视频、音频编码器分别维护格式就绪标记(isVideoFormatReady、isAudioFormatReady)
    • 只有当两个编码器都收到过INFO_OUTPUT_FORMAT_CHANGED回调、成功拿到带完整CSD数据的输出格式后,再依次调用addTrack添加两条轨、启动Muxer
  • 验证排查点:
    • 分别打印两个编码器触发格式变更回调的时间戳,确认存在跨轨时序差
    • 打印传入Muxer的音频MediaFormat,检查是否包含csd-0、csd-1字段,未就绪的格式会缺失这些关键参数
    • 调整时序逻辑后重新录制,确认日志中不再出现Missing codec specific data报错,音频轨停止状态码恢复为0

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.31 09:15:04