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

Seek to initial position in a live stream using absolute time #9122

Open
sruditsky opened this issue Jun 27, 2021 · 3 comments
Open

Seek to initial position in a live stream using absolute time #9122

sruditsky opened this issue Jun 27, 2021 · 3 comments
Assignees

Comments

@sruditsky
Copy link

Let's say ExoPlayer is playing a live stream with a relatively long playlist (e.g. one hour).
The user pauses the playback and leaves it paused for long enough for the device to fall asleep.
Later the device is woken up and the playback is restarted.
What would be desirable is to restart it from the position where it was paused.

It is possible to call prepare, wait for the moment when the timeline is known and then call the seekTo.
However, this seems to inevitably leave some chance that some media will be downloaded before the seek (i.e. for a wrong playback position).

Is there any way to start live playback with the initial position specified as an absolute time (UTC) which avoids downloading media (and initialization) segments for a wrong/default position?

@kim-vde
Copy link
Contributor

kim-vde commented Jun 29, 2021

It is possible to call prepare, wait for the moment when the timeline is known and then call the seekTo.
However, this seems to inevitably leave some chance that some media will be downloaded before the seek (i.e. for a wrong playback position).

You can save the window and position before the device falls asleep and call seekTo before prepare (like we do in our demo app). Is there a reason you need to know the timeline before calling seekTo?

Is there any way to start live playback with the initial position specified as an absolute time (UTC) which avoids downloading media (and initialization) segments for a wrong/default position?

No. You need to provide a timestamp relative to the start of the video.

@kim-vde kim-vde self-assigned this Jun 29, 2021
@kim-vde kim-vde closed this as completed Jul 14, 2021
@google google locked and limited conversation to collaborators Sep 13, 2021
@tonihei
Copy link
Collaborator

tonihei commented Sep 20, 2021

This feature request has come up for the second time now, so it's probably best to mark this as an enhancement. See #8218 (comment) for the proposed API.

@tonihei tonihei reopened this Sep 20, 2021
@tonihei tonihei assigned marcbaechinger and unassigned kim-vde Sep 20, 2021
@tonihei tonihei changed the title How to seek to initial position in a live stream using absolute time? Seek to initial position in a live stream using absolute time Sep 20, 2021
@tonihei
Copy link
Collaborator

tonihei commented Feb 20, 2023

There is a workaround for this issue, which allows you to override the start time of an item:

DefaultMediaSourceFactory defaultMediaSourceFactory = new DefaultMediaSourceFactory(dataSourceFactory);
MediaSource.Factory mediaSourceFactory =
    new MediaSource.Factory() {
      @Override
      public MediaSource.Factory setDrmSessionManagerProvider(
          DrmSessionManagerProvider drmSessionManagerProvider) {
        defaultMediaSourceFactory.setDrmSessionManagerProvider(drmSessionManagerProvider);
        return this;
      }

      @Override
      public MediaSource.Factory setLoadErrorHandlingPolicy(
          LoadErrorHandlingPolicy loadErrorHandlingPolicy) {
        defaultMediaSourceFactory.setLoadErrorHandlingPolicy(loadErrorHandlingPolicy);
        return this;
      }

      @Override
      public @C.ContentType int[] getSupportedTypes() {
        return defaultMediaSourceFactory.getSupportedTypes();
      }

      @Override
      public MediaSource createMediaSource(MediaItem mediaItem) {
        MediaSource mediaSource = defaultMediaSourceFactory.createMediaSource(mediaItem);
        return new WrappingMediaSource(mediaSource) {
          @Override
          protected void onChildSourceInfoRefreshed(Timeline newTimeline) {
            Timeline updatedTimeline =
                new ForwardingTimeline(newTimeline) {
                  @Override
                  public Window getWindow(
                      int windowIndex, Window window, long defaultPositionProjectionUs) {
                    super.getWindow(windowIndex, window, defaultPositionProjectionUs);
                    if (window.isLive() && window.windowStartTimeMs != C.TIME_UNSET) {
                      long startTimeSinceUnixEpochUs = /* get start time from MediaItem */;
                      window.defaultPositionUs =
                          Math.max(0, startTimeSinceUnixEpochUs - window.windowStartTimeMs);
                    }
                    return window;
                  }
                };
            refreshSourceInfo(updatedTimeline);
          }
        };
      }
    };
ExoPlayer player = 
    new ExoPlayer.Builder(context).setMediaSourceFactory(mediaSourceFactory).build();

The startTimeSinceUnixEpochUs can be obtained from custom fields on the MediaItem (e.g. from localConfiguration.tag or mediaItem.mediaMetadata.extras).

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

4 participants