Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

New queue playback solution #13

Open
wants to merge 11 commits into
base: main
Choose a base branch
from
Open

Conversation

Zensonaton
Copy link

Closes #3. All the details are explained in the #3.

Please thoroughly check the PR before merging this, there is a possibility I've made something wacky during conflict resolving :D

@Zensonaton Zensonaton marked this pull request as draft April 19, 2024 04:35
@Chaphasilor
Copy link
Contributor

If we were to go with an implementation that feeds the next X tracks, it would make sense to make that number dynamic depending on the cache size/duration.
Although it might be that media-kit will only pre-fetch the very next track anyway, in which case one track ahead would be enough.

@Pato05 Pato05 self-assigned this Apr 20, 2024
@Pato05 Pato05 self-requested a review April 20, 2024 15:46
@Pato05 Pato05 added the enhancement New feature or request label Apr 20, 2024
@Pato05
Copy link
Owner

Pato05 commented Apr 20, 2024

Thank you for this, I will take a more thorough look in the next days

@Zensonaton
Copy link
Author

Hello! I'm kinda curious whether there is progress with this PR.

No rush, just curious 👀

@Pato05
Copy link
Owner

Pato05 commented May 2, 2024

Hello! I'm kinda curious whether there is progress with this PR.

No rush, just curious 👀

There hasn't been any, I'm currently very busy with school exams.. I'll try to check this if I have any free time.

Anyways, my idea is that we could feed the next 2 or 3 tracks to media-kit so that we can prefetch them (maybe implement this under a method so that we can reuse the code?). This should happen every time the track is changed.

@Zensonaton
Copy link
Author

Zensonaton commented May 2, 2024

I'm currently very busy with school exams, ...

Oh, I really hope that my comment didn't look like I was rushing you or anything, sorry 'bout that. I wish you luck with the exams. 🤞

Speaking of your solution about feeding player next N media, that can be implemented pretty much easily in my fork, so I might try that. The only thing that I need to keep in mind is the fact that MK's player should never be shuffled, otherwise things might get really badly.

@Pato05
Copy link
Owner

Pato05 commented May 5, 2024

Oh, I really hope that my comment didn't look like I was rushing you or anything, sorry 'bout that.

Oh, don't worry! I didn't feel rushed at all, probably my comment sounded way too harsh, sorry.

@Zensonaton Zensonaton marked this pull request as ready for review July 4, 2024 10:42
@Zensonaton
Copy link
Author

No idea why I marked this PR as draft, lol :D

@Chaphasilor
Copy link
Contributor

So you're not planning to implenent the pre-fetching for now? :)

@Zensonaton
Copy link
Author

Zensonaton commented Jul 6, 2024

So you're not planning to implenent the pre-fetching for now? :)

Tried to do so- I'm not 100% sure how to do that without any disgusting hacks.

rename some variables,
make some code reusable (so that it looks a bit cleaner)
fix the indexes (which just_audio already corrects for them to be according to the shuffled indices)
keep [_shuffleOrder] updated in removeRange and move requests
@Pato05
Copy link
Owner

Pato05 commented Jul 15, 2024

@Zensonaton I want to congratulate you for this implementation (which to my surprise worked almost perfectly, which is unusual since this is kind of hacky). I fixed some things (as you can see by my commits), and I also merged it to the latest changes. I'd just wait to implement prefetching (by including the next X items in the playlist, as I said), then we can merge this PR.

@Zensonaton
Copy link
Author

Glad to hear this! Happy to see the changes made.

prefetching (by including the next X items in the playlist, as I said)

There's a bit of a problem with that approach; my code subscribes to MK's completed event stream, which is supposed to fire only when the audio source (like our playlist) ends. Currently, MK's player uses a "playlist" with just one track, so the completed event gets fired as expected. However, if we introduce multiple tracks to the playlist, that completed event won't fire.

While it's possible to subscribe to the media index and other events, however, that'll require more wacky-hacky code :D

@Pato05
Copy link
Owner

Pato05 commented Jul 16, 2024

Yeah.. I overlooked the issue indeed: added to what you already said (which can easily be fixed by listening to whenever the current entry changes, thus regenerating the playlist), --prefetch-playlist expects a static playlist, and having a dynamic one with next and previous X elements will not satisfy this requirement.

I might test it anyways, and check if it seems to work. If it does, great, we can take this approach, otherwise I'll make it so that enabling --prefetch-playlist will disable the hacks in this PR.

…ting, etc.

Fix wrong indecies being used with enabled shuffle.
Fix issues with loop mode.
Fix wrong media being played on loop.
Use `await _player.method` instead of `_player.method.then(...)`.
More loggers.
@Zensonaton
Copy link
Author

Zensonaton commented Aug 10, 2024

It seems like I've successfully implemented the prefetching. As it turned out, it's been more easier than I've thought it would be :D
I'm not sure if it is robust, so I hope that someone is going to try whether it is working properly or not.
To check my fork, replace just_audio_media_kit in pubspec.yaml to this:

just_audio_media_kit:
  git:
    url: https://github.com/Zensonaton/just_audio_media_kit.git
    ref: "529af19"

and set prefetchPlaylist to true like this:

JustAudioMediaKit.title = "My Spotify competitor app";

JustAudioMediaKit.prefetchPlaylist = true;
JustAudioMediaKit.ensureInitialized();

Not only that, new commit introduced a lot of QoL-changes to the just_audio_media_kit's code, like documentation, clean-ups, etc.

Also... It seems like @Pato05's "fix a few things" commit broke my entire shuffle implementation. I've had a lot of time trying to understand why my music player wasn't working properly, lol :D
Those commits fixed the issue, however, I've had to get rid of the implementation that uses _entryIndex getter. Please look at the docs on _currentIndex and _shuffledIndex for explanation.

@Chaphasilor
Copy link
Contributor

@Zensonaton great to hear! I'll try to take a look at this tomorrow by plugging it into Finamp. Shuffle was broken on desktop for us anyway, but I'll see what works and what doesn't! Please remind me if I forget!

@Zensonaton
Copy link
Author

@Chaphasilor , hope that'll work properly for you.

I'm curious, why was the shuffle broken in your app?

@Pato05
Copy link
Owner

Pato05 commented Aug 11, 2024

It seems like @Pato05's "fix a few things" commit broke my entire shuffle implementation. I've had a lot of time trying to understand why my music player wasn't working properly, lol :D

Could you elaborate on that? That commit pretty much had the effect of setting _currentIndex instead of _shuffledIndex in the PlaybackEventMessage which seemed to be what just_audio expected, as the highlighted entry in the example app would be correct lile this...

Also, about _entryIndex, it was just a replacement for _shuffledIndex, basically it would return the real index based on _currentIndex instead of having to set it everytime _currentIndex changed.

Would you mind telling me how you tested the package? I have personally used the example app of just_audio, which showcases every function including shuffling.

Copy link
Owner

@Pato05 Pato05 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

About this commit, as I've stated in my previous comment:

--prefetch-playlist expects a static playlist, and having a dynamic one with next and previous X elements will not satisfy this requirement

Did you test this implementation thoroughly? Like, did you see if any data gets discarded even if not needed?

registerWith();
MediaKit.ensureInitialized(libmpv: libmpv);
}
(UniversalPlatform.isMacOS && macOS))) return;
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This shouldn't be done. It should be the user's choice whether to enable just_audio_media_kit to be used instead of the default plugin on macOS.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm a bit confused about this one... I've cleaned my code, so brackets won't confuse you:

if (!(
  (UniversalPlatform.isLinux && linux) ||
  (UniversalPlatform.isWindows && windows) ||
  (UniversalPlatform.isAndroid && android) ||
  (UniversalPlatform.isIOS && iOS) ||
  (UniversalPlatform.isMacOS && macOS)
)) return;

I haven't removed the isMacOS check, it is still present in my code. Or am I missing something here?


Basically, my code does the exact same thing as your did, but instead of this:

if (condition) {
  do_something();
}

I've changed it to this:

if (!condition) return;

do_something();

@Zensonaton
Copy link
Author

Thank you @Pato05 for checking my commits.

Could you elaborate on that?

My music app completely broke after commit of yours: basically, I've had an issue, where user plays song A, but my app starts playing completely random song of a playlist. Basically, my app calls this method to start playing music:

await player.setAudioSource(
  ConcatenatingAudioSource(...),
  initialIndex: selectedSongIndex, // finds index of a selected audio via .indexOf(...)
);

I was really confused what went wrong. Decided to try the same thing on Android build of my app which uses non-modified just_audio, but it was working as intended.
Decided to check my fork, and my reaction was "AHA! Found ya!" or something like that. After checking the commit that you've made, I've noticed that you were feeding just_audio with real index, instead of shuffled one. Because of that, not only app was playing the wrong audio, the UI was also showing the wrong track.

Would you mind telling me how you tested the package?

I've been testing this package on my own app that uses just_audio_media_kit on Windows, and just_audio on Android. My fork's goal was to make just_audio_media_kit's behavior same as with "vanilla" just_audio.
Being honest, I've haven't thought about testing that package with just_audio's example app. Is this is the way you've been testing it?

(about prefetching, --prefetch-playlist expects a static playlist, ...)

Unfortunately, I have missed that "expects a static playlist" part. Ouch.
Want to note that my naive implementation of pre-fetching seems to be working as intended. Currently, instead of feeding playlist with only 1 media, just_audio_media_kit now feeds 2 (or more) medias to the MK's player.
Surprisingly, even tho MK's player gets a "new" playlist every time it jumps on a different track, pre-fetching seems to be working properly: checked via mitmproxy, and saw that it downloaded audio A, and only then audio B. After user skips to next media, player starts to download audio C, as intended. I was thinking that it would re-download audio B, however, it seems like MK's player is smart enough.

Did you test this implementation thoroughly?

No, I did not. Tested the simple cases, with and without shuffle enabled, checked whether media gets re-downloaded where it is not supposed to.

Did you see if any data gets discarded even if not needed?

I'm not sure if there is a way to tell just_audio to cancel/discard the media, so there isn't such a thing.

P.S.: I really hope that this comment doesn't sound harsh or anything.

@Zensonaton
Copy link
Author

Decided to try my fork with just_audio's example app (example_playlist.dart), and it's working properly.

@Zensonaton
Copy link
Author

Any progress with that? 👀

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Shuffle completely breaks the playlist's indexies
3 participants