I want to play audio from a stream. I have used Just Audio for this. I want a progress bar like Audio Video Progress bar also play the audio in the background using Audio Service.
I have used the examples for all of them and they are working individually but I cannot concatenate them. would you please help with an example of how can I do it?
The example from audio_service plugin contains how to use audio_service along with just_audio. (combining 2 packages done)
Below is the mentioned SeekBar
given in the example of the audio_service plugin.
// A seek bar.
StreamBuilder<MediaState>(
stream: _mediaStateStream,
builder: (context, snapshot) {
final mediaState = snapshot.data;
return SeekBar(
duration:
mediaState?.mediaItem?.duration ?? Duration.zero,
position: mediaState?.position ?? Duration.zero,
onChangeEnd: (newPosition) {
AudioService.seekTo(newPosition);
},
);
},
),
...
class SeekBar extends StatefulWidget {
final Duration duration;
final Duration position;
final ValueChanged<Duration>? onChanged;
final ValueChanged<Duration>? onChangeEnd;
SeekBar({
required this.duration,
required this.position,
this.onChanged,
this.onChangeEnd,
});
@override
_SeekBarState createState() => _SeekBarState();
}
// more code in the plugin example
Now from the above code, as you can see the example uses custom-designed SeekBar
(which uses slider).
Instead of the custom slider, you can possibly use the plugin widget you wish. ProgressBar
in your case.
StreamBuilder<MediaState>(
stream: _mediaStateStream,
builder: (context, snapshot) {
final mediaState = snapshot.data;
return ProgressBar(
total:
mediaState?.mediaItem?.duration ?? Duration.zero,
progress: mediaState?.position ?? Duration.zero,
onSeek: (newPosition) {
AudioService.seekTo(newPosition);
},
);
},
),
This is a change for the above SeekBar
with ProgressBar
.
(Combining 3rd package done)
Note: For the buffered
. You can get the bufferedPosition
from the audio_service PlaybackStateStream
.
Edit:
The below is how I used it to add bufferedPosition
.
(I changed the MediaState class, corresponding state getter a bit to achieve it)
StreamBuilder<MediaState>(
stream: _mediaStateStream,
builder: (context, snapshot) {
final mediaState = snapshot.data;
return ProgressBar(
total:
mediaState?.mediaItem?.duration ?? Duration.zero,
progress: mediaState?.position ?? Duration.zero,
buffered: mediaState?.playbackState?
.bufferedPosition ?? Duration.zero,
onSeek: (newPosition) {
AudioService.seekTo(newPosition);
},
);
},
),
...
Stream<MediaState> get _mediaStateStream =>
Rx.combineLatest3<MediaItem, Duration, PlaybackState, MediaState>(
AudioService.currentMediaItemStream,
AudioService.positionStream,
AudioService.playbackStateStream,
(mediaItem, position, playbackState) =>
MediaState(mediaItem, position, playbackState));
...
class MediaState {
final MediaItem mediaItem;
final Duration position;
final PlaybackState playbackState;
MediaState(this.mediaItem, this.position, this.playbackState);
}