230 lines
7.6 KiB
Markdown
230 lines
7.6 KiB
Markdown
# just_audio
|
|
|
|
This Flutter plugin plays audio from URLs, files, assets, DASH/HLS streams and playlists. Furthermore, it can clip, concatenate, loop, shuffle and compose audio into complex arrangements with gapless playback. This plugin can be used with [audio_service](https://pub.dev/packages/audio_service) to play audio in the background and control playback from the lock screen, Android notifications, the iOS Control Center, and headset buttons.
|
|
|
|
## Features
|
|
|
|
| Feature | Android | iOS | MacOS | Web |
|
|
| ------- | :-------: | :-----: | :-----: | :-----: |
|
|
| read from URL | ✅ | ✅ | ✅ | ✅ |
|
|
| read from file | ✅ | ✅ | ✅ | |
|
|
| read from asset | ✅ | ✅ | ✅ | |
|
|
| request headers | ✅ | ✅ | ✅ | |
|
|
| DASH | ✅ | | | |
|
|
| HLS | ✅ | ✅ | ✅ | |
|
|
| buffer status/position | ✅ | ✅ | ✅ | ✅ |
|
|
| play/pause/seek | ✅ | ✅ | ✅ | ✅ |
|
|
| set volume | ✅ | ✅ | ✅ | ✅ |
|
|
| set speed | ✅ | ✅ | ✅ | ✅ |
|
|
| clip audio | ✅ | ✅ | ✅ | ✅ |
|
|
| playlists | ✅ | ✅ | ✅ | ✅ |
|
|
| looping | ✅ | ✅ | ✅ | ✅ |
|
|
| shuffle | ✅ | ✅ | ✅ | ✅ |
|
|
| compose audio | ✅ | ✅ | ✅ | ✅ |
|
|
| gapless playback | ✅ | ✅ | ✅ | |
|
|
| report player errors | ✅ | ✅ | ✅ | ✅ |
|
|
|
|
Please consider reporting any bugs you encounter [here](https://github.com/ryanheise/just_audio/issues) or submitting pull requests [here](https://github.com/ryanheise/just_audio/pulls).
|
|
|
|
## Example
|
|
|
|
![just_audio](https://user-images.githubusercontent.com/19899190/89558581-bf369080-d857-11ea-9376-3a5055284bab.png)
|
|
|
|
Initialisation:
|
|
|
|
```dart
|
|
final player = AudioPlayer();
|
|
var duration = await player.setUrl('https://foo.com/bar.mp3');
|
|
var duration = await player.setFilePath('/path/to/file.mp3');
|
|
var duration = await player.setAsset('path/to/asset.mp3');
|
|
```
|
|
|
|
Standard controls:
|
|
|
|
```dart
|
|
player.play(); // Usually you don't want to wait for playback to finish.
|
|
await player.seek(Duration(seconds: 10));
|
|
await player.pause();
|
|
```
|
|
|
|
Clipping audio:
|
|
|
|
```dart
|
|
await player.setClip(start: Duration(seconds: 10), end: Duration(seconds: 20));
|
|
await player.play(); // Waits until the clip has finished playing
|
|
```
|
|
Adjusting audio:
|
|
|
|
```dart
|
|
await player.setSpeed(2.0); // Double speed
|
|
await player.setVolume(0.5); // Halve volume
|
|
```
|
|
|
|
Gapless playlists:
|
|
|
|
```dart
|
|
await player.load(
|
|
ConcatenatingAudioSource(
|
|
children: [
|
|
AudioSource.uri(Uri.parse("https://example.com/track1.mp3")),
|
|
AudioSource.uri(Uri.parse("https://example.com/track2.mp3")),
|
|
AudioSource.uri(Uri.parse("https://example.com/track3.mp3")),
|
|
],
|
|
),
|
|
);
|
|
player.seekToNext();
|
|
player.seekToPrevious();
|
|
// Jump to the beginning of track3.mp3.
|
|
player.seek(Duration(milliseconds: 0), index: 2);
|
|
```
|
|
|
|
Looping and shuffling:
|
|
|
|
```dart
|
|
player.setLoopMode(LoopMode.off); // no looping (default)
|
|
player.setLoopMode(LoopMode.all); // loop playlist
|
|
player.setLoopMode(LoopMode.one); // loop current item
|
|
player.setShuffleModeEnabled(true); // shuffle except for current item
|
|
```
|
|
|
|
Composing audio sources:
|
|
|
|
```dart
|
|
player.load(
|
|
// Loop child 4 times
|
|
LoopingAudioSource(
|
|
count: 4,
|
|
// Play children one after the other
|
|
child: ConcatenatingAudioSource(
|
|
children: [
|
|
// Play a regular media file
|
|
ProgressiveAudioSource(Uri.parse("https://example.com/foo.mp3")),
|
|
// Play a DASH stream
|
|
DashAudioSource(Uri.parse("https://example.com/audio.mdp")),
|
|
// Play an HLS stream
|
|
HlsAudioSource(Uri.parse("https://example.com/audio.m3u8")),
|
|
// Play a segment of the child
|
|
ClippingAudioSource(
|
|
child: ProgressiveAudioSource(Uri.parse("https://w.xyz/p.mp3")),
|
|
start: Duration(seconds: 25),
|
|
end: Duration(seconds: 30),
|
|
),
|
|
],
|
|
),
|
|
),
|
|
);
|
|
```
|
|
|
|
Releasing resources:
|
|
|
|
```dart
|
|
await player.dispose();
|
|
```
|
|
|
|
Catching player errors:
|
|
|
|
```dart
|
|
try {
|
|
await player.setUrl("https://s3.amazonaws.com/404-file.mp3");
|
|
} catch (e) {
|
|
print("Error: $e");
|
|
}
|
|
```
|
|
|
|
Listening to state changes:
|
|
|
|
```dart
|
|
player.playerStateStream.listen((state) {
|
|
if (state.playing) ... else ...
|
|
switch (state.processingState) {
|
|
case AudioPlaybackState.none: ...
|
|
case AudioPlaybackState.loading: ...
|
|
case AudioPlaybackState.buffering: ...
|
|
case AudioPlaybackState.ready: ...
|
|
case AudioPlaybackState.completed: ...
|
|
}
|
|
});
|
|
|
|
// See also:
|
|
// - durationStream
|
|
// - positionStream
|
|
// - bufferedPositionStream
|
|
// - sequenceStateStream
|
|
// - sequenceStream
|
|
// - currentIndexStream
|
|
// - icyMetadataStream
|
|
// - playingStream
|
|
// - processingStateStream
|
|
// - loopModeStream
|
|
// - shuffleModeEnabledStream
|
|
// - volumeStream
|
|
// - speedStream
|
|
// - playbackEventStream
|
|
```
|
|
|
|
## Platform specific configuration
|
|
|
|
### Android
|
|
|
|
If you wish to connect to non-HTTPS URLS, add the following attribute to the `application` element of your `AndroidManifest.xml` file:
|
|
|
|
```xml
|
|
<application ... android:usesCleartextTraffic="true">
|
|
```
|
|
|
|
If you want to set the Android AudioAttributes, use the following method with the desired choice of parameters:
|
|
|
|
```dart
|
|
player.setAndroidAudioAttributes(AndroidAudioAttributes(
|
|
contentType: AndroidAudioContentType.music,
|
|
flags: AndroidAudioAttributes.FLAG_AUDIBILITY_ENFORCED,
|
|
usage: AndroidAudioUsage.media,
|
|
allowedCapturePolicy: AndroidAudioAllowedCapturePolicy.all,
|
|
));
|
|
```
|
|
|
|
If you need access to the player's AudioSession ID, you can listen to `AudioPlayer.androidAudioSessionIdStream`. Note that the AudioSession ID will change whenever you set new AudioAttributes.
|
|
|
|
### iOS
|
|
|
|
If you wish to connect to non-HTTPS URLS, add the following to your `Info.plist` file:
|
|
|
|
```xml
|
|
<key>NSAppTransportSecurity</key>
|
|
<dict>
|
|
<key>NSAllowsArbitraryLoads</key>
|
|
<true/>
|
|
<key>NSAllowsArbitraryLoadsForMedia</key>
|
|
<true/>
|
|
</dict>
|
|
```
|
|
|
|
By default, iOS will mute your app's audio when your phone is switched to silent mode. Depending on the requirements of your app, you can change the default audio session category using `AudioPlayer.setIosCategory`. For example, if you are writing a media app, Apple recommends that you set the category to `AVAudioSessionCategoryPlayback`, which you can achieve by adding the following code to your app's initialisation:
|
|
|
|
```dart
|
|
AudioPlayer.setIosCategory(IosCategory.playback);
|
|
```
|
|
|
|
Note: If your app uses a number of different audio plugins in combination, e.g. for audio recording, or text to speech, or background audio, it is possible that those plugins may internally override the setting you choose here. You may consider asking the developer of each other plugin you use to provide a similar method so that you can configure the same audio session category universally across all plugins you use.
|
|
|
|
### MacOS
|
|
|
|
To allow your MacOS application to access audio files on the Internet, add the following to your `DebugProfile.entitlements` and `Release.entitlements` files:
|
|
|
|
```xml
|
|
<key>com.apple.security.network.client</key>
|
|
<true/>
|
|
```
|
|
|
|
If you wish to connect to non-HTTPS URLS, add the following to your `Info.plist` file:
|
|
|
|
```xml
|
|
<key>NSAppTransportSecurity</key>
|
|
<dict>
|
|
<key>NSAllowsArbitraryLoads</key>
|
|
<true/>
|
|
<key>NSAllowsArbitraryLoadsForMedia</key>
|
|
<true/>
|
|
</dict>
|
|
```
|