如何在JustAudio播放器中实现HLS流的懒加载式M3U8获取
实现HLS音频播放列表的按需懒加载
你的问题核心是预加载所有HLS流对应的M3U8文件导致初始化耗时过长,下面是改成播放时才请求对应资源的懒加载实现方案:
核心思路
借助just_audio的自定义AudioSource能力,创建一个懒加载音频源类——仅当播放器准备播放该音频项时,才触发HTTP请求获取实际M3U8地址,再加载真正的音频资源。
代码实现
1. 自定义懒加载HLS音频源
class LazyHlsAudioSource extends AudioSource { final String hlsApiUrl; final MediaItem mediaItem; LazyHlsAudioSource({ required this.hlsApiUrl, required this.mediaItem, }); @override Future<AudioSource> load() async { // 仅在播放触发时发起网络请求 final response = await http.get( Uri.parse(hlsApiUrl), headers: {"Access-Control-Allow-Origin": "*"}, ); final audioData = json.decode(response.body); final m3u8Url = audioData['url']; return AudioSource.uri( Uri.parse(m3u8Url), tag: mediaItem, ); } @override String get id => mediaItem.id; @override MediaItem get tag => mediaItem; }
2. 初始化播放列表
Future<void> _init() async { final List<AudioSource> lazySources = []; for (int i = 0; i < widget.audioURLs!.length; i++) { lazySources.add( LazyHlsAudioSource( hlsApiUrl: widget.audioURLs![i], mediaItem: MediaItem( id: '${_nextMediaId++}', album: widget.audioTitles![i], title: widget.artistName!, ), ), ); } final playlist = ConcatenatingAudioSource(children: lazySources); await _player.setAudioSource(playlist); }
方案说明
- 初始化阶段仅创建懒加载源对象,不会发起任何网络请求,直接缩短初始化耗时;
- 当用户点击播放某首歌、播放器自动切换下一首时,才会触发对应音频源的
load方法,执行HTTP请求并加载M3U8资源; - 原有播放器的控制逻辑(上一首、下一首、列表切换等)无需修改,保持原有交互体验。
内容的提问来源于stack exchange,提问作者Jagpreet Sethi
相关产品推荐
相关产品推荐

