Flutter:使用just_audio自定义排序当前播放列表
实现基于元数据的自定义排序(just_audio + flutter_media_metadata)
当然可以!just_audio完全支持基于自定义元数据的播放列表排序,我帮你梳理下具体实现步骤和代码示例:
核心思路
你需要先把每个音频源和对应的元数据绑定,然后根据元数据字段对这个绑定列表排序,最后将排序后的音频源生成播放列表设置给播放器。
具体步骤
- 创建绑定元数据和音频源的模型类
首先定义一个简单的类,用来关联每个音频的AudioSource和从flutter_media_metadata获取到的Metadata:
import 'package:just_audio/just_audio.dart'; import 'package:flutter_media_metadata/flutter_media_metadata.dart'; class TrackWithMetadata { final AudioSource audioSource; final Metadata metadata; TrackWithMetadata({ required this.audioSource, required this.metadata, }); }
- 提取所有音频的元数据并绑定
遍历你要加入播放列表的音频文件/资源,用flutter_media_metadata提取元数据,然后生成TrackWithMetadata列表:
// 假设你有一个本地音频文件路径列表 final audioPaths = ['/path/to/track1.mp3', '/path/to/track2.mp3']; final List<TrackWithMetadata> tracks = []; for (final path in audioPaths) { // 提取元数据 final metadata = await MetadataRetriever.fromFile(File(path)); // 创建对应的AudioSource(本地文件用AudioSource.file) final audioSource = AudioSource.file(path); // 添加到绑定列表 tracks.add(TrackWithMetadata(audioSource: audioSource, metadata: metadata)); }
- 根据元数据自定义排序
根据你需要的字段排序,比如按标题、艺术家、时长等。这里举几个常见例子:
- 按标题升序排序:
tracks.sort((a, b) { // 处理元数据字段可能为空的情况,用默认值兜底 final titleA = a.metadata.title ?? ''; final titleB = b.metadata.title ?? ''; return titleA.compareTo(titleB); });
- 按艺术家+标题排序:
tracks.sort((a, b) { final artistA = a.metadata.artist ?? ''; final artistB = b.metadata.artist ?? ''; final artistCompare = artistA.compareTo(artistB); if (artistCompare != 0) return artistCompare; final titleA = a.metadata.title ?? ''; final titleB = b.metadata.title ?? ''; return titleA.compareTo(titleB); });
- 按时长降序排序:
tracks.sort((a, b) { // 时长单位是毫秒,注意空值处理 final durationA = a.metadata.duration ?? 0; final durationB = b.metadata.duration ?? 0; return durationB.compareTo(durationA); });
- 生成排序后的播放列表并设置给播放器
将排序后的TrackWithMetadata列表转换成ConcatenatingAudioSource(just_audio常用的播放列表类型),然后设置给播放器:
final player = AudioPlayer(); // 生成排序后的播放列表 final sortedPlaylist = ConcatenatingAudioSource( children: tracks.map((track) => track.audioSource).toList(), ); // 设置给播放器 await player.setAudioSource(sortedPlaylist);
适配你的现有流程
如果你的现有流程是先创建播放列表再设置到播放器,那可以调整为:先提取所有音频的元数据并排序,再创建排序后的播放列表,最后设置给播放器。如果已经有了已创建的播放列表,也可以遍历ConcatenatingAudioSource的children,逐个提取元数据后重新排序,再生成新的播放列表替换原有的。
注意事项
- 处理元数据字段为空的情况:部分音频文件可能没有完整的元数据,一定要用
??给默认值,避免排序时出现空指针异常。 - 异步处理:提取元数据是异步操作,要确保在所有元数据提取完成后再进行排序。
- 网络音频:如果是网络音频源,需要用
MetadataRetriever.fromUri来提取元数据,对应AudioSource.uri。
内容的提问来源于stack exchange,提问作者batalha
相关产品推荐
相关产品推荐

