使用MediaPlayer的App录屏无法录制内部音频的原因及修复方案
核心成因
- 系统版本底层限制:Android 10(API 29)之前没有公开的非root内部音频采集接口,所有录屏应用无法直接拿到App输出的音频流,只能通过麦克风采集扬声器播放的声音,一旦用户插耳机、开静音就完全录不到。
- App自身音频配置拦截:
- 应用
AndroidManifest.xml中allowAudioPlaybackCapture属性被设为false,系统会直接禁止所有录屏工具采集该App的音频 - MediaPlayer初始化时配置了错误的
AudioAttributes:比如把音频Usage设为通知、按键音、通话类通道,或是主动加了FLAG_AUDIO_NO_MEDIA_PROJECTION_CAPTURE标记,系统会将这类音频判定为不可采集 - 播放的是DRM版权保护的音视频内容,系统级版权保护机制会强制拦截音频采集
- 应用
- 录屏工具/ROM适配问题:
- 录屏工具没有拿到系统「媒体投影」权限,或是音频源设置为「麦克风」「无」,没有切换到内部音频采集通道
- 国内部分定制ROM默认禁用了第三方App的内部音频采集权限,或是魔改音频路由规则,把App音频输出到了录屏工具无法访问的专属通道
- 音频被路由到外接蓝牙、USB音频设备的独占模式时,部分ROM的录屏服务无法捕获该通路的音频
修复方案
- 版本适配兜底
对于targetSdkVersion低于29、运行在Android 9及以下系统的场景,原生系统不支持无root内部音频采集,检测到系统版本低于29时可提示用户:要么升级系统到Android 10及以上,要么使用带root权限的录屏工具,或是外放声音通过麦克风采集(会有环境音损耗)。 - 修正App自身音频配置
- 检查
AndroidManifest.xml的application标签,确保允许音频采集:
<application <!-- 其他配置 --> android:allowAudioPlaybackCapture="true"> <!-- 组件声明 --> </application>- 给MediaPlayer配置正确的音频属性,不要加禁止采集的标记:
MediaPlayer mediaPlayer = new MediaPlayer(); if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { AudioAttributes attributes = new AudioAttributes.Builder() .setUsage(AudioAttributes.USAGE_MEDIA) // 必须使用媒体类Usage,不要改成语音、通知、告警类 .setContentType(AudioAttributes.CONTENT_TYPE_MUSIC) // 禁止添加以下代码,否则会主动屏蔽录屏采集: // .setFlags(AudioAttributes.FLAG_AUDIO_NO_MEDIA_PROJECTION_CAPTURE) .build(); mediaPlayer.setAudioAttributes(attributes); } else { // 低版本兼容,设置为媒体流类型 mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC); } // 后续正常设置数据源、prepare、start即可- 如果播放的是无版权的自有内容,不要给MediaPlayer加DRM安全解码配置,否则系统会自动拦截采集。
- 检查
- 外部场景排查引导
- 验证时优先用系统自带的录屏功能测试:如果系统录屏能采集到音频、第三方录屏不行,说明是第三方录屏工具自身适配问题,和你的App无关;
- 针对定制ROM用户,提示用户给录屏工具开启「系统音频录制」的特殊权限,录屏时把音频输出切回手机内置扬声器,暂时关闭蓝牙/USB外接音频设备、第三方音效增强类应用。
内容的提问来源于stack exchange,提问作者Up Gelo
相关产品推荐
相关产品推荐

