-
Notifications
You must be signed in to change notification settings - Fork 296
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
Allows exact live sync for HLS #703
base: release
Are you sure you want to change the base?
Conversation
This commit addresses the issue of inaccurate live position measurement in HLS by introducing NTP time synchronization. Unlike DASH, HLS lacks origin time synchronization logic, resulting in potential discrepancies in wall-clock time when using `System.currentTimeMillis()`. The commit utilizes the `SntpClient` in ExoPlayer to determine the clock offset with the default NTP server (`time.android.com`) and applies this information to the `HlsMediaSource`. With the implementation of this change, multiple devices can now synchronize playback to a common time source, as long as the origin server also synchronizes to an NTP time source.
Enables testing the Live Offset settings with the main demo PlayerActivity. Using an intent like: ``` adb shell am start -n androidx.media3.demo.main/.PlayerActivity -a androidx.media3.demo.main.action.VIEW --ei live_offset_target 30 --ef live_offset_adjust_speed 35.0 ``` Will start playback synced to a 30 second offset with agressive speed adjustment to achive it, note this requires audio codec that supports speed changes (AAC for example)
/* elapsedRealtimeEpochOffsetMs= */ C.TIME_UNSET, | ||
SntpClient.getElapsedRealtimeOffsetMs(), | ||
periodDurationUs, |
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.
If the SntpClient is not initialized this change done nothing, so you could consider making the changes to DefaultHlsPlaylistTracker
surrounded by a feature flag from the HlsPlaylistTracker.Factory
(if it was not private), or simply a PSFB flag.
} | ||
|
||
private void requestMasterPlaylist( | ||
EventDispatcher eventDispatcher, ParsingLoadable<HlsPlaylist> multivariantPlaylistLoadable) { | ||
long elapsedRealtime = | ||
initialPlaylistLoader.startLoading( | ||
multivariantPlaylistLoadable, |
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.
The requestMasterPlaylist
was simply a refactoring (extract method), then call the method in the SntpClient
callback. Most times this is a no-op as the SntpClient
offset is up to date.
} | ||
} | ||
|
||
private void loadAfterTimeSync(Uri playlistRequestUri) { | ||
ParsingLoadable.Parser<HlsPlaylist> mediaPlaylistParser = |
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.
The same refactor lift method to create loadAfterTimeSync()
. Here only the primary playlist load needs to possibly refresh SntpClient
as the master playlist is only loaded once
@stevemayhew I think you should rebase this against |
This pull request satisfies the enhancement request #702. For playback longer than a few hours the fix for SntpClient is also required, see pull request #697