You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Flutter:使用just_audio自定义排序当前播放列表

实现基于元数据的自定义排序(just_audio + flutter_media_metadata)

当然可以!just_audio完全支持基于自定义元数据的播放列表排序,我帮你梳理下具体实现步骤和代码示例:

核心思路

你需要先把每个音频源和对应的元数据绑定,然后根据元数据字段对这个绑定列表排序,最后将排序后的音频源生成播放列表设置给播放器。

具体步骤

  1. 创建绑定元数据和音频源的模型类
    首先定义一个简单的类,用来关联每个音频的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,
  });
}
  1. 提取所有音频的元数据并绑定
    遍历你要加入播放列表的音频文件/资源,用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));
}
  1. 根据元数据自定义排序
    根据你需要的字段排序,比如按标题、艺术家、时长等。这里举几个常见例子:
  • 按标题升序排序:
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);
});
  1. 生成排序后的播放列表并设置给播放器
    将排序后的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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.28 20:27:38