为何request方法的end参数始终为null?加密音频大文件播放卡顿
加密音频播放卡顿与StreamAudioSource request参数异常问题
我正在开发一款支持加密文件存储与读取的App,使用just_audio和audio_service包实现音频播放功能。为解决大音频文件加载时App帧率降至2fps的问题,我尝试在StreamAudioSource中实现缓冲区系统,但运行时发现request方法的end参数始终传入null。
测试情况:
- 10分钟时长的音频在调试模式下可正常播放
- 50MB以上的大文件在调试及发布模式下均卡顿严重(帧率仅2fps)且无法播放(当前优先处理Android端)
相关实现代码
class EncryptedAudioSource extends StreamAudioSource { final Stream<List<int>> streamedData; List<int> bufferedData = []; Completer? targetCompleter; int? currentTarget; final String mimeType; final int fileByteLength; EncryptedAudioSource(this.streamedData, this.mimeType, this.fileByteLength, {super.tag = 'EncryptedAudioSource'}) { streamedData.listen((receivedData) { bufferedData += receivedData; if(currentTarget != null && bufferedData.length >= currentTarget!) { if(targetCompleter != null) { targetCompleter!.complete(); } currentTarget = null; } }); } @override Future<StreamAudioResponse> request([int? start, int? end]) async { debugPrint('asked for $start to $end length is $fileByteLength'); start ??= 0; end ??= bufferedData.length; return StreamAudioResponse( sourceLength: fileByteLength, contentLength: end - start, offset: start, stream: Stream.value(bufferedData.sublist(start, end)), contentType: mimeType, ); } } class AudioPlayerHandler extends BaseAudioHandler with SeekHandler { final _player = AudioPlayer(); AudioPlayerHandler() { _player.playbackEventStream.map(_transformEvent).pipe(playbackState); } void playFile(MediaItem item, EncryptedAudioSource source) { mediaItem.add(item); _player.setAudioSource(source); } @override Future<void> play() async { if(playbackState.value.processingState == AudioProcessingState.ready) { _player.play(); } } @override Future<void> pause() => _player.pause(); @override Future<void> seek(Duration position) => _player.seek(position); @override Future<void> stop() => _player.stop(); PlaybackState _transformEvent(PlaybackEvent event) { 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, ); } }
运行时日志
asked for null to null length is 10195448 asked for 65765 to null length is 10195448 asked for 219 to null length is 10195448 asked for 101071 to null length is 10195448 asked for 101071 to null length is 10195448 asked for 101071 to null length is 10195448 asked for 101071 to null length is 10195448
内容的提问来源于stack exchange,提问作者theskyblockman
相关产品推荐
相关产品推荐

