google / ExoPlayer

This project is deprecated and stale. The latest ExoPlayer code is available in https://github.com/androidx/media
https://developer.android.com/media/media3/exoplayer
Apache License 2.0
21.72k stars 6.03k forks source link

Using live HLS streams, seek to a certain datetime #3488

Closed Eyliss closed 6 years ago

Eyliss commented 6 years ago

Hello,

I'm working on a radio application with Exoplayer v2.5.1. While reproducing live stream I'm implementing a song timeline where the user is able to "timeshift" to a already reproduced song. The timestamp when the song was played is known and my goal is to be able to seek to that timestamp in the player.

I tried several methods having in mind that the current time is equivalent to the current player position and I have managed to reach a point where I can move to the start of a song but if I repeat the same steps several times it suddenly reproduce a different point in the stream.

My iOS college made this work because the iOS player has a function called seekToDate and I was wondering if Exoplayer support this functionality (I have been checking the documentation and I didn't find anything I could use to achieve it).

Thanks in advance.

ojw28 commented 6 years ago

I guess the HLS playlists include EXT-X-PROGRAM-DATE-TIME tags to facilitate this? If that's the case then yes, it should be possible to do this during playback.

When seeking, you're required to pass a position relative to the start of the window of available content. For a live stream this is the position relative to when the live stream started, or relative to the oldest part of the stream that's still available in the case that segments are removed after a certain period of time. So to do what you're trying to do, you need to know the DateTime of the start of the current window so that you can apply the correct offset for the seek. You can do this by doing something like (disclaimer: completely untested):

Timeline timeline = player.getCurrentTimeline();
if (timeline.isEmpty()) {
  // Haven't got a non-empty timeline yet. Wait for onTimelineChanged() and try again
} else {
  long windowStartTimeMs = timeline.getWindow(0, new Timeline.Window()).windowStartTimeMs;
  if (windowStartTimeMs == C.TIME_UNSET) {
    // HLS playlist didn't have EXT-X-PROGRAM-DATE-TIME tag
    // Hopefully doesn't apply for your content
  } else {
    long seekPositionInWindowMs = dateTimeSeekPositionMs - windowStartTimeMs;
    // Should do some sanity checking here
    // E.g. Make sure it's non-negative and less than window duration
    player.seekTo(seekPositionInWindowMs);
  }
}