assets_audio_player

直接从 Flutter 播放存储在 assets 文件中的音乐/音频(同步播放),支持 Android / iOS / Web。

您也可以通过 URL 播放网络上的音频文件。

flutter:
  assets:
    - assets/audios/
AssetsAudioPlayer.newPlayer().open(
    Audio("assets/audios/song1.mp3"),
    autoPlay: true,
);

sample1
sample1

? 导入

dependencies:
  assets_audio_player: ^1.4.7+4

兼容 flutter: ">=1.12.13+hotfix.6 <2.0.0",请确保升级您的 SDK。

? Web 支持

如果您想要 Web 支持,请先启用 Web,然后添加:

dependencies:
  assets_audio_player_web: ^1.4.7+4

喜欢这个库?请给我买杯咖啡!:)

Buy Me a Coffee at ko-fi.com

音频来源 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 中打开它们。

  1. 在您的 assets 中创建一个音频目录(不一定命名为“audios”)
  2. 在您的 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();

通知

notification_android

notification_iOS

在 iOS 上,它将使用 MPNowPlayingInfoCenter

  1. 在您的音频中添加元数据。
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
          ),
   );
  1. 使用 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

audio_widget

//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>

GitHub

https://github.com/florent37/Flutter-AssetsAudioPlayer