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
Live Streaming and ExoPlayer Shenanigans #1147
Conversation
-PoC for new seamless stream loading mechanism.
-Fixed media source manager excessive loading. -Remove unneeded fields in loaded media source.
…headset unplugged). -Fixed live media sources failing when using cached data source by introducing cacheless data sources. -Added custom track selector to circumvent ExoPlayer's language normalization NPE. -Updated Extractor to correctly load live streams. -Removed deprecated deferred media source and media source manager. -Removed Livestream exceptions.
-Extracted expiration time in media source manager. -Re-enabled long click on live stream info items. -Fixed dash source building to use mpd instead of extractor.
…tion policy. -Added sync buttons on live streams to allow seeking to live edge. -Added custom cache key for extractor sources to allow more persistent reuse. -Refactored player data source factories into own class and separating live and non-live data sources.
-Fixed play queue playlist desynchronization caused by media source manager window loading expansion on sublist prior to current item. -Fixed failed media source not treated as ready for playback.
…SourceManager. -Modified LoadController to allow fast playback start and increased buffer zigzag window. -Removed unnecessary loading on timeline changes. -Changed select message in MediaSourceManager to cause immediate load. -Reduced default expiration time in MediaSourceManager. -Fixed main video player not showing end time on audio-only streams. -Fixed live stream has player view disabled after transitioning from audio stream. -Fixed inconsistent progress bar height between live and non-live video on main player.
…ge for intent transactions. -Fixed potential transaction too large exceptions for player intents.
…ger to allow faster access time. -Added some null checks annotation.
A couple updates:
|
…rceManager. -Added nonnull and final constraints to variables in MediaSourceManager. -Added nonnull and final constraints on context related objects in BasePlayer. -Fixed Hls livestreams crashing player when behind live window for too long. -Fixed cache miss when InfoCache key mismatch between StreamInfo and StreamInfoItem.
-Improved player sync calls to recognize different metadata updates. -Changed MediaSourceManager to synchronize only after timeline changes and reenabled multiple sync calls to player. -Renamed listener and synchronization methods related to MediaSourceManager.
-Reenabled full window loading in MediaSourceManager.
-[TeamNewPipe#1151] Hide video player UI on playing to avoid unnecessary interruptions after pause, seek and resize.
49c620b
to
7f068b6
Compare
More updates:
|
off by a few seconds
I personally hate players that do that, could you create a setting for that?
|
I did. It's disabled by default. |
Oh, I didn't see that part, thanks!
|
… the last item on play queue is playing. -Added toggle to enable auto-queuing. -Modified main video player to only pause the video onPause. -Fixed main video player not saving play queue state onStop.
-Disabled auto queuing when repeating is enabled. -Added method to use startForegroundService instead of startService in sdk 26 and up.
lruCache.put(keyOf(info), data); | ||
|
||
final long expirationMillis; | ||
if (info.getServiceId() == SoundCloud.getServiceId()) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@theScrabi
I was hoping to receive some more review and discussions before having the PR merged, since there might be parts that would lead to tech debts.
For example, this part where different services can have different cache expiration. SoundCloud was added here since their API seems to fail sporadically and would cause the StreamInfo
to have bad stream urls and need to be reloaded.
This probably should be part of the extractor, or at least ServiceHelper
. Please consider removing this.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I see, I merged early, so now we have to take care about this in the aftermath.
For example, this part where different services can have different cache expiration. SoundCloud was added here since their API seems to fail sporadically and would cause the
StreamInfo
to have bad stream urls and need to be reloaded.
So you'd suggest a new field in StreamInfo
that tells the URls expiration time? If so we should add this.
Please consider removing this.
You mean the part that checks for SoundCloud? Right thats a hack and needs a proper solution.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm currently working on a PR that lets user wipe the InfoCache
, so we can remove this check. I've also reduce the default cache time to 1 hr instead of 4. I've also moved that check to ServiceHelper
for now and reduce the cache time for SoundCloud to 5 minutes.
However, this is not a long term solution, as SoundCloud stream url seems to consistently expire after a few minutes if they are not played, at least from my side. We will need to figure out exactly why this is happening, since it's probably a bad idea just slapping on an arbitrary expiration time for each service.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Well we might have similare problems with YouTube as some issues point out. But you are right, we should investigate this.
@@ -83,6 +98,58 @@ public static String resizeTypeOf(@NonNull final Context context, | |||
} | |||
} | |||
|
|||
@NonNull | |||
public static String cacheKeyOf(@NonNull final StreamInfo info, @NonNull VideoStream video) { | |||
return info.getUrl() + video.getResolution() + video.getFormat().getName(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just for the record. The cache key generation here might be too naive. Hopefully someone can find a better alternative, such as generating the VideoStream
or AudioStream
identifier in the extractor.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So you think we should distinguish between audio and video data as well?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sure, I think each normal stream should have a unique id they can use regardless of their url, since it changes all the time.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes that makes better sense.
This is why the UrlIdHandlers exist. Maybe these should be used at this point.
Hi! Thank you for your works! By the way, at times the sync of live stream doesn't work. It plays a certain interval of the stream and so the sync button plays always from the same point of the stream. The live stream is this, which has been broadcasted for several days. New playing also repeats the above problem. It starts from the very point of stream. It never goes to the present live streamed point because the playing ends at the point of 2 hours. And the live-watching number isn't updated in subscription window and in the detail window, while the live-watching number of the browsed result of the stream is correct. Restarting the app also repeats the problems. Do the problems have to do with caching the stream data? (+edit) |
@oceanwaves90 I also reproduced the sync button problem on the url you gave. I think this is probably due to the livestream being renewed on the uploader end, causing the livestream manifest to automatically transition into a normal stream, as I had no problem streaming this on live-edge for about 8 hours. So, unless this problem becomes rampant, I'd avoid writing extra logic to deal with this kind of cases, since we don't know when a stream url becomes stale. However, now that we have more dynamic data with livestreaming, we should consider expiring Youtube stream page data sooner, as well as adding a quick button (on the top right dropdown) to let users wipe the cache manually. |
I see! That will be great! I'll look forward to the next updates! |
TransactionTooLargeException
when passing player intents.Addendum:
HLS playlists really doesn't like loading and playing on demand, which means we can no longer use the existing
DeferredMediaSource
. Therefore, the old loader is being replaced by a new async loading inside theMediaSourceManager
.It works by first generating a list of placeholder media sources in order to create a playlist media source. When these placeholder are played, they stall the player until they are replaced with a
LoadedMediaSource
. When loading is requested, outside the lifecycle ofMediaSource
, theMediaSourceManager
loads and builds theMediaSource
asynchronously and replaces thePlaceholderMediaSource
at the corresponding index on the playlist media source. If the loading fails for a particular media source, then aFailedMediaSource
will be used for replacement.By doing this, HLS livestream is now able to load the playlists properly and we can now have better control on the playlist to evict or update
MediaSource
s with expired urls.Regarding the
CustomTrackSelector
, it is mostly a copypasta fromDefaultTrackSelector
. A few lines are changed in order to allow us to use irregular caption language names. This will be removed once ExoPlayer properly nullchecks their language code normalization.Currently, I have disabled track selection on livestreams since the manifest allows ExoPlayer to adaptively choose the quality according to the network status. Of course, this adaptiveness can be overriden if needed, but this requires us to create a separate quality menu just for livestreams, which will make the video player more complex. Let me know what you think.
Todos: