Flutter中用just_audio播放WebSocket流式Uint8List音频失败求助
问题分析与解决方案
核心问题
你当前的代码存在两个关键问题:
- 每次收到WebSocket音频chunk就调用
setAudioSource重置播放器,这会打断之前的播放流程,且不符合流式音频的处理逻辑 - 错误
(-11828) Cannot Open是iOS平台无法加载音频源的提示,MissingPluginException则大概率是插件未正确初始化或版本兼容问题
修复just_audio播放问题的步骤
1. 改用流式音频源处理连续chunk
just_audio提供了StreamAudioSource专门处理流式音频,无需每次重置音频源。通过StreamController收集WebSocket传来的音频chunk,再喂给播放器:
late final AudioPlayer _audioPlayer; late StreamController<List<int>> _audioStreamController; @override void initState() { super.initState(); _audioPlayer = AudioPlayer(); _audioStreamController = StreamController<List<int>>.broadcast(); _initStreamAudioSource(); } void _initStreamAudioSource() async { await _audioPlayer.setAudioSource( StreamAudioSource( stream: _audioStreamController.stream, contentType: 'audio/mpeg', // 匹配ElevenLabs的MP3格式 ), ); } void connectWebSocket() { _channel = IOWebSocketChannel.connect( 'wss://api.elevenlabs.io/v1/text-to-speech/$voiceId/stream-input?model_id=$model' ); _channel!.stream.listen((data) { final response = jsonDecode(data); if (response['audio'] != null) { try { final audioChunk = response['audio'] as String; final uint8List = Uint8List.fromList(base64.decode(audioChunk)); // 将chunk添加到流控制器,播放器会自动处理连续播放 _audioStreamController.add(uint8List); // 仅在播放器闲置时启动播放,避免重复调用 if (_audioPlayer.processingState == ProcessingState.idle) { _audioPlayer.play(); } } catch (e) { print("Error processing audio chunk: $e"); } } }, onError: (error) { print("WebSocket error: $error"); }, onDone: () { _audioStreamController.close(); }); } @override void dispose() { _audioPlayer.dispose(); _audioStreamController.close(); _channel?.sink.close(); super.dispose(); }
2. 解决MissingPluginException
- 执行
flutter clean后再flutter pub get,确保插件资源正确加载 - 重启应用和模拟器/真机(热重载不会刷新插件原生实现)
- 更新just_audio到最新稳定版,修改
pubspec.yaml:just_audio: ^0.9.36 # 替换为当前最新版本 - iOS平台需进入
ios目录执行pod install,确保原生依赖安装完成
3. 确认音频格式兼容性
ElevenLabs流式返回的是MP3格式,确保contentType设置为audio/mpeg,若后续格式变更需同步调整。
替代包推荐
如果just_audio仍无法解决问题,可以尝试以下更适合流式场景的库:
audioplayers:轻量易用,支持直接播放Uint8List,低延迟模式适合实时场景:
final player = AudioPlayer(); // 收到chunk时直接播放,低延迟模式减少卡顿 await player.play(BytesSource(uint8List), mode: PlayerMode.lowLatency);flutter_sound:专注音频流处理,支持实时音频播放与录制:
final flutterSoundPlayer = FlutterSoundPlayer(); await flutterSoundPlayer.openAudioSession(); // 启动流式播放 await flutterSoundPlayer.startPlayerFromStream(codec: Codec.mp3); // 推送音频chunk到播放器 flutterSoundPlayer.foodSink.add(FoodData(uint8List));
内容的提问来源于stack exchange,提问作者Sahil Singh
相关产品推荐
相关产品推荐

