Playing same audio on two players simultaneously using just_audio and just_audio_background - flutter

I am working on an app that plays audiobooks, and when you click a book in your list a full window player will start playing the book, however when you close/minimize it, I want a miniplayer to show right about the navbar in the bottom. This player has to continue playing from where the first player "stopped" until the user decides to pause.
Im unsure if this can be achieved without having to have both play the audio at the same time? Reason is that when the Fullscreen is closed, player.Dispose is called.
I currently have a function which saves the position of the player and stores it in shared pref, it however cuts the seconds of, so even if I called that in the miniplayer, it wouldnt continue from the same position.
Im new to flutter/dart btw, with only a few months experience. Thanks in advance

You should use a single player and then have two player "widgets" displaying the state of that same player. That way, you don't need to try to stop and start the player - the player can continue playing the whole time while the widgets are the only things changing.
If you're a beginner, the simplest way to define a single player that can be referenced from everywhere is to define it in a global variable, outside of any class declarations (for something more advanced, read about the service locator pattern):
final player = AudioPlayer();
Then let's say you have two widgets to view the state of the same player: FullPlayerWidget and MiniPlayerWidget. They can both reference the same player instance defined above.
Finally, your logic error is that you are calling dispose when minimising the full player widget. You shouldn't do that unless you want the audiobook to stop playing permanently. You don't want it to stop permanently, and you don't even want it to stop at all!
Actually, the only thing you want to happen when minimising is a visual thing. You want to hide the full widget and display the mini widget. But on the audio side, you want the player itself to be unaffected, continuing to play audio as if nothing had happened. Therefore, in this event you should in fact not call any methods on the player.
The best thing you can do as a beginner is to study lots of examples. E.g. podcastproject (although its dependencies are a bit out of date now).

Related

how to watch a provider without destroying another

In my game, I've got a soundProvider = Provider<MySoundClass> so various Widgets can command changes to sound. It stores long-lived audio resources. I also have a gameStateProvider = ChangeNotifierProvider<GameState> holding the game's state.
I'd like soundProvider to watch gameStateProvider, so that e.g. when the game is won, soundProvider can change from playing normal music to playing victory music.
But doing so would trigger a recreation of soundProvider's underlying MySoundClass when gameStateProvider notified it, which would leak the long-lived audio resources left lying around in the discarded MySoundClass.
How should I structure this to prevent the leak but play victory music? Should I use ref.listen(gameStateProvider) callbacks within soundProvider, instead of ref.watch, to play victory music? Or should I store the long-held audio resources in a third provider which soundProvider watches? The former seems a little difficult to manage and the latter seems a little too boilerplate.

Flutter Implementing pause and play..... Streaming Music

I've tried multiple flutter plug-ins to stream and play and pause music but as of currently, I haven't yet figured out a simple way to implement play and pause, whilst having the ability to avoid music overlapping, I want so that when the current song is playing, if I were to press play on new music track, the current song playing will stop and play the newly pressed song. I've tried flutter_sound, audio player, audio file player, and flute music player but I can't seem to figure out how to do this.
If it is possible either using one of these or a new plug-in, is there a way to implement what I have just described.
The library you seek is more of a multi-track player than a player. Which does not currently exists AFAIK.
The simplest way is to act according to the status of the tracks (which should be given by the player).
Roughly, what I suggest: have something that keeps the status (e.g. paused, playing, completed) of each track. (e.g. List of Tracks) When you press play on track 2 or track 1 finishes playing, you set to 'completed' (or as you wish) the track 1 and set to 'playing' the track 2.
Have a listener on the status of the current track and voila (for autoplay). When the track completes, notify the listener to call a function to start the next one on your list. When you press another track, set to 'completed' the current track and to 'playing' the track you pressed, then notify listeners.
Any library letting you know the status of a track is good enough for your purpose.

Is there a way of changing playback position using AudioKit / AKPlayer?

Been scratching my head with this one, to no avail.
Am just trying to find out how to instantly change the current playback position when using the AKAudioPlayer provided by AudioKit.
player.playhead is read-only, so cant be changed.
changing player.startTime whilst the player is already playing seems to change the playback position in terms of the reported .playhead position but the actual audio being played does not change position - am I missing something here?
Obviously I can stop audio and restart at new position but a several second expensive CPU gap is not desirable for a a simple mp3 / wav file player!
Any ideas?
We've added a new player called AKPlayer which will also allow scanning through the file. The player will stream from disk by default. This player is designed to fix some of the shortcomings in AKAudioPlayer.
OK Aurelius pointed me in the right direction of a new class introduced a couple weeks ago called AKClipPlayer
Like the standard Apple AV class you can now set the .currentTime property (in seconds) (the AKAudioPlayer class did not allow this) - it seems to stop playback doing this though so don't forget to .play() your node right after - there is no glitch or pause, is seamless on an old iPhone6S

AVAudioPlayerNode - Get Player State?

In an iOS-project I am using the AVAudioPlayerNode in conjunction with the AVAudioEngine and an AVAudioUnitTimePitch. Everything works peachy. However, I was wondering if there is a way to figure out what the current player's state (e.g. isPlaying, isPaused) or at least the playback position is.
While AVAudioPlayer at least allows you to get the currentTime-parameter, I could not yet figure out how to get that information with AVAudioPlayerNode. I tried playing around with the nodeTimeForPlayerTime and playerTimeForNodeTime methods described in the swift documentation but I couldn't make any progress.
Any help would be highly appreciated.
Since the AVAudioPlayerNode is designed as an audio stream, it doesn't necessarily keep track of the time within a particular file. However, the AVAudioPlayerNode does keep a running time of how long its been playing all audio. This timer doesn't reset with each file, in order to change it, you must explicitly tell it where you want to start counting from.
So to find the current time the player has been playing you must do the following:
player.lastRenderTime.sampleTime / file.fileFormat.sampleRate
Now in order to get the timer to reset after each file, you must explicitly reset the players current time. To do this use the player.playAtTime: function.
If you would like an example, check one out here: https://github.com/danielmj/AEAudioPlayer

Is it possible to play a video on iPhone and have a subtitles synchronized with it show up?

I want to add a "subtitles" to a video played in an iPhone app. I don't want those subtitles encoded into the video itself - ideally I'd love to have a view showing the video (with pause, play, volume and such standard controls) together with a view displaying the text that changes together with movie time changing.
If I drawn that, it's something like this,
So, basicly, I would need a way to get a method called when movie is playing, and then synchronize the text displayed on the label with the movie timing.
Anyone used a solution that was able to do it?
I've recently done something that syncs graphics to times in an audio track. The way I did it was by using the currentPlaybackTime property of the MPMediaPlayback interface (which the MoviePlayer controller should also conform to). This returns the seconds elapsed in the media, in a double (typedef'ed as NSTimeInterval). The actual synchronisation in my app was not done in notifications, as I couldn't find any resembling a "tick", but instead I created a timer, calling a function queried the currentPlaybackTime, and updated the graphics based on this.
In terms of your implementation, I would assume you have some kind of system for associating label text (subtitles) with a particular time. You could then compare the text's time range with the time returned from currentPlaybackTime to find the correct text to display.