Audio player does not work well with "long tracks"

Server Version#: N/A (all)
Player Version#: 9.1.0.32210

This has been a problem with the android app forever. Years. I never bothered to look up how to report it until today because I figured that if I waited log enough eventually it would be resolved either by the devs noticing it directly, or someone else reporting it. Today is the day I am just going to finally report this.

I listen to long “dj sets”. The tracks are long 60+ minutes. Sometimes several hours. I think this is the basis of the issue. It seems to me, that the player code that deals with resuming audio after being paused (either manually or due to being disconnected from a bluetooth player). It seems like the player has some number of minutes of audio “cached” at all times. It seems like the code feels like that whatever is “cached” is enough to cover the rest of the current “song” when it resumes. I’m guessing under normal circumstances, the current song that was resumed would have ended before the cache limit was reached and the player would start playing the next track and everything would be fine. However, in my case, the “cached” data is no where near enough data to “finish” the song. So when the cache runs out it it just stops playing. Its like, it just assumed something else was going to happen before that state ocurred, hence my assuption detailed above.

What makes this even more annoying, is that this is supplimented by another issue that I constantly run into with this where when “resuming” after being paused, the player often just cant figure out where it was at in the track and just throws my progress piont out the window and just starts the set over from the beginning. If i was 30 minutes into a 2 hour set, I don’t want to re-listen to the first 30 minutes I just listened to because “reasons”. If I anticipate the bug is going to occur I usually make note of where the seek bar was in the track before resuming so that if it glitches out and starts over, I can manually seek it back to where it was… however the percision of the seek bar on a 2+ hour set is terrible so getting it exact is neigh impossible. I have to settle with “getting it close” where I ether have to listen to the last track again, or miss a track or two.

Generally speaking when I manually pause and resume from the app interface it works OK, most of the time, but one or both bugs can still occur in this scenario. However I can alsost pefectly replicate the issue on command using my car bluetooth radio. The way I can reproduce it, is get in my car, hook up the audio to BT mode, start playing a long set in the plex app. Drive to where I’m going and turn the car off. This turns off the radio, which disconnects the bluetooth. Plex stops playing at this time but the seek bar shows where the set was left off at until you resume playback.

When I get back to my car, turn the car on, the bluetooth reconnects to my phone. A 3rd bug can occur here as well, where it does not auto-resume playback where other audio apps will know that BT disconnect paused, and then auto-resume upon BT-Reconnecton but Plex does not usually do this I cant remember if it ever works or never works but I generally have to tell it to start playing again from the app. This is where the lost progress bug will occur. Sometimes it happens immediately. The player will immedialtey reset the progress and start the set from the beginning or it will play from the resume point, but eventually after as few minutes (cache runs out?) it will just stop playing and reset progress back to the beginning, needing to be manually restarted. Its also worth noting that some times after the ‘cache runs out’ event occurs, the entire app hard crashes and reboots. I’m not sure if thats what’s happening every time because I’m not usually “looking at it” when it happens, but on several occasions I have noticed it fully restart the app out of nowhere, recently after resuming playback.

Are your “dj sets” a single track that’s 60+ minutes long or are these just playlists?

1 - The audio player can only hold so much data. If it is a single 60+ minute track, there may not be enough cache to hold it all. If it is a playlist, we only cache the current and next song, assuming these fit in the available space.

2 - The app does not save where in a playlist playback managed to finish. It will track the position as long as the current sessions is still open. If something happens to close the sessions, the position is lost. So if you are on song 20 of a 100+ song playlist, if you stop playback too long so that the session expires, the position is lost and there is not a way to resume. This is a feature that has been requested but has not been implemented. Playlists - Remember position for subsequent resume

3 - This should work. There have been reports that Android’s battery optimization feature can interfere with this. Check if you have that setting enabled. Try turning it off and see if it helps.

Yes, the sets are 60+ minute single tracks, not a playlist of songs.

I’m not implying the app should cache the entire set. What I’m saying is the app should do a better job of tracking what was being played last and at what position playback was last stopped so that it can be resumed where it left off. This could be done by updating a state tracking object in the persistnent config every 5 - 10 seconds.

I’m not sure why the choice to limit the tracking of this information to a “session” was made when it could easily be written to some sort of config storage that persists indefinitely. Its quite presumptuous that I would not want to resume playback where I left off just because some [insert time period] had elapsed since playblack was last stopped. Also this causes a negative user experience if the app crashes. Then you have a new session and a lost place.

What you said about caching tracks with my observation that it appears to play out what was “in the buffer” or cached before just stopping or whatever. Even you said that it caches the current and next song. That seems like the logic was programmed to assume “songs” and it may not be accounting for the fact that the the current cache is not enough to finish the current song. I believe there is likely a piece of code that is not veryfying and resuming buffering and instead banking the song being cahced and letting whatever code resumes the “next song” also invoke the resuming of the buffering / caching. I do not believe that “resume buffer” code is being executed in my specific scenario. I’m not looking at the code, but as an app developer myself, this is my opinion of what “appears” to be happening. I could be wrong, but it tracks with what I’m seeing happen and with what you kind of said about what it caches. I think its worth checking that code to see if there is anything in there to check to ensure the buffering is resumed when resuming a song because it honestly feels like there is not. :shrug:

All that being said, the playlist request does not really apply to my situation.

Also I feel that its worth mentioning that if some of the issues here may be caused by relying on the server for too much. I dont think it should be outside of the realm of consideration to have your player apps do some of the lifting as far as what it was last playing it resuming. This way of thinking could even be applied to that playlist thread you linked. At a quick glance, it looked like there was questions or issues with device ids and tracking where the playback was last stopped… well if the “app” or “player” was responsible for its own logging of what it was last playing, playlist, position in the list, postin in a song or video or whatever, then whole device id stuff is moot. I can see where, thinking about this from the server perspective would make this all really complicated and a PITA to track and make work right, but if you give the responsibility of the where what and when of it all to the player itself, it becomes quite simple and trivial IMO.

I could be off base. I’m not saying any of this applies or makes sense for sure or that you guys haven’t thought of it. However I’m guilty of being too close to the forest to see the trees in some of my own projects so if this is possibly an alternate perspective that wasn’t previously considered for whatever reason then I figure its worth throwing it out there.

Cheers!

Edit: On a side note where I had the [insert period of time] I originally wrapped it in &lt &gt signs like an HTML tag and in the output the tag was removed (which is better than being left in unmodified which would present XSS vulnerabilities) but removing it was not the best play either. Replaceing the actual lt/gt chars with html entities like > and < would have been the best option. I’m not sure if this board software is something you control or if this is just purchased software, but if you do control it you should pass this note along to the devs for it :slight_smile:

Edit 2 — funny enough\ when I put the & gt; and & lt; entities in my last parargraph they were rendered out correctly!

I think there is a slight disconnection on “resume”. There are 2 types of resume.

1 - When you choose to play a track, it can start from the beginning or from the last point it was stopped. Plex will store the progress of a song as it plays. This info is sent from the client back to your server every 10s. There is a setting for your music library in Plex Media Server to “Store track progress”. If enabled, it saves the info it receives. You will then be given the option to start from the beginning or resuming from this stopped point.

2 - If you are referring to playing a song, hitting pause, then wanting to resume at some time in the future, there is a limitation on how that works. This part is handled entirely by the client app. The app will cache as much of the song from the server as possible. As long as the connection to the server is working (the session I referred to in my previous comment) , it will add to the cache as space become available. This cache will last as long as the app is open. If the app is in focus, this should exist indefinitely. However, if you background the app, switch to another app, or the screensaver kicks in, the Android OS takes over and decides if/when an app in the background gets closed or if it’s cache cleared. Plex cannot control this. This also breaks the connection to the server so that new data can’t be added to the cache. Even if the cache is not cleared, losing the connection to the server prevents appending to the exiting cache, the cache does not work that way.

Regarding #1 - I will look into that server setting and see if that makes any difference for my use case. I will report back on this.

Regarding #2 - “If you are referring to playing a song, hitting pause, then wanting to resume at some time in the future” - Yes this is exactly what I’m talking about… There are ways to work around that “limitation” that you do control, though, which I tried to explain in my last post. If you have your app keep track of playback progress by server/media/time code in a persistent config file, then when control is restored, the app can pull that information from the persistent config and “resume” where it left off. There is no need to rely on the active app caching for this. You can still use that, but you can “backup” the play state in that persistent config that is not subject to these limitations. When the app comes back, if its a “fresh” state, it can check the persistent config if there is something that should be resumed.

I’m not saying this is an easy task or whatever, but if I was developing this app, that’s how I would look into handling this personally.

This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.