Jouez de la musique/audio stockée dans des fichiers de ressources (simultanément) directement depuis Flutter (android / ios / web / macos).
Vous pouvez également utiliser la lecture de fichiers audio à partir de réseau en utilisant leur URL, radios/diffusion en direct et fichiers locaux
La notification peut être affichée sur Android et iOS, et les actions Bluetooth sont gérées
flutter:
assets:
- assets/audios/
AssetsAudioPlayer.newPlayer().open(
Audio("assets/audios/song1.mp3"),
autoPlay: true,
showNotification: true,
);
dependencies:
assets_audio_player: ^3.0.6
or
assets_audio_player:
git:
url:
ref: master
ref can be latest commit id.
Marche avec flutter: ">=1.12.13+hotfix.6 <2.0.0"
assurez-vous de mettre à jour votre SDK
Le forfait vous plaît ? achète moi un kofi 🙂
Source audio | Android | iOS | la toile | Mac OS |
---|---|---|---|---|
🗄️ Fichier d’actif (chemin d’accès à l’actif) | ✅ | ✅ | ✅ | ✅ |
🌐 Fichier réseau (url) | ✅ | ✅ | ✅ | ✅ |
📁 Fichier local (chemin) | ✅ | ✅ | ✅ | ✅ |
📻 Réseau LiveStream / radio (url) (Par défaut, HLS, Dash, SmoothStream) | ✅ | ✅ | ✅ | ✅ |
Caractéristique | Android | iOS | la toile | Mac OS |
---|---|---|---|---|
🎶 Plusieurs joueurs | ✅ | ✅ | ✅ | ✅ |
💽 Ouvrir la liste de lecture | ✅ | ✅ | ✅ | ✅ |
💬Notification système | ✅ | ✅ | 🚫 | 🚫 |
🎧 Actions Bluetooth | ✅ | ✅ | 🚫 | 🚫 |
🔕 Respectez le mode silencieux du système | ✅ | ✅ | 🚫 | 🚫 |
📞 Pause sur appel téléphonique | ✅ | ✅ | 🚫 | 🚫 |
Commandes | Android | iOS | la toile | Mac OS |
---|---|---|---|---|
▶ Jouer | ✅ | ✅ | ✅ | ✅ |
⏸ Pause | ✅ | ✅ | ✅ | ✅ |
⏹ Arrêtez | ✅ | ✅ | ✅ | ✅ |
⏩ Chercher (position) | ✅ | ✅ | ✅ | ✅ |
⏪⏩ RecherchePar(position) | ✅ | ✅ | ✅ | ✅ |
⏩ Avancer (vitesse) | ✅ | ✅ | ✅ | ✅ |
⏪ Rembobiner (vitesse) | ✅ | ✅ | ✅ | ✅ |
⏭ Suivant | ✅ | ✅ | ✅ | ✅ |
⏮ Préc | ✅ | ✅ | ✅ | ✅ |
Widget | Android | iOS | la toile | Mac OS |
---|---|---|---|---|
🐦 Widget audio | ✅ | ✅ | ✅ | ✅ |
🐦 Constructeurs de widgets | ✅ | ✅ | ✅ | ✅ |
🐦 Extension des constructeurs AudioPlayer | ✅ | ✅ | ✅ | ✅ |
Propriétés | Android | iOS | la toile | Mac OS |
---|---|---|---|---|
🔁 Boucle | ✅ | ✅ | ✅ | ✅ |
🔀 Mélanger | ✅ | ✅ | ✅ | ✅ |
🔊 obtenir/régler le volume | ✅ | ✅ | ✅ | ✅ |
⏩ obtenir/définir la vitesse de lecture | ✅ | ✅ | ✅ | ✅ |
⏩ obtenir/régler la hauteur | ✅ | 🚫 | 🚫 | 🚫 |
Les auditeurs | Android | iOS | la toile | Mac OS |
---|---|---|---|---|
🦻 Auditeur onReady (durée complète) | ✅ | ✅ | ✅ | ✅ |
🦻 Position actuelle de l’auditeur | ✅ | ✅ | ✅ | ✅ |
🦻 Auditeur terminé | ✅ | ✅ | ✅ | ✅ |
🦻 Mise en mémoire tampon de l’auditeur | ✅ | ✅ | ✅ | ✅ |
🦻 Volume d’écoute | ✅ | ✅ | ✅ | ✅ |
🦻Vitesse de lecture de l’auditeur | ✅ | ✅ | ✅ | ✅ |
🦻Pitch d’écoute | ✅ | 🚫 | 🚫 | 🚫 |
Pas besoin de copier des chansons dans un cache multimédia, avec assets_audio_player, vous pouvez les ouvrir directement à partir des actifs.
- Créez un répertoire audio dans vos ressources (pas nécessairement nommé « audios »)
- Déclarez-le dans votre pubspec.yaml
flutter:
assets:
- assets/audios/
🛠️ Mise en route
final assetsAudioPlayer = AssetsAudioPlayer();
assetsAudioPlayer.open(
Audio("assets/audios/song1.mp3"),
);
Vous pouvez également jouer chansons du réseau de URL
Diffusion en direct / Radio de URL
La principale différence avec le réseau, si vous mettez en pause/jouez, sur le livestream, il reprendra à la durée actuelle
Et joue chansons du fichier
//create a new player
final assetsAudioPlayer = AssetsAudioPlayer();
assetsAudioPlayer.open(
Audio.file(FILE_URI),
);
pour le fichier uri, veuillez regarder
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();
sur iOS, il utilisera MPNowPlayingInfoCenter
- Ajoutez des métas à l’intérieur de votre 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
),
);
- ouvrir avec
showNotification: true
_player.open(audio, showNotification: true)
Avis personnalisé
Icône personnalisée (Android uniquement)
Par nom de ressource
Assurez-vous d’avoir ajouté ces icônes dans votre android/res/drawable
!!! pas sur les actifs flutter !!!!
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"),
)
Et n’oubliez pas de dire à proguard de garder ces ressources pour le mode de publication
(partie Conservation des ressources)
<?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"/>
Par manifeste
-
Ajoutez votre icône dans votre Android
res
dossier (android/app/src/main/res) -
Référencez cette icône dans votre AndroidManifest (android/app/src/main/AndroidManifest.xml)
<meta-data
android:name="assets.audio.player.notification.icon"
android:resource="@drawable/ic_music_custom"/>
Vous pouvez également modifier les icônes d’actions
<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"/>
Gérer le clic de notification (Android)
Ajouter dans principal
AssetsAudioPlayer.setupNotificationsOpenAction((notification) {
//custom action
return true; //true : handled, does not notify others listeners
//false : enable others listeners to handle it
});
Ensuite, si vous voulez une action personnalisée sur le widget
AssetsAudioPlayer.addNotificationOpenAction((notification) {
//custom action
return false; //true : handled, does not notify others listeners
//false : enable others listeners to handle it
});
Actions personnalisées
Vous pouvez activer/désactiver une action de notification
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");
}
)
)
Mettre à jour les métas/contenus de notification de l’audio
Après votre création audio, appelez simplement
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
),
);
Actions Bluetooth
Vous devez activer la notification pour les faire fonctionner
Commandes à distance disponibles :
- Jouer pause
- Prochain
- Précédent
- Arrêt
Stratégie HeadPhone
(Seulement pour Android pour l’instant)
lors de l’ouverture d’une chanson/playlist, ajouter une stratégie
assetsAudioPlayer.open(
...
headPhoneStrategy: HeadPhoneStrategy.pauseOnUnplug,
//headPhoneStrategy: HeadPhoneStrategy.none, //default
//headPhoneStrategy: HeadPhoneStrategy.pauseOnUnplugPlayOnPlug,
)
Si vous souhaitez également le faire fonctionner sur Bluetooth, vous devrez ajouter l’autorisation BLUETOOTH dans votre AndroidManifest.xml.
<uses-permission android:name="android.permission.BLUETOOTH" />
Vous pouvez créer un nouveau AssetsAudioPlayer en utilisant AssetsAudioPlayer.newPlayer(), qui jouera des chansons dans un lecteur multimédia natif différent
Cela permettra de jouer deux chansons simultanément
Vous pouvez avoir autant de joueurs que vous le souhaitez !
///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")
);
Chaque joueur a un unique généré id
vous pouvez les récupérer ou les créer manuellement à l’aide de
final player = AssetsAudioPlayer.withId(id: "MY_UNIQUE_ID");
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);
Widget audio
Si vous voulez une façon plus flottante de lire de l’audio, essayez le AudioWidget
!
//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
},
);
}
Comment 🛑 arrêter 🛑 l’AudioWidget ?
Supprimez simplement l’Audio de l’arborescence ! Ou tout simplement garder play: false
🎧 Auditeurs
Tous les écouteurs exposent les flux à l’aide de RxDart, AssetsAudioPlayer expose certains écouteurs en tant que ValueObservable (Observable qui fournit un accès synchrone au dernier élément émis) ;
🎵 Chanson actuelle
//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;
})
⌛ Durée de la chanson actuelle
//Listen to the current playing song
final duration = assetsAudioPlayer.current.value.duration;
⏳ Position actuelle (en secondes)
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());
}),
ou utilisez un PlayerBuilder !
PlayerBuilder.currentPosition(
player: _assetsAudioPlayer,
builder: (context, duration) {
return Text(duration.toString());
}
)
ou l’extension Player Builder
_assetsAudioPlayer.builderCurrentPosition(
builder: (context, duration) {
return Text(duration.toString());
}
)
▶ En cours de lecture
observable booléen représentant l’état de lecture actuel du lecteur multimédia
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");
}),
ou utilisez un PlayerBuilder !
PlayerBuilder.isPlaying(
player: _assetsAudioPlayer,
builder: (context, isPlaying) {
return Text(isPlaying ? "Pause" : "Play");
}
)
ou l’extension Player Builder
_assetsAudioPlayer.builderIsPlaying(
builder: (context, isPlaying) {
return Text(isPlaying ? "Pause" : "Play");
}
)
🔊 Volume
Modifier le volume (entre 0,0 et 1,0)
assetsAudioPlayer.setVolume(0.5);
Le lecteur multimédia peut suivre le « mode volume » du système (vibreur, silencieux, normal). Réglez simplement le respectSilentMode
paramètre facultatif comme true
_player.open(PLAYABLE, respectSilentMode: true);
Écoutez le volume
return StreamBuilder(
stream: assetsAudioPlayer.volume,
builder: (context, asyncSnapshot) {
final double volume = asyncSnapshot.data;
return Text("volume : $volume");
}),
ou utilisez un PlayerBuilder !
PlayerBuilder.volume(
player: _assetsAudioPlayer,
builder: (context, volume) {
return Text("volume : $volume");
}
)
✋ Terminé
Appelé lorsque la chanson en cours a fini de jouer,
il donne la lecture audio qui vient de se terminer
assetsAudioPlayer.playlistAudioFinished //ValueObservable<Playing>
assetsAudioPlayer.playlistAudioFinished.listen((Playing playing){
})
Appelé lorsque la liste de lecture complète a fini de jouer
assetsAudioPlayer.playlistFinished //ValueObservable<bool>
assetsAudioPlayer.playlistFinished.listen((finished){
})
🔁 Boucle
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
🏃 Vitesse de lecture
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);
🎙️ Emplacement
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);
Par défaut, en cas d’erreur de lecture, il arrête l’audio
MAIS vous pouvez ajouter un comportement personnalisé
_player.onErrorDo = (handler){
handler.player.stop();
};
Ouvrir un autre fichier audio
_player.onErrorDo = (handler){
handler.player.open(ANOTHER_AUDIO);
};
Essayez d’ouvrir à nouveau sur la même position
_player.onErrorDo = (handler){
handler.player.open(
handler.playlist.copyWith(
startIndex: handler.playlistIndex
),
seek: handler.currentPosition
);
};
Android n’autorise que les appels HTTPS, vous aurez une erreur si vous utilisez HTTP, n’oubliez pas d’ajouter l’autorisation INTERNET et de voir usesCleartextTraffic="true"
dans ton AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest ...>
<uses-permission android:name="android.permission.INTERNET" />
<application
...
android:usesCleartextTraffic="true"
...>
...
</application>
</manifest>
iOS n’autorise que les appels HTTPS, vous aurez une erreur si vous utilisez HTTP, n’oubliez pas de modifier votre info.plist Et mettre NSAppTransportSecurity
à NSAllowsArbitraryLoads
<key>NSAppTransportSecurity</key>
<dict>
<key>NSAllowsArbitraryLoads</key>
<true/>
</dict>
Pour activer les appels http sur macOs, vous devez ajouter des capacités d’appels d’entrée/sortie dans 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/>
et dans votre
Runner/DebugProfile.entitlements
ajouter
<key>com.apple.security.network.client</key>
<true/>
Complet Runner/DebugProfile.entitlements
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "
<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>
Toutes les musiques utilisées dans les échantillons proviennent de
GitHub
Voir Github