Awesome Open Source
Awesome Open Source

๐ŸŽง assets_audio_player ๐Ÿ”Š

pub package Awesome Flutter

Codemagic build status CodeFactor

Play music/audio stored in assets files (simultaneously) directly from Flutter (android / ios / web / macos).

You can also use play audio files from network using their url, radios/livestream and local files

Notification can be displayed on Android & iOS, and bluetooth actions are handled

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

sample1 sample1

๐Ÿ“ฅ Import

dependencies:
  assets_audio_player: ^3.0.3+1
  
or

assets_audio_player:
git:
url: https://github.com/florent37/Flutter-AssetsAudioPlayer.git
ref: master

ref can be latest commit id. 

Works with flutter: ">=1.12.13+hotfix.6 <2.0.0", be sure to upgrade your sdk

You like the package ? buy me a kofi :)

Buy Me a Coffee at ko-fi.com

Audio Source Android iOS Web MacOS
๐Ÿ—„๏ธ Asset file (asset path) โœ… โœ… โœ… โœ…
๐ŸŒ Network file (url) โœ… โœ… โœ… โœ…
๐Ÿ“ Local file (path) โœ… โœ… โœ… โœ…
๐Ÿ“ป Network LiveStream / radio (url)
(Default, HLS, Dash, SmoothStream)
โœ… โœ… โœ… โœ…
Feature Android iOS Web MacOS
๐ŸŽถ Multiple players โœ… โœ… โœ… โœ…
๐Ÿ’ฝ Open Playlist โœ… โœ… โœ… โœ…
๐Ÿ’ฌSystem notification โœ… โœ… ๐Ÿšซ ๐Ÿšซ
๐ŸŽง Bluetooth actions โœ… โœ… ๐Ÿšซ ๐Ÿšซ
๐Ÿ”• Respect System silent mode โœ… โœ… ๐Ÿšซ ๐Ÿšซ
๐Ÿ“ž Pause on phone call โœ… โœ… ๐Ÿšซ ๐Ÿšซ
Commands Android iOS Web MacOS
โ–ถ Play โœ… โœ… โœ… โœ…
โธ Pause โœ… โœ… โœ… โœ…
โน Stop โœ… โœ… โœ… โœ…
โฉ Seek(position) โœ… โœ… โœ… โœ…
โชโฉ SeekBy(position) โœ… โœ… โœ… โœ…
โฉ Forward(speed) โœ… โœ… โœ… โœ…
โช Rewind(speed) โœ… โœ… โœ… โœ…
โญ Next โœ… โœ… โœ… โœ…
โฎ Prev โœ… โœ… โœ… โœ…
Widgets Android iOS Web MacOS
๐Ÿฆ Audio Widget โœ… โœ… โœ… โœ…
๐Ÿฆ Widget Builders โœ… โœ… โœ… โœ…
๐Ÿฆ AudioPlayer Builders Extension โœ… โœ… โœ… โœ…
Properties Android iOS Web MacOS
๐Ÿ” Loop โœ… โœ… โœ… โœ…
๐Ÿ”€ Shuffle โœ… โœ… โœ… โœ…
๐Ÿ”Š get/set Volume โœ… โœ… โœ… โœ…
โฉ get/set Play Speed โœ… โœ… โœ… โœ…
โฉ get/set Pitch โœ… ๐Ÿšซ ๐Ÿšซ ๐Ÿšซ
Listeners Android iOS Web MacOS
๐Ÿฆป Listener onReady(completeDuration) โœ… โœ… โœ… โœ…
๐Ÿฆป Listener currentPosition โœ… โœ… โœ… โœ…
๐Ÿฆป Listener finished โœ… โœ… โœ… โœ…
๐Ÿฆป Listener buffering โœ… โœ… โœ… โœ…
๐Ÿฆป Listener volume โœ… โœ… โœ… โœ…
๐ŸฆปListener Play Speed โœ… โœ… โœ… โœ…
๐ŸฆปListener Pitch โœ… ๐Ÿšซ ๐Ÿšซ ๐Ÿšซ

๐Ÿ“ Import assets files

No needed to copy songs to a media cache, with assets_audio_player you can open them directly from the assets.

  1. Create an audio directory in your assets (not necessary named "audios")
  2. Declare it inside your pubspec.yaml
flutter:
  assets:
    - assets/audios/

๐Ÿ› ๏ธ Getting Started

final assetsAudioPlayer = AssetsAudioPlayer();

assetsAudioPlayer.open(
    Audio("assets/audios/song1.mp3"),
);

You can also play network songs from url

final assetsAudioPlayer = AssetsAudioPlayer();

try {
    await assetsAudioPlayer.open(
        Audio.network("http://www.mysite.com/myMp3file.mp3"),
    );
} catch (t) {
    //mp3 unreachable
}

LiveStream / Radio from url

The main difference with network, if you pause/play, on livestream it will resume to present duration

final assetsAudioPlayer = AssetsAudioPlayer();

try {
    await assetsAudioPlayer.open(
        Audio.liveStream(MY_LIVESTREAM_URL),
    );
} catch (t) {
    //stream unreachable
}

And play songs from file

//create a new player
final assetsAudioPlayer = AssetsAudioPlayer();

assetsAudioPlayer.open(
    Audio.file(FILE_URI),
);

for file uri, please look at https://pub.dev/packages/path_provider

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();

Notifications

notification

notification

on iOS, it will use MPNowPlayingInfoCenter

  1. Add metas inside your audio
final audio = Audio.network("/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. open with showNotification: true
_player.open(audio, showNotification: true)

Custom notification

Custom icon (android only)

By ResourceName

Make sur you added those icons inside your android/res/drawable !!! not on flutter assets !!!!

await _assetsAudioPlayer.open(
        myAudio,
        showNotification: true,
        notificationSettings: NotificationSettings(
            customStopIcon: AndroidResDrawable(name: "ic_stop_custom"),
            customPauseIcon: AndroidResDrawable(name:"ic_pause_custom"),
            customPlayIcon: AndroidResDrawable(name:"ic_play_custom"),
            customPrevIcon: AndroidResDrawable(name:"ic_prev_custom"),
            customNextIcon: AndroidResDrawable(name:"ic_next_custom"),
        )
      

And don't forget tell proguard to keep those resources for release mode

(part Keeping Resources)

https://sites.google.com/a/android.com/tools/tech-docs/new-build-system/resource-shrinking


<?xml version="1.0" encoding="utf-8"?>
<resources xmlns:tools="http://schemas.android.com/tools"
tools:keep="@drawable/ic_next_custom, @drawable/ic_prev_custom, @drawable/ic_pause_custom, @drawable/ic_play_custom, @drawable/ic_stop_custom"/>

By Manifest

  1. Add your icon into your android's res folder (android/app/src/main/res)

  2. Reference this icon into your AndroidManifest (android/app/src/main/AndroidManifest.xml)

<meta-data
     android:name="assets.audio.player.notification.icon"
     android:resource="@drawable/ic_music_custom"/>

You can also change actions icons

<meta-data
    android:name="assets.audio.player.notification.icon.play"
    android:resource="@drawable/ic_play_custom"/>
<meta-data
    android:name="assets.audio.player.notification.icon.pause"
    android:resource="@drawable/ic_pause_custom"/>
<meta-data
    android:name="assets.audio.player.notification.icon.stop"
    android:resource="@drawable/ic_stop_custom"/>
<meta-data
    android:name="assets.audio.player.notification.icon.next"
    android:resource="@drawable/ic_next_custom"/>
<meta-data
    android:name="assets.audio.player.notification.icon.prev"
    android:resource="@drawable/ic_prev_custom"/>

Handle notification click (android)

Add in main

AssetsAudioPlayer.setupNotificationsOpenAction((notification) {
    //custom action
    return true; //true : handled, does not notify others listeners
                 //false : enable others listeners to handle it
});

Then if you want a custom action on widget

AssetsAudioPlayer.addNotificationOpenAction((notification) {
   //custom action
   return false; //true : handled, does not notify others listeners
                 //false : enable others listeners to handle it
});

Custom actions

You can enable/disable a notification action

open(AUDIO,
   showNotification: true,
   notificationSettings: NotificationSettings(
       prevEnabled: false, //disable the previous button
  
       //and have a custom next action (will disable the default action)
       customNextAction: (player) {
         print("next");
       }
   )

)

Update audio's metas / notification content

After your audio creation, just call

audio.updateMetas(
       player: _assetsAudioPlayer, //add the player if the audio is actually played
       title: "My new title",
       artist: "My new artist",
       //if I not provide a new album, it keep the old one
       image: MetasImage.network(
         //my new image url
       ),
);

Bluetooth Actions

You have to enable notification to make them work

Available remote commands :

  • Play / Pause
  • Next
  • Prev
  • Stop

HeadPhone Strategy

(Only for Android for now)

while opening a song/playlist, add a strategy

assetsAudioPlayer.open(
   ...
  headPhoneStrategy: HeadPhoneStrategy.pauseOnUnplug,
  //headPhoneStrategy: HeadPhoneStrategy.none, //default
  //headPhoneStrategy: HeadPhoneStrategy.pauseOnUnplugPlayOnPlug,
)

If you want to make it work on bluetooth too, you'll have to add the BLUETOOTH permission inside your AndroidManifest.xml

<uses-permission android:name="android.permission.BLUETOOTH" />

โ›“ Play in parallel / simultaneously

You can create new AssetsAudioPlayer using AssetsAudioPlayer.newPlayer(), which will play songs in a different native Media Player

This will enable to play two songs simultaneously

You can have as many player as you want !

///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")
);

Each player has an unique generated id, you can retrieve or create them manually using

final player = AssetsAudioPlayer.withId(id: "MY_UNIQUE_ID");

๐Ÿ—„๏ธ Playlist

assetsAudioPlayer.open(
  Playlist(
    audios: [
      Audio("assets/audios/song1.mp3"),
      Audio("assets/audios/song2.mp3")
    ]
  ),
  loopMode: LoopMode.playlist //loop the full playlist
);

assetsAudioPlayer.next();
assetsAudioPlayer.prev();
assetsAudioPlayer.playlistPlayAtIndex(1);

Audio Widget

If you want a more flutter way to play audio, try the AudioWidget !

sample

//inside a stateful widget

bool _play = false;

@override
Widget build(BuildContext context) {
  return AudioWidget.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) {
          //onPositionChanged
      },
  );
}

How to ๐Ÿ›‘ stop ๐Ÿ›‘ the AudioWidget ?

Just remove the Audio from the tree ! Or simply keep play: false

๐ŸŽง Listeners

All listeners exposes Streams Using RxDart, AssetsAudioPlayer exposes some listeners as ValueObservable (Observable that provides synchronous access to the last emitted item);

๐ŸŽต Current song

//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;
})

โŒ› Current song duration

//Listen to the current playing song
final duration = assetsAudioPlayer.current.value.duration;

โณ Current position (in seconds)

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());  
    }),

or use a PlayerBuilder !

PlayerBuilder.currentPosition(
     player: _assetsAudioPlayer,
     builder: (context, duration) {
       return Text(duration.toString());  
     }
)

or Player Builder Extension

_assetsAudioPlayer.builderCurrentPosition(
     builder: (context, duration) {
       return Text(duration.toString());  
     }
)

โ–ถ IsPlaying

boolean observable representing the current mediaplayer playing state

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");  
    }),

or use a PlayerBuilder !

PlayerBuilder.isPlaying(
     player: _assetsAudioPlayer,
     builder: (context, isPlaying) {
       return Text(isPlaying ? "Pause" : "Play");  
     }
)

or Player Builder Extension

_assetsAudioPlayer.builderIsPlaying(
     builder: (context, isPlaying) {
       return Text(isPlaying ? "Pause" : "Play");  
     }
)

๐Ÿ”Š Volume

Change the volume (between 0.0 & 1.0)

assetsAudioPlayer.setVolume(0.5);

The media player can follow the system "volume mode" (vibrate, muted, normal) Simply set the respectSilentMode optional parameter as true

_player.open(PLAYABLE, respectSilentMode: true);

https://developer.android.com/reference/android/media/AudioManager.html?hl=fr#getRingerMode()

https://developer.apple.com/documentation/avfoundation/avaudiosessioncategorysoloambient

Listen the volume

return StreamBuilder(
    stream: assetsAudioPlayer.volume,
    builder: (context, asyncSnapshot) {
        final double volume = asyncSnapshot.data;
        return Text("volume : $volume");  
    }),

or use a PlayerBuilder !

PlayerBuilder.volume(
     player: _assetsAudioPlayer,
     builder: (context, volume) {
       return Text("volume : $volume");
     }
)

โœ‹ Finished

Called when the current song has finished to play,

it gives the Playing audio that just finished

assetsAudioPlayer.playlistAudioFinished //ValueObservable<Playing>

assetsAudioPlayer.playlistAudioFinished.listen((Playing playing){
    
})

Called when the complete playlist has finished to play

assetsAudioPlayer.playlistFinished //ValueObservable<bool>

assetsAudioPlayer.playlistFinished.listen((finished){
    
})

๐Ÿ” Looping

final LoopMode loopMode = assetsAudioPlayer.loop; 
// possible values
// LoopMode.none : not looping
// LoopMode.single : looping a single audio
// LoopMode.playlist : looping the fyll playlist

assetsAudioPlayer.setLoopMode(LoopMode.single);

assetsAudioPlayer.loopMode.listen((loopMode){
    //listen to loop
})

assetsAudioPlayer.toggleLoop(); //toggle the value of looping

๐Ÿƒ Play Speed

assetsAudioPlayer.setPlaySpeed(1.5);

assetsAudioPlayer.playSpeed.listen((playSpeed){
    //listen to playSpeed
})

//change play speed for a particular Audio

Audio audio = Audio.network(
    url,
    playSpeed: 1.5
);
assetsAudioPlayer.open(audio);

๐ŸŽ™๏ธ Pitch

assetsAudioPlayer.setPitch(1.2);

assetsAudioPlayer.pitch.listen((pitch){
    //listen to pitch
})

//change pitch for a particular Audio

Audio audio = Audio.network(
    url,
    pitch: 1.2
);
assetsAudioPlayer.open(audio);

Error Handling

By default, on playing error, it stop the audio

BUT you can add a custom behavior

_player.onErrorDo = (handler){
  handler.player.stop();
};

Open another audio

_player.onErrorDo = (handler){
  handler.player.open(ANOTHER_AUDIO);
};

Try to open again on same position

_player.onErrorDo = (handler){
  handler.player.open(
      handler.playlist.copyWith(
        startIndex: handler.playlistIndex
      ),
      seek: handler.currentPosition
  );
};

Network Policies (android/iOS/macOS)

Android only allow HTTPS calls, you will have an error if you're using HTTP, don't forget to add INTERNET permission and seet usesCleartextTraffic="true" in your AndroidManifest.xml

<?xml version="1.0" encoding="utf-8"?>
<manifest ...>
    <uses-permission android:name="android.permission.INTERNET" />
    <application
        ...
        android:usesCleartextTraffic="true"
        ...>
        ...
    </application>
</manifest>

iOS only allow HTTPS calls, you will have an error if you're using HTTP, don't forget to edit your info.plist and set NSAppTransportSecurity to NSAllowsArbitraryLoads

<key>NSAppTransportSecurity</key>
<dict>
    <key>NSAllowsArbitraryLoads</key>
    <true/>
</dict>

To enable http calls on macOs, you have to add input/output calls capabilities into info.plist

<key>NSAppTransportSecurity</key>
<dict>
    <key>NSAllowsArbitraryLoads</key>
    <true/>
</dict>
<key>UIBackgroundModes</key>
<array>
    <string>audio</string>
    <string>fetch</string>
</array>
<key>com.apple.security.network.client</key>
<true/>

and in your

Runner/DebugProfile.entitlements

add

<key>com.apple.security.network.client</key>
<true/>

Complete Runner/DebugProfile.entitlements

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
	<key>com.apple.security.app-sandbox</key>
	<true/>
	<key>com.apple.security.cs.allow-jit</key>
	<true/>
	<key>com.apple.security.network.server</key>
	<true/>
	<key>com.apple.security.network.client</key>
	<true/>
</dict>
</plist>

๐ŸŽถ Musics

All musics used in the samples came from https://www.freemusicarchive.org/


Get A Weekly Email With Trending Projects For These Topics
No Spam. Unsubscribe easily at any time.
Java (698,001)ย 
Swift (94,889)ย 
Dart (63,554)ย 
Kotlin (61,993)ย 
Android (41,705)ย 
Ios (19,619)ย 
Flutter (12,515)ย 
Macos (9,206)ย 
Web (7,814)ย 
Audio (4,136)ย 
Mac (1,464)ย 
Player (1,385)ย 
Media (865)ย 
Mp3 (806)ย 
Playlist (582)ย 
Songs (468)ย 
Listen (106)ย 
Audios (9)ย 
Related Projects
Advertising ๐Ÿ“ฆย 9
All Projects
Application Programming Interfaces ๐Ÿ“ฆย 120
Applications ๐Ÿ“ฆย 181
Artificial Intelligence ๐Ÿ“ฆย 72
Blockchain ๐Ÿ“ฆย 70
Build Tools ๐Ÿ“ฆย 111
Cloud Computing ๐Ÿ“ฆย 79
Code Quality ๐Ÿ“ฆย 28
Collaboration ๐Ÿ“ฆย 30
Command Line Interface ๐Ÿ“ฆย 48
Community ๐Ÿ“ฆย 81
Companies ๐Ÿ“ฆย 60
Compilers ๐Ÿ“ฆย 60
Computer Science ๐Ÿ“ฆย 74
Configuration Management ๐Ÿ“ฆย 39
Content Management ๐Ÿ“ฆย 167
Control Flow ๐Ÿ“ฆย 197
Data Formats ๐Ÿ“ฆย 77
Data Processing ๐Ÿ“ฆย 266
Data Storage ๐Ÿ“ฆย 132
Economics ๐Ÿ“ฆย 60
Frameworks ๐Ÿ“ฆย 198
Games ๐Ÿ“ฆย 122
Graphics ๐Ÿ“ฆย 103
Hardware ๐Ÿ“ฆย 148
Integrated Development Environments ๐Ÿ“ฆย 47
Learning Resources ๐Ÿ“ฆย 147
Legal ๐Ÿ“ฆย 28
Libraries ๐Ÿ“ฆย 119
Lists Of Projects ๐Ÿ“ฆย 21
Machine Learning ๐Ÿ“ฆย 336
Mapping ๐Ÿ“ฆย 61
Marketing ๐Ÿ“ฆย 15
Mathematics ๐Ÿ“ฆย 55
Media ๐Ÿ“ฆย 228
Messaging ๐Ÿ“ฆย 97
Networking ๐Ÿ“ฆย 304
Operating Systems ๐Ÿ“ฆย 84
Operations ๐Ÿ“ฆย 120
Package Managers ๐Ÿ“ฆย 52
Programming Languages ๐Ÿ“ฆย 229
Runtime Environments ๐Ÿ“ฆย 96
Science ๐Ÿ“ฆย 42
Security ๐Ÿ“ฆย 375
Social Media ๐Ÿ“ฆย 26
Software Architecture ๐Ÿ“ฆย 70
Software Development ๐Ÿ“ฆย 68
Software Performance ๐Ÿ“ฆย 57
Software Quality ๐Ÿ“ฆย 127
Text Editors ๐Ÿ“ฆย 45
Text Processing ๐Ÿ“ฆย 131
User Interface ๐Ÿ“ฆย 310
User Interface Components ๐Ÿ“ฆย 465
Version Control ๐Ÿ“ฆย 29
Virtualization ๐Ÿ“ฆย 68
Web Browsers ๐Ÿ“ฆย 38
Web Servers ๐Ÿ“ฆย 25
Web User Interface ๐Ÿ“ฆย 194