Flutter实现音频听筒播放(当前仅扬声器输出)方案问询
Flutter听筒播放音频实现方案
能力支持结论
Flutter原生生态完全支持音频从设备听筒输出的能力,当前代码无法生效是音频会话配置参数不符合听筒播放场景要求,不需要替换已接入的just_audio播放内核,补充对应依赖、修正配置即可实现需求。
适配场景可用插件
已接入的just_audio: ^0.9.24、audio_session: ^0.1.7可直接保留,额外接入音频路由控制插件flutter_audio_router: ^0.0.4即可,该版本完全兼容当前使用的Flutter 3.0.1 stable环境。
现有代码失效原因
当前编写的音频会话配置为通用媒体播放模式,系统默认将音频路由到扬声器输出:
- iOS端使用
AVAudioSessionMode.defaultMode+AVAudioSessionCategory.playback组合,系统默认路由优先级为:外接设备>扬声器>听筒,不会主动走听筒 - Android端配置
AndroidAudioUsage.media为媒体播放场景,系统默认将音频输出到外放扬声器,无特殊配置不会路由到听筒。
具体实现步骤
1. 添加依赖
在pubspec.yaml中补充路由插件依赖:
dependencies: flutter: sdk: flutter just_audio: ^0.9.24 audio_session: ^0.1.7 flutter_audio_router: ^0.0.4
执行flutter pub get完成依赖安装。
2. 补充Android端权限
在项目android/app/src/main/AndroidManifest.xml中添加音频设置修改权限:
<uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS" />
3. 修正音频会话配置
将原有AudioSessionConfiguration配置替换为听筒场景适配参数:
await audioSession.configure(AudioSessionConfiguration( // iOS端配置:语音通话模式,默认优先路由到听筒 avAudioSessionCategory: AVAudioSessionCategory.playAndRecord, avAudioSessionCategoryOptions: AVAudioSessionCategoryOptions.allowBluetooth, avAudioSessionMode: AVAudioSessionMode.voiceChat, avAudioSessionRouteSharingPolicy: AVAudioSessionRouteSharingPolicy.independent, avAudioSessionSetActiveOptions: AVAudioSessionSetActiveOptions.none, // Android端配置:语音通话属性,系统自动匹配听筒输出路由 androidAudioAttributes: const AndroidAudioAttributes( contentType: AndroidAudioContentType.speech, flags: AndroidAudioFlags.none, usage: AndroidAudioUsage.voiceCommunication, ), androidAudioFocusGainType: AndroidAudioFocusGainType.gain, androidWillPauseWhenDucked: true, ));
4. 主动指定音频输出路由
在音频资源加载完成、调用播放方法前,执行路由切换代码强制指定听筒输出:
// 引入路由插件 import 'package:flutter_audio_router/flutter_audio_router.dart'; // 音频加载完成后调用 await FlutterAudioRouter.setAudioRoute(AudioRoute.earpiece);
如果后续需要切换回扬声器播放,调用await FlutterAudioRouter.setAudioRoute(AudioRoute.speaker);即可。
测试注意事项
- 测试时断开所有蓝牙音频设备、有线耳机,否则系统会优先将音频路由到外接输出设备,不会走机身自带听筒/扬声器
- Android部分定制ROM可能存在音频路由逻辑修改,如果配置后仍不生效,可以在切换路由后延迟100ms再调用播放方法
- iOS端无需额外配置权限,会话参数设置正确即可正常路由。
内容的提问来源于stack exchange,提问作者Jinto Joseph
相关产品推荐
相关产品推荐

