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

Buffer duration control? #11

Closed
Chaphasilor opened this issue Apr 7, 2024 · 14 comments
Closed

Buffer duration control? #11

Chaphasilor opened this issue Apr 7, 2024 · 14 comments
Assignees
Labels
enhancement New feature or request

Comments

@Chaphasilor
Copy link
Contributor

Is there any way to control the buffer duration with the media-kit backend? For Android there's AndroidLoadControl.minBufferDuration and AndroidLoadControl.minBufferDuration, and for iOS there's DarwinLoadControl.preferredForwardBufferDuration in just_audio.

It appears like currently the player is using the AndroidLoadControl on Windows, but that could just be a coincidence.
Either way, it seems like the buffer always stops at the end of the current track, and does not pre-fetch the next track, contrary to what happens on the mobile platforms. Setting the buffer duration to 10 minutes should always fetch the next 10 minutes of the current audio source (which is a ConcatenatingAudioSouce in this case), even if the current track is shorter than that.

Is that a limitation of media-kit?

@Pato05
Copy link
Owner

Pato05 commented Apr 7, 2024

No, it's not a limitation, you can edit the buffer size with the JustAudioMediaKit.bufferSize static parameter.

Please check the README: https://github.com/Pato05/just_audio_media_kit?tab=readme-ov-file#plugin-specific-configuration-settings-for-media_kits-player-instance

@Pato05
Copy link
Owner

Pato05 commented Apr 7, 2024

Either way, it seems like the buffer always stops at the end of the current track, and does not pre-fetch the next track

That is true. I wanted to create a proxy server to handle this, but that would be too bloat-y to include in the main plugin, so I'll probably never actually do this. However, feel free to create a new plugin for it!

Actually this might not be necessary as it seems mpv already supports this via the --prefetch-playlist option (see media_kit#200). I'll test for a possible solution in the next days, as today I may not be able to.

@Chaphasilor
Copy link
Contributor Author

So there's no way to set the buffer size based on a duration somehow?

The --prefetch-playlist option actually doesn't seem to solve the issue. It expects a static queue, and only fetches the next track shortly before the current track ends. So it's more like a gapless option?

@Pato05
Copy link
Owner

Pato05 commented Apr 7, 2024

So there's no way to set the buffer size based on a duration somehow?

Not as far as I'm aware...

The --prefetch-playlist option actually doesn't seem to solve the issue. It expects a static queue, and only fetches the next track shortly before the current track ends. So it's more like a gapless option?

depends on the demuxer cache settings [...]. This merely opens the URL of the next playlist entry as soon the current URL is fully read. (source)

According to docs it's kinda similar to what just_audio provides in Android. Though docs also say it's highly experimental, so I may make this available under a flag that is false by default.

Also I'm not really sure how "gapless" would be different than pre-fetching the next track..

I'll implement this anyways (also cause it doesn't hurt to), though, can you try it yourself as to check whether this meets your needs?

@Chaphasilor
Copy link
Contributor Author

I am a bit confused by the part about it not pre-fetching video data. It sounded like it would simply open a connection and fetch the header of the next item, instead of actually loading any media data. I guess we'll have to try it out.

Where would I need to add this option to try things out?

@Pato05
Copy link
Owner

Pato05 commented Apr 7, 2024

It sounded like it would simply open a connection and fetch the header of the next item, instead of actually loading any media data.

You may actually be right, that's why it says "merely", I guess...

Where would I need to add this option to try things out?

You could add it right after _player = Player(...); in mediakit_player.dart, you'd have to call _player.platform.setProperty('prefetch-playlist', 'yes'); or something along these lines.. Check here: media-kit/media-kit#14 (comment).

@Pato05 Pato05 self-assigned this Apr 8, 2024
@Pato05 Pato05 added the enhancement New feature or request label Apr 8, 2024
@Pato05
Copy link
Owner

Pato05 commented Apr 9, 2024

Ok, so I did some testing by using a python HTTP server (from scratch, so that I can check whenever the connection is open), and it seems that --prefetch-playlist just makes the loading a little bit less lazy by starting to load the track moments before it has to be played (see attached video)

Screencast.from.2024-04-09.14-25-14.webm

I don't think increasing the demuxer buffer will actually do anything, as by default it should be about 150MB, and, well, the song doesn't even go close to that...

It's surely better to put the option to use --prefetch-playlist, as it is a little more 'gap-less' this way, though it's not what we ideally want.

@Pato05
Copy link
Owner

Pato05 commented Apr 9, 2024

So there's no way to set the buffer size based on a duration somehow?

I was looking at the mpv docs, and yes, you can specify a duration instead of specifying bytes, with the --cache-secs option. It may make sense to use the AndroidLoadControl.maxBufferDuration option as the value for this option, or just let it be.

If ryanheise/just_audio#1222 gets fixed, I could export the Player instance, so that more options can be set via setProperty, thus allow more freedom on controlling the player without editing just_audio_media_kit's code..

Pato05 added a commit that referenced this issue Apr 9, 2024
@Pato05
Copy link
Owner

Pato05 commented Apr 9, 2024

While testing the new option, it seems that the actual behaviour in media_kit is slightly different (and way closer to what we want in the first place). My example app is just a tweak of the example in just_audio, where I removed the ClippingAudioSource, and basically changed the URL for the third entry to my local HTTP server.

I'll cut to the chase: it started loading the track when there were about 15 minutes left from the podcast, and it didn't only stop when it received the headers, but the entire song was downloaded way before it was required for playback!

prefetch.webm

With that said, this issue can be now closed (feel free to reopen if you find a new solution or feel like this is incomplete).

@Pato05 Pato05 closed this as completed Apr 9, 2024
@Chaphasilor
Copy link
Contributor Author

Sorry for not responding to this, I'm currently sitting on a huge stack of unread notifications and I'm spread way to thin. So thanks for all your work, and the nice write-ups.
Looks like everything ended up working out great!

I see that you've already published your changes. I'll give this a try immediately and report back!

@Chaphasilor
Copy link
Contributor Author

Yeah, that seems to work well! Sometimes the buffer doesn't show up in our UI immediately, but the next track is definitely starting to play immediately.
Skipping ahead two tracks doesn't seem to work yet, but that's fine. Could be a cache size issue, although you mentioned a size of 150 MB, which should be more than enough.

Either way, I also consider this issue closed. Providing the buffer duration in seconds would be nice, but if you want to wait for ryanheise/just_audio#1222 for that, that's also fine with me!
Thanks again!

@Pato05
Copy link
Owner

Pato05 commented Apr 18, 2024

Either way, I also consider this issue closed. Providing the buffer duration in seconds would be nice [...]

As I said earlier, media-kit itself doesn't have a way of specifying the buffer in seconds, even though mpv does have a property --demuxer-readahead-secs which, according to docs, should do what you're asking for.

Exporting the native platform would of course mean that you can set this property yourself, thus reaching your goal. Though I would like to avoid tinkering with properties (and introducing "hacks") as much as possible and just sticking to what media-kit already provides.

Though of course, if a hack is needed for a huge deficiency (like in #3), that would be completely fine as there wouldn't be any way around it.

@Chaphasilor
Copy link
Contributor Author

I'm still a but fuzzy with the relation between media-kit and mpv. I thought media-kit was a stand-alone player that doesn't use platform-specific implementations, but your comment makes me think it's just an additional wrapper around the "native" players for all platforms, that exposes a unified API?

@Pato05
Copy link
Owner

Pato05 commented Apr 30, 2024

I'm still a but fuzzy with the relation between media-kit and mpv. I thought media-kit was a stand-alone player that doesn't use platform-specific implementations, but your comment makes me think it's just an additional wrapper around the "native" players for all platforms, that exposes a unified API?

media-kit uses libmpv internally. There would be only two "platform implementations", being the native platform (platforms with dart:io) and the web platform (flutter web, which implements an HTML player)

2shrestha22 added a commit to 2shrestha22/just_audio_media_kit that referenced this issue Jul 21, 2024
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

No branches or pull requests

2 participants