Android端just_audio播放30个音频后出现Audio Sink/Playback Error求助
Android端just_audio播放多音频后触发AudioTrack初始化失败(错误码-20)
我开发的播客应用在Android端使用just_audio播放30个音频后,会触发Audio Sink Error与Audio Playback Error。即使重复播放同一批30个音频,播放30-35次后播放器失效:音频文件看似在播放但无声音,播放器通知控件停留在上一个音频界面。
该问题仅出现在Android端,iOS端播放完全正常。尝试播放本地下载和服务器端的MP3音频均出现此问题,甚至杀死应用后audio_service仍会后台运行但无声音。相关错误日志显示初始化AudioTrack时返回-20错误,无法创建AudioTrack。
错误日志
E/android.media.AudioTrack( 8248): Error code -20 when initializing AudioTrack. E/MediaCodecAudioRenderer( 8248): Audio sink error E/MediaCodecAudioRenderer( 8248): com.google.android.exoplayer2.audio.AudioSink$InitializationException: AudioTrack init failed 0 Config(44100, 4, 28288) Format(null, null, null, audio/raw, null, -1, null, [-1, -1, -1.0], [1, 44100]) E/MediaCodecAudioRenderer( 8248): at com.google.android.exoplayer2.audio.DefaultAudioSink$Configuration.buildAudioTrack(DefaultAudioSink.java:2136) E/MediaCodecAudioRenderer( 8248): at com.google.android.exoplayer2.audio.DefaultAudioSink.buildAudioTrack(DefaultAudioSink.java:1073) E/MediaCodecAudioRenderer( 8248): at com.google.android.exoplayer2.audio.DefaultAudioSink.buildAudioTrackWithRetry(DefaultAudioSink.java:1051) E/MediaCodecAudioRenderer( 8248): at com.google.android.exoplayer2.audio.DefaultAudioSink.initializeAudioTrack(DefaultAudioSink.java:843) E/MediaCodecAudioRenderer( 8248): at com.google.android.exoplayer2.audio.DefaultAudioSink.handleBuffer(DefaultAudioSink.java:929) E/MediaCodecAudioRenderer( 8248): at com.google.android.exoplayer2.audio.MediaCodecAudioRenderer.processOutputBuffer(MediaCodecAudioRenderer.java:709) E/MediaCodecAudioRenderer( 8248): at com.google.android.exoplayer2.mediacodec.MediaCodecRenderer.drainOutputBuffer(MediaCodecRenderer.java:1889) E/MediaCodecAudioRenderer( 8248): at com.google.android.exoplayer2.mediacodec.MediaCodecRenderer.render(MediaCodecRenderer.java:782) E/MediaCodecAudioRenderer( 8248): at com.google.android.exoplayer2.ExoPlayerImplInternal.doSomeWork(ExoPlayerImplInternal.java:1007) E/MediaCodecAudioRenderer( 8248): at com.google.android.exoplayer2.ExoPlayerImplInternal.handleMessage(ExoPlayerImplInternal.java:502) E/MediaCodecAudioRenderer( 8248): at android.os.Handler.dispatchMessage(Handler.java:102) E/MediaCodecAudioRenderer( 8248): at android.os.Looper.loopOnce(Looper.java:240) E/MediaCodecAudioRenderer( 8248): at android.os.Looper.loop(Looper.java:351) E/MediaCodecAudioRenderer( 8248): at android.os.HandlerThread.run(HandlerThread.java:67) E/MediaCodecAudioRenderer( 8248): Caused by: java.lang.UnsupportedOperationException: Cannot create AudioTrack E/MediaCodecAudioRenderer( 8248): at android.media.AudioTrack$Builder.build(AudioTrack.java:1390) E/MediaCodecAudioRenderer( 8248): at com.google.android.exoplayer2.audio.DefaultAudioSink$Configuration.createAudioTrackV29(DefaultAudioSink.java:2185) E/MediaCodecAudioRenderer( 8248): at com.google.android.exoplayer2.audio.DefaultAudioSink$Configuration.createAudioTrack(DefaultAudioSink.java:2163) E/MediaCodecAudioRenderer( 8248): at com.google.android.exoplayer2.audio.DefaultAudioSink$Configuration.buildAudioTrack(DefaultAudioSink.java:2128) E/MediaCodecAudioRenderer( 8248): ... 13 more E/ExoPlayerImplInternal( 8248): Playback error E/ExoPlayerImplInternal( 8248): com.google.android.exoplayer2.ExoPlaybackException: MediaCodecAudioRenderer error, index=1, format=Format(null, null, null, audio/mpeg, null, -1, null, [-1, -1, -1.0], [1, 44100]), format_supported=YES E/ExoPlayerImplInternal( 8248): at com.google.android.exoplayer2.ExoPlayerImplInternal.handleMessage(ExoPlayerImplInternal.java:578) E/ExoPlayerImplInternal( 8248): at android.os.Handler.dispatchMessage(Handler.java:102) E/ExoPlayerImplInternal( 8248): at android.os.Looper.loopOnce(Looper.java:240) E/ExoPlayerImplInternal( 8248): at android.os.Looper.loop(Looper.java:351) E/ExoPlayerImplInternal( 8248): at android.os.HandlerThread.run(HandlerThread.java:67) E/ExoPlayerImplInternal( 8248): Caused by: com.google.android.exoplayer2.audio.AudioSink$InitializationException: AudioTrack init failed 0 Config(44100, 4, 28288) Format(null, null, null, audio/raw, null, -1, null, [-1, -1, -1.0], [1, 44100]) E/ExoPlayerImplInternal( 8248): at com.google.android.exoplayer2.audio.DefaultAudioSink$Configuration.buildAudioTrack(DefaultAudioSink.java:2136) E/ExoPlayerImplInternal( 8248): at com.google.android.exoplayer2.audio.DefaultAudioSink.buildAudioTrack(DefaultAudioSink.java:1073) E/ExoPlayerImplInternal( 8248): at com.google.android.exoplayer2.audio.DefaultAudioSink.buildAudioTrackWithRetry(DefaultAudioSink.java:1051) E/ExoPlayerImplInternal( 8248): at com.google.android.exoplayer2.audio.DefaultAudioSink.initializeAudioTrack(DefaultAudioSink.java:843) E/ExoPlayerImplInternal( 8248): at com.google.android.exoplayer2.audio.DefaultAudioSink.handleBuffer(DefaultAudioSink.java:929) E/ExoPlayerImplInternal( 8248): at com.google.android.exoplayer2.audio.MediaCodecAudioRenderer.processOutputBuffer(MediaCodecAudioRenderer.java:709) E/ExoPlayerImplInternal( 8248): at com.google.android.exoplayer2.mediacodec.MediaCodecRenderer.drainOutputBuffer(MediaCodecRenderer.java:1889) E/ExoPlayerImplInternal( 8248): at com.google.android.exoplayer2.mediacodec.MediaCodecRenderer.render(MediaCodecRenderer.java:782) E/ExoPlayerImplInternal( 8248): at com.google.android.exoplayer2.ExoPlayerImplInternal.doSomeWork(ExoPlayerImplInternal.java:1007) E/ExoPlayerImplInternal( 8248): at com.google.android.exoplayer2.ExoPlayerImplInternal.handleMessage(ExoPlayerImplInternal.java:502) E/ExoPlayerImplInternal( 8248): ... 4 more E/ExoPlayerImplInternal( 8248): Suppressed: com.google.android.exoplayer2.audio.AudioSink$InitializationException: AudioTrack init failed 0 Config(44100, 4, 28288) Format(null, null, null, audio/raw, null, -1, null, [-1, -1, -1.0], [1, 44100]) E/ExoPlayerImplInternal( 8248): ... 14 more E/ExoPlayerImplInternal( 8248): Caused by: java.lang.UnsupportedOperationException: Cannot create AudioTrack E/ExoPlayerImplInternal( 8248): at android.media.AudioTrack$Builder.build(AudioTrack.java:1390) E/ExoPlayerImplInternal( 8248): at com.google.android.exoplayer2.audio.DefaultAudioSink$Configuration.createAudioTrackV29(DefaultAudioSink.java:2185) E/ExoPlayerImplInternal( 8248): at com.google.android.exoplayer2.audio.DefaultAudioSink$Configuration.createAudioTrack(DefaultAudioSink.java:2163) E/ExoPlayerImplInternal( 8248): at com.google.android.exoplayer2.audio.DefaultAudioSink$Configuration.buildAudioTrack(DefaultAudioSink.java:2128) E/ExoPlayerImplInternal( 8248): ... 13 more E/ExoPlayerImplInternal( 8248): Caused by: java.lang.UnsupportedOperationException: Cannot create AudioTrack E/ExoPlayerImplInternal( 8248): at android.media.AudioTrack$Builder.build(AudioTrack.java:1390) E/ExoPlayerImplInternal( 8248): at com.google.android.exoplayer2.audio.DefaultAudioSink$Configuration.createAudioTrackV29(DefaultAudioSink.java:2185) E/ExoPlayerImplInternal( 8248): at com.google.android.exoplayer2.audio.DefaultAudioSink$Configuration.createAudioTrack(DefaultAudioSink.java:2163) E/ExoPlayerImplInternal( 8248): at com.google.android.exoplayer2.audio.DefaultAudioSink$Configuration.buildAudioTrack(DefaultAudioSink.java:2128) E/ExoPlayerImplInternal( 8248): ... 13 more D/MediaCodec( 8248): [0xb4000075ee75b000] setState: 7
相关代码
audioHandler.dart
class AudioPlayerHandlerMain extends BaseAudioHandler with SeekHandler, ChangeNotifier { AudioPlayer _player = AudioPlayer(); static var current_audio_file_id = ''; static var current_audio_file_type = 'suhbas'; Future<void> dispose() async { _player.dispose(); print("Disposedddd"); } Stream<Duration>? _positionStream; var currentSecond = 0; late StreamSubscription<Duration> _positionSubscription; AudioPlayerHandlerMain(PlayingMediaItem _item, BuildContext context) { _player.playbackEventStream.map(_transformEvent).pipe(playbackState); mediaItem.add(_item); _player.setAudioSource(AudioSource.uri(Uri.parse(_item.id))); notifyListeners(); } AudioPlayer getPlayer() { return _player; } static isMediaPlayable(String? url, int id) async { print("Audio file id: $id"); try { if(Platform.isIOS){ AudioPlayer().setFilePath(url ?? ""); }else{ await AudioPlayer().setUrl(url ?? ""); } Timer.periodic(Duration(seconds: 10), (Timer t) { getIt<AudioPulseDaoRepository>() .getAudioPulseItem(current_audio_file_id) .then((value) { }); }); return true; } catch (e) { return false; } } static getDuration(String url) async { try { return await AudioPlayer().setUrl(url ?? ""); } catch (e) { return Duration(); } } AudioPlayerHandlerMain? _audioHandler; void initAudioHandler(AudioPlayerHandlerMain audioHandler) { _audioHandler = audioHandler; notifyListeners(); } AudioPlayerHandlerMain? audioHandler() => _audioHandler; @override Future<void> play() async { _player.play(); notifyListeners(); } @override Future<void> pause() async{ _player.pause(); notifyListeners(); } @override Future<void> seek(Duration position) => _player.seek(position); @override Future<void> stop() async { _player.stop(); await playbackState.firstWhere((state) => state.processingState == AudioProcessingState.idle); super.stop(); } PlaybackState _transformEvent(PlaybackEvent event) { if (current_audio_file_id.isNotEmpty) { Stream.periodic(const Duration(seconds: 4), (_) => _player.position) .listen((event) { if (event.inSeconds != 0) { currentSecond = event.inSeconds; if(currentSecond%5==0){ getIt<AudioPulseDaoRepository>().insertAudioPulseItem( AudioPulseModel( current_audio_file_id, currentSecond.toString(), current_audio_file_type)); } } }); } return PlaybackState( controls: [ MediaControl.rewind, if (_player.playing) MediaControl.pause else MediaControl.play, MediaControl.stop, MediaControl.fastForward, ], systemActions: const { MediaAction.seek, MediaAction.seekForward, MediaAction.seekBackward, }, androidCompactActionIndices: const [0, 1, 3], processingState: const { ProcessingState.idle: AudioProcessingState.idle, ProcessingState.loading: AudioProcessingState.loading, ProcessingState.buffering: AudioProcessingState.buffering, ProcessingState.ready: AudioProcessingState.ready, ProcessingState.completed: AudioProcessingState.completed, }[_player.processingState]!, playing: _player.playing, updatePosition: _player.position, bufferedPosition: _player.bufferedPosition, speed: _player.speed, queueIndex: event.currentIndex, ); } Duration lastFileDuration = Duration.zero; void setLastFileDuration(Duration fileDuration) { //TODO: maybe required in future. lastFileDuration = fileDuration; notifyListeners(); } }
main.dart(初始化音频处理器部分)
Future<void> initAudioHandler(BuildContext context) async { var handler = await AudioService.init( builder: () => AudioPlayerHandlerMain( PlayingMediaItem.getDummyModel() ,context ), config: const AudioServiceConfig( androidNotificationChannelId: 'com.platform.untotheones', androidNotificationChannelName: 'Unto The One', androidNotificationOngoing: false, androidStopForegroundOnPause: true, ), ); Provider.of<AudioPlayerHandlerMain>(context, listen: false).initAudioHandler(handler); } }
内容的提问来源于stack exchange,提问作者Saffi Zahid
相关产品推荐
相关产品推荐

