assets_audio_player
直接从 Flutter 播放存储在 assets 文件中的音乐/音频(同步播放),支持 Android / iOS / Web。
您也可以通过 URL 播放网络上的音频文件。
flutter:
assets:
- assets/audios/
AssetsAudioPlayer.newPlayer().open(
Audio("assets/audios/song1.mp3"),
autoPlay: true,
);
? 导入
dependencies:
assets_audio_player: ^1.4.7+4
兼容 flutter: ">=1.12.13+hotfix.6 <2.0.0",请确保升级您的 SDK。
喜欢这个库?请给我买杯咖啡!:)
| 音频来源 | Android | iOS | Web |
|---|---|---|---|
| Asset 文件 (asset 路径) | ✅ | ✅ | ✅ |
| 网络文件 (url) | ✅ | ✅ | ✅ |
| 本地文件 (路径) | ✅ | ✅ | ✅ |
| 网络直播流 (url) | ✅ | ✅ | ✅ |
| 命令 | Android | iOS | Web |
|---|---|---|---|
| 播放 | ✅ | ✅ | ✅ |
| 暂停 | ✅ | ✅ | ✅ |
| 停止 | ✅ | ✅ | ✅ |
| 定位 (position) | ✅ | ✅ | ✅ |
| 按位移定位 (SeekBy) | ✅ | ✅ | ✅ |
| 快进 (speed) | ✅ | ✅ | ✅ |
| 快退 (speed) | ✅ | ✅ | ✅ |
| 下一步 | ✅ | ✅ | ✅ |
| 上一个 | ✅ | ✅ | ✅ |
| 功能 | Android | iOS | Web |
|---|---|---|---|
| 多个播放器 | ✅ | ✅ | ✅ |
| 打开播放列表 | ✅ | ✅ | ✅ |
| 系统通知 | ✅ | ✅ | ? |
| 尊重系统静音模式 | ✅ | ✅ | ? |
| 通话时暂停 | ✅ | ✅ | ? |
| Audio Widget | ✅ | ✅ | ✅ |
| 属性 | Android | iOS | Web |
|---|---|---|---|
| 循环 | ✅ | ✅ | ✅ |
| 获取/设置音量 | ✅ | ✅ | ✅ |
| 获取/设置播放速度 | ✅ | ✅ | ✅ |
| 监听器 | Android | iOS | Web |
|---|---|---|---|
| 就绪监听器 (completeDuration) | ✅ | ✅ | ✅ |
| 当前位置监听器 | ✅ | ✅ | ✅ |
| 完成监听器 | ✅ | ✅ | ✅ |
| 缓冲监听器 | ✅ | ✅ | ✅ |
| 音量监听器 | ✅ | ✅ | ✅ |
| 播放速度监听器 | ✅ | ✅ | ✅ |
? 导入 Asset 文件
无需将歌曲复制到媒体缓存,使用 assets_audio_player 可以直接从 assets 中打开它们。
- 在您的 assets 中创建一个音频目录(不一定命名为“audios”)
- 在您的 pubspec.yaml 中声明它
flutter:
assets:
- assets/audios/
?️ 入门
final assetsAudioPlayer = AssetsAudioPlayer();
assetsAudioPlayer.open(
Audio("assets/audios/song1.mp3"),
);
您还可以通过 URL 播放网络歌曲。
final assetsAudioPlayer = AssetsAudioPlayer();
try {
await assetsAudioPlayer.open(
Audio.network("http://www.mysite.com/myMp3file.mp3"),
);
} catch (t) {
//mp3 unreachable
}
并播放文件中的歌曲。
//create a new player
final assetsAudioPlayer = AssetsAudioPlayer();
assetsAudioPlayer.open(
Audio.file(FILE_URI),
);
assetsAudioPlayer.playOrPause();
assetsAudioPlayer.play();
assetsAudioPlayer.pause();
assetsAudioPlayer.seek(Duration to);
assetsAudioPlayer.seekBy(Duration by);
assetsAudioPlayer.forwardRewind(double speed);
//if positive, forward, if negative, rewind
assetsAudioPlayer.stop();
通知


在 iOS 上,它将使用 MPNowPlayingInfoCenter。
- 在您的音频中添加元数据。
final audio = Audio("/assets/audio/country.mp3",
metas: Metas(
title: "Country",
artist: "Florent Champigny",
album: "CountryAlbum",
image: MetasImage.asset("assets/images/country.jpg"), //can be MetasImage.network
),
);
- 使用
showNotification: true打开。
_player.open(audio, showNotification: true)
⛓ 并行/同步播放
您可以使用 AssetsAudioPlayer.newPlayer() 创建新的 AssetsAudioPlayer,
这将使用不同的原生媒体播放器播放歌曲。
这将允许同时播放两首歌曲。
您可以拥有任意数量的播放器!
///play 3 songs in parallel
AssetsAudioPlayer.newPlayer().open(
Audio("assets/audios/song1.mp3")
);
AssetsAudioPlayer.newPlayer().open(
Audio("assets/audios/song2.mp3")
);
//another way, with create, open, play & dispose the player on finish
AssetsAudioPlayer.playAndForget(
Audio("assets/audios/song3.mp3")
);
每个播放器都有一个唯一的生成 id,您可以使用以下方法检索或手动创建它们:
final player = AssetsAudioPlayer.withId(id: "MY_UNIQUE_ID");
播放列表
assetsAudioPlayer.open(
Playlist(
assetAudioPaths: [
"assets/audios/song1.mp3",
"assets/audios/song2.mp3"
]
)
);
assetsAudioPlayer.next();
assetsAudioPlayer.prev();
assetsAudioPlayer.playAtIndex(1);
Audio Widget
如果您想要一种更 Flutter 风格的音频播放方式,请尝试 AudioWidget!

//inside a stateful widget
bool _play = false;
@override
Widget build(BuildContext context) {
return Audio.assets(
path: "assets/audios/country.mp3",
play: _play,
child: RaisedButton(
child: Text(
_play ? "pause" : "play",
),
onPressed: () {
setState(() {
_play = !_play;
});
}
),
onReadyToPlay: (duration) {
//onReadyToPlay
},
onPositionChanged: (current, duration) {
//onReadyToPlay
},
);
}
如何?停止? AudioWidget?
只需从树中移除 Audio 即可!
或者简单地保持 play: false。
? 监听器
所有监听器都公开 Stream。
使用 RxDart,AssetsAudioPlayer 将一些监听器公开为 ValueObservable(提供对最后发出项的同步访问的 Observable);
? 当前歌曲
//The current playing audio, filled with the total song duration
assetsAudioPlayer.current //ValueObservable<PlayingAudio>
//Retrieve directly the current played asset
final PlayingAudio playing = assetsAudioPlayer.current.value;
//Listen to the current playing song
assetsAudioPlayer.current.listen((playingAudio){
final asset = playingAudio.assetAudio;
final songDuration = playingAudio.duration;
})
⌛ 当前歌曲时长
//Listen to the current playing song
final duration = assetsAudioPlayer.current.value.duration;
⏳ 当前位置(以秒为单位)
assetsAudioPlayer.currentPosition //ValueObservable<Duration>
//retrieve directly the current song position
final Duration position = assetsAudioPlayer.currentPosition.value;
return StreamBuilder(
stream: assetsAudioPlayer.currentPosition,
builder: (context, asyncSnapshot) {
final Duration duration = asyncSnapshot.data;
return Text(duration.toString());
}),
或者使用 PlayerBuilder!
PlayerBuilder.currentPosition(
player: _assetsAudioPlayer,
builder: (context, duration) {
return Text(duration.toString());
}
)
▶ 正在播放
一个布尔值 Observable,表示当前媒体播放器的播放状态。
assetsAudioPlayer.isPlaying // ValueObservable<bool>
//retrieve directly the current player state
final bool playing = assetsAudioPlayer.isPlaying.value;
//will follow the AssetsAudioPlayer playing state
return StreamBuilder(
stream: assetsAudioPlayer.isPlaying,
builder: (context, asyncSnapshot) {
final bool isPlaying = asyncSnapshot.data;
return Text(isPlaying ? "Pause" : "Play");
}),
或者使用 PlayerBuilder!
PlayerBuilder.isPlaying(
player: _assetsAudioPlayer,
builder: (context, isPlaying) {
return Text(isPlaying ? "Pause" : "Play");
}
)
? 音量
更改音量(介于 0.0 和 1.0 之间)。
assetsAudioPlayer.setVolume(0.5);
媒体播放器可以遵循系统的“音量模式”(振动、静音、正常)。
只需将 respectSilentMode 可选参数设置为 true。
_player.open(PLAYABLE, respectSilentMode: true);
https://developer.android.com.cn/reference/android/media/AudioManager.html?hl=fr#getRingerMode()
https://developer.apple.com/documentation/avfoundation/avaudiosessioncategorysoloambient
监听音量
return StreamBuilder(
stream: assetsAudioPlayer.volume,
builder: (context, asyncSnapshot) {
final double volume = asyncSnapshot.data;
return Text("volume : $volume");
}),
或者使用 PlayerBuilder!
PlayerBuilder.volume(
player: _assetsAudioPlayer,
builder: (context, volume) {
return Text("volume : $volume");
}
)
✋ 完成
当前歌曲播放完毕时调用。
它会提供刚完成的正在播放的音频。
assetsAudioPlayer.playlistAudioFinished //ValueObservable<Playing>
assetsAudioPlayer.playlistAudioFinished.listen((Playing playing){
})
完整的播放列表播放完毕时调用。
assetsAudioPlayer.playlistFinished //ValueObservable<bool>
assetsAudioPlayer.playlistFinished.listen((finished){
})
? 循环
final bool isLooping = assetsAudioPlayer.loop; //true / false
assetsAudioPlayer.loop = true; //set loop as true
assetsAudioPlayer.isLooping.listen((loop){
//listen to loop
})
assetsAudioPlayer.toggleLoop(); //toggle the value of looping
网络策略 (android/iOS)
Android 只允许 HTTPS 调用,如果您使用 HTTP 将会收到错误。
不要忘记添加 INTERNET 权限并在您的 AndroidManifest.xml 中设置 usesCleartextTraffic="true"。
<?xml version="1.0" encoding="utf-8"?>
<manifest ...>
<uses-permission android:name="android.permission.INTERNET" />
<application
...
android:usesCleartextTraffic="true"
...>
...
</application>
</manifest>
iOS 只允许 HTTPS 调用,如果您使用 HTTP 将会收到错误。
不要忘记编辑您的 info.plist 并将 NSAppTransportSecurity 设置为 NSAllowsArbitraryLoads。
<key>NSAppTransportSecurity</key>
<dict>
<key>NSAllowsArbitraryLoads</key>
<true/>
</dict>

