How to get audio duration with audio_service? - flutter

I am using audio_service to play mp3 file. I am following example_playlist as AudioPlayerHander. My code is exactly same as example. But I use dependency injection (get_It) rather than a global variable. And I replace with broadcast media item changes in _init() method to get duration.
Rx.combineLatest5<int?, List<MediaItem>, bool, List<int>?, Duration?,
MediaItem?>(
_player.currentIndexStream,
queue,
_player.shuffleModeEnabledStream,
_player.shuffleIndicesStream,
_player.durationStream, // <- add listening to durationStream here
(index, queue, shuffleModeEnabled, shuffleIndices, duration) {
if (kDebugMode) {
print("${mediaItem.value?.title} - $duration");
}
final queueIndex =
getQueueIndex(index, shuffleModeEnabled, shuffleIndices);
return (queueIndex != null && queueIndex < queue.length)
? queue[queueIndex].copyWith(
duration: duration) // <- sink mediaItem provided with duration
: null;
}).whereType<MediaItem>().distinct().listen(mediaItem.add);
But I did not get the duration correctly.
For playlist 1, it is upload in _init() method and first track's duration is showing correctly but if you click second track, duration is still showing first track's duration.
I have added Load Play List 2 button and load playlist 2. All track's duration is always zero.
Note: audio is playing and start progress from 0 if duration is zero.
If I added playlist 2 in audio_service's example_playlist, it is showing correctly.
So the only different is using global variable and dependency injection (getIt).
I have added sample Github project audio_service_playlist_test
May I know which path is missing?

Related

How to set audio handler with carousel slider in flutter?

Currently i am working on music app and according to my ui i have to manage audio player with carousel slider.The without carousel slider it is working fine but with carousel slider when click on the shuffle or when onPageChanged called, i used the skipToQueueItem for play particular song with audio player, that time suddenly audioHandler.mediaItem listen continuously called and in every 1 second changed song and slider images because of skipToQueueItem line.I used just audio and audio service package.For privacy i am not sharing the code.But for update carousel slider with audio i used below code.
audioHandler.queue.listen((playlist) async {
if (playlist.isEmpty) {
mediaItemsListNotifier.value = [];
} else {
///Update media items notifier list value
mediaItemsListNotifier.value = playlist;
await audioHandler.updateQueue(playlist);
}
});
audioHandler.mediaItem.listen((mediaItem) async {
int index = audioHandler.queue.value.indexOf(mediaItem!);
currentSliderIndex.value = index >= 0 ? index : 0;
///Main issue using this line
await audioHandle.skipToQueueItem(currentSliderIndex.value);
carouselController.jumpToPage(currentSliderIndex.value);
}

Flutter video_player Duration?

I am using the Flutter video_player package here: https://pub.dev/packages/video_player
How do I get the duration of the video? I can see there is a position property, so I would need that to get the current value in time.
But how do I get the total duration of the video? The video is from a URL.
I am making a custom player so I need these two values.
For getting the Total duration you can use the video controller
VideoPlayerController _controller = VideoPlayerController.network('https://flutter.github.io/assets-for-api-docs/assets/videos/bee.mp4')
..initialize().then((_) {
// Ensure the first frame is shown after the video is initialized, even before the play button has been pressed.
});
Duration durationOfVideo = _controller.value.duration;
You can also directly store the integer instead of duration as below image
You can create a function to calculate the video Dutarion and format it.
getVideoPosition() {
var duration = Duration(milliseconds: videoController.value.position.inMilliseconds.round());
return [duration.inMinutes, duration.inSeconds].map((seg) => seg.remainder(60).toString().padLeft(2, '0')).join(':');
}
After craeate this function, you just need to call it to show the duration.
Ex.:
Text(getVideoPosition())

How can I save the current time stamp for audio progress in flutter

I am creating a podcast app using Just audio.
How can I save the current timestamp, so that the playback will start from the same location the next time the app is opened?
You can listen to events of positionStream method:
audioPlayer.positionStream.listen((event) {
if (event.inMilliseconds != 0) {
var duration = audioPlayer.duration!.inMilliseconds; //get the duration of audio
progress = (event.inMilliseconds / duration)*100 // get the current position in percent
}
});

Stream synthetized audio in real time in flutter

I'm trying to create an app generating a continuos sinewave of various frequency (controlled by the user) and I'm trying to play the data as it's generated in real time.
I'm using just_audio right now to play bytes generated using wave_generator, as follows (snippet from issue):
class BufferAudioSource extends StreamAudioSource {
final Uint8List _buffer;
BufferAudioSource(this._buffer) : super(tag: "Bla");
#override
Future<StreamAudioResponse> request([int? start, int? end]) {
start = start ?? 0;
end = end ?? _buffer.length;
return Future.value(
StreamAudioResponse(
sourceLength: _buffer.length,
contentLength: end - start,
offset: start,
contentType: 'audio/wav',
stream: Stream.value(List<int>.from(_buffer.skip(start).take(end - start))),
),
);
}
}
And I'm using the audio source like this:
StreamAudioSource _source = BufferAudioSource(_data!);
_player.setAudioSource(_source);
_player.play()
Is there a way I could feed the data to the player as soon as I generate it on the fly, using a sinewave generator, so that if the user changes the frequency, the playback will reflect the change as soon as it happens?
I tried looking online and on the repository github but I couldn't find anything.

There is a way to specify the time delay between audio tracks on the same playlist?

I need to set a specific time delay between audio tracks on the playlist. Ex. 10 seconds delay. How could I achieve this?. Thanks in advance
There are two ways:
Create a silent audio track of the desired duration and insert it between each item in your ConcatenatingAudioSource.
Don't use ConcatenatingAudioSource, write your own playlist logic.
An example of the second approach could be:
// Maintain your own playlist position
int index = 0;
// Define your tracks
final tracks = <IndexedAudioSource>[ ... ];
// Auto advance with a delay when the current track completes
player.processingStateStream.listen((state) async {
if (state == ProcessingState.completed && index < tracks.length) {
await Future.delayed(Duration(seconds: 10));
// You might want to check if another skip happened during our sleep
// before we execute this skip.
skipToIndex(index + 1);
}
});
// Make this a method so that you can wire up UI buttons to skip on demand.
Future<void> skipToIndex(int i) {
index = i;
await player.setAudioSource(tracks[index]);
}