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

Support key-frame accurate seeking in HLS #2882

Closed
mohammed-atif opened this issue May 29, 2017 · 24 comments
Closed

Support key-frame accurate seeking in HLS #2882

mohammed-atif opened this issue May 29, 2017 · 24 comments
Assignees

Comments

@mohammed-atif
Copy link

mohammed-atif commented May 29, 2017

SimpleExoPlayer.seekTo(int millis) issue

I have seen several issues requesting the same feature of smoother seeking in Exoplayer

At one thread I have seen your reply mentioning about the decoder but Android's VideoView default seeking is much more smoother when compared to ExoPlayer or MediaPlayer

Here is my code for reference

@Override
    public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) {
        long seekTo = (long) (mPlayer.getCurrentPosition() - distanceX);
        Log.d(TAG, "current scroll position "+seekTo);
        mPlayer.seekTo(seekTo);
        return true;
    }

I am using locally stored mp4 file to play using Exoplayer with TextureView

current exoplayer version - r2.4.1
com.google.android.exoplayer:exoplayer-core:r2.4.1

Are there any configurations that I have to change for smoother seeking?

@ojw28
Copy link
Contributor

ojw28 commented May 31, 2017

The reason behavior is different is that ExoPlayer does frame-accurate seeking (in all cases). I think VideoView does key-frame accurate seeking, which is faster but less accurate. We can use this issue to track supporting key-frame accurate seeking as an option, but it's low priority.

@ojw28 ojw28 changed the title SimpleExoPlayer.seekTo performance issue Support key-frame accurate seeking May 31, 2017
@mohammed-atif
Copy link
Author

@ojw28 , In other players, we have a callback which notifies about the successful seeking. If I make multiple calls for seek using onScroll method, I can ignore the inputs if seek is in progress, but in case of ExoPlayer there is no such callback and due to multiple seek requests, the performance of seeking further goes down. It would be really good if ExoPlayer too provides the callbacks for seek completion.

Apart from that, as you mentioned about the key-frame seeking, can you provide me details about the class which I can look into to do minor tweaks at my end for better seeking?

@goffioul
Copy link
Contributor

@atifmohammed Not sure this will help you, but I also needed some callback after seek completion. What I come up with was to drop a flag in my app when starting the seek operation, then listen to state change in onPlayerStateChanged. If my flag was set and the player state was STATE_READY, then I fired my callback. That seemed to work for my use case.

@mohammed-atif
Copy link
Author

@goffioul Thanks for the response, I figured it out few days ago but couldn't update here. While seeking the state goes to Buffer and after seek it shifts to ready.

@ojw28 forward seek works good after adding the callbacks. But when I seek backwards, player's current time is not updated.

int currentTime =  mSimpleExoPlayer.getCurrentTime();
int seekToMillis = currentTime - 45; //seek duration is very small in the range of 30 to 60 milliseconds
mSimpleExoPlayer.seekTo(seekToMillis);

if seekToMillis is currentTime + duration then everything works good, but when seeking back, in STATE_READY, currentTime remains same after every seek action which causes back and forth jerk to the video. Is it avoidable by making any changes?

@ojw28
Copy link
Contributor

ojw28 commented Jun 21, 2017

You shouldn't rely on the player reporting exactly your seek position back through getCurrentTime. The reported position may be adjusted slightly. If you want to seek in tiny increments like this, you should find a way to keep track of the last position that you performed a seek in your own code, and subtract 45 from that value each time. With that approach each position you pass to seekTo really will be 45 less than the previous value passed.

If we could keep this issue on topic, which is to support seeking to the nearest key-frame, that would be good. Thanks.

@ojw28 ojw28 self-assigned this Nov 19, 2017
ojw28 added a commit that referenced this issue Dec 4, 2017
Issue: #2882

-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=177814974
ojw28 added a commit that referenced this issue Dec 12, 2017
Issue: #2882

-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=178370038
ojw28 added a commit that referenced this issue Dec 12, 2017
Issue: #2882

-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=178606133
ojw28 added a commit that referenced this issue Dec 15, 2017
Also fix ClippingMediaSource to consider the start position an
artificial key-frame, and to properly offset the value returned
by getAdjustedSeekPositionUs.

Issue: #2882

-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=179032243
ojw28 added a commit that referenced this issue Jan 3, 2018
Whilst the previous behavior was WAI and had the advantage of
updating the position to be more exact when known, there were
a couple of disadvantages:

1. If seeking to the very end of a period in a playlist when
   paused, the position adjustment could trigger a position
   discontinuity to the next period.
2. We de-duplicate seeks to the current playback position.
   The position adjustment can prevent this from being
   effective. This is particularly important with the new
   SeekParameters support. When seeking to nearest sync point
   it's often possible to de-duplicate seeks, but we cannot
   do so if the playback position adjusts away from the sync
   point's time.

Issue: #2439
Issue: #2882

-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=180540736
ojw28 added a commit that referenced this issue Jan 15, 2018
Issue: #2882

-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=181314086
@green-nick
Copy link

Hi, @ojw28
When we could see key-frame supporting on release? Will it be in 2.6.2?
Or does dev-branch stable enough?

ojw28 added a commit that referenced this issue Jan 23, 2018
This avoids issues that can arise due to slight discrepancies between
chunk start times (obtained from the manifest of segment index) and
the timestamps of the samples contained within those chunks.

Issue: #2882

-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=182054959
@ojw28
Copy link
Contributor

ojw28 commented Jan 23, 2018

It will be 2.7.0 (I'm not sure whether we're doing any further 2.6.x releases, but if we are they wont include the relevant changes). We don't have an ETA yet.

@green-nick
Copy link

@ojw28 Ok, thanks!

@jclova
Copy link

jclova commented Feb 21, 2018

Really hoping to see the seekTo() options for us to choose:

  1. Accurate/slow seek
  2. To nearest keyframe/fast seek.

@ojw28
Copy link
Contributor

ojw28 commented Feb 21, 2018

This is supported for all media types except HLS in 2.7.0, which will be released shortly, via ExoPlayer.setSeekParameters.

@ojw28
Copy link
Contributor

ojw28 commented Feb 26, 2018

2.7.0 is now released, so this is now supported except for when playing HLS content.

@jclova
Copy link

jclova commented Feb 26, 2018 via email

@google google deleted a comment from KKXLC Feb 28, 2018
@google google deleted a comment from tonihei Feb 28, 2018
@google google deleted a comment from KKXLC Feb 28, 2018
@google google deleted a comment from andrewlewis Feb 28, 2018
@ojw28 ojw28 changed the title Support key-frame accurate seeking Support key-frame accurate seeking in HLS May 9, 2018
@animaonline
Copy link

When will this be support for HLS streams?

@ojw28
Copy link
Contributor

ojw28 commented Aug 28, 2018

We do not have an ETA for supporting this for HLS.

@BrainCrumbz
Copy link
Contributor

Hi all. Does anyone know how key-frame accurate seeking is reflected in SeekParameters "constants" (ref.)?

Which one should be passed to setSeekParameters() in order to achieve:

  1. any frame accurate seeking
  2. key-frame accurate seeking

?

TA

@andrewlewis
Copy link
Collaborator

andrewlewis commented Sep 20, 2018

@BrainCrumbz If you want to snap the seek position to the closest keyframe use SeekParameters.CLOSEST_SYNC. To see to a exact frame (the frame before the requested position, even if it's not a keyframe) use SeekParameters.EXACT.

@BrainCrumbz
Copy link
Contributor

BrainCrumbz commented Sep 27, 2018

@ maintainers: would you consider a tiny PR over javadoc for those constants, to better clarify what each means? Not sure if e.g. "seeking to the closest sync point" fully clarifies that's a keyframe.

@ojw28
Copy link
Contributor

ojw28 commented Sep 27, 2018

The documentation is deliberately vague, because exactly what happens depends a bit on the type of media being played. For DASH and SmoothStreaming, chunk boundaries are the sync points. If a chunk contains an additional keyframe somewhere in the middle, that's not considered as a sync point. For regular MP4, sync points are keyframes. For fragmented MP4, sync points are fragment boundaries.

The takeaway here is that sync points are whatever the underlying format naturally supports. A sync point will nearly always be aligned with a keyframe, but it's not necessarily true that all keyframes will be considered sync points.

@tipoc123
Copy link

tipoc123 commented Apr 30, 2019

Do you have some enhancements for HLS seek? Current HLS seek is slow and not suitable for production use (ExoPlayer 2.9.6)

@NathanSass
Copy link

I agree. It would be great to see this scheduled ASAP

@Zoeie
Copy link

Zoeie commented Jul 24, 2019

Like the MediaPlayer, it's just return the start position of the ts which the seek point owns to. The seeking operation is fast。
How should I modify the Exo source to be the same as the Seeking of MediaPlayer?

@stevemayhew
Copy link
Contributor

@ojw28 and @AquilesCanta I'm looking at this now for I-Frame only playback. The issue there is when you scrub multiple i-Frames are loaded an discard before any first frame shows, so the delay runs into 100's of milliseconds depending on the network and size of i-Frames.

My plan is to implement something similar to DefaultDashChunkSource's method, getAdjustedSeekPositionUs() obviously the playlist would need to support and be marked with #EXT-X-INDEPENDENT-SEGMENTS for this to work. Also before / after tolerances less than a segment duration would not really work (as there is no way to know the GOP interval in the HLS segments data). For I-Frame only, this does not matter trivially as each segment contains only a single i-Frame.

Scrub seeking (like the original request is for) is best done in i-Frame mode, so we could restrict the getAdjustedSeekPositionUs() function to only adjust the position when the primary sample stream wrapper is I-frame only.

stevemayhew added a commit to TiVo/ExoPlayer that referenced this issue Oct 6, 2021
The HLS implementation of `getAdjustedSeekPositionUs()` now completely supports `SeekParameters.CLOSEST_SYNC` and it's brotheran, assuming the HLS stream indicates segments all start with an IDR (that is EXT-X-INDEPENDENT-SEGMENTS  is specified).

This fixes issue google#2882 and improves (but does not completely solve google#8592
stevemayhew added a commit to TiVo/ExoPlayer that referenced this issue Oct 18, 2021
The HLS implementation of `getAdjustedSeekPositionUs()` now completely supports `SeekParameters.CLOSEST_SYNC`
and it's brotheran, assuming the HLS stream indicates segments all start with
an IDR (that is EXT-X-INDEPENDENT-SEGMENTS  is specified).

This fixes issue google#2882 and improves (but does not completely solve google#8592
@ojw28 ojw28 closed this as completed Feb 23, 2022
@jonas-livesporttv
Copy link

jonas-livesporttv commented Feb 23, 2022

@ojw28 you closing this issue means that key-frame accurate seeking in HLS is possible now?

@ojw28
Copy link
Contributor

ojw28 commented Feb 23, 2022

I believe support was added by @stevemayhew in the merged pull requests referenced above.

@google google locked and limited conversation to collaborators Apr 25, 2022
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests