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

Accessing active datasource in onPositionDiscontinuity #7525

Closed
Tolriq opened this issue Jun 18, 2020 · 8 comments
Closed

Accessing active datasource in onPositionDiscontinuity #7525

Tolriq opened this issue Jun 18, 2020 · 8 comments
Assignees
Labels

Comments

@Tolriq
Copy link
Contributor

Tolriq commented Jun 18, 2020

[REQUIRED] Searched documentation and issues

I did :)

[REQUIRED] Question

I'm having an hard time to get the active datasource when the media change in a ConcatenatingMediaSource.

I use a specific DataSourceFactory that extends HttpDataSource.BaseFactory and prepare the media in the open(dataSpec).
During this preparation the media can be transcoded or not and depending on many factor the resulting may support some things like seeking or not.
I need to be able to access this information to do things like not calling normal seek but restart the transcoding at the new position.

The problem is that in ConcatenatingMediaSource open can be called to prepare the next media while the active media is still not closed.

So the question is how can I access the datasource from the player onPositionDiscontinuity callback. Or how can I access the MediaSource from the DataSource to be able to modify the tag?

@AquilesCanta
Copy link
Contributor

Why don't you assign a specific DataSourceFactory to each MediaSource so that each DataSourceFactory knows to which MediaSource they are assigned?

So when the media source calls open(...) for preparation (or whatever), you know which is the calling MediaSource, since the DataSourceFactory knows the corresponding MediaSource.

@Tolriq
Copy link
Contributor Author

Tolriq commented Jun 19, 2020

Isn't that highly inefficient to create a DefaultDataSourceFactory and my factory for every single items for very large playlists?

@tonihei
Copy link
Collaborator

tonihei commented Sep 22, 2020

DefaultDataSourceFactory is just a thin wrapper creating other DataSource instances, so there should be no issue with creating multiple factories if needed.

Not sure about your exact use case, but you can also consider one of the following:

  • Use ResolvingDataSource to add additional loading steps based on the DataSpec. You could detect whatever you need from the DataSpec URL, custom header key-value pairs or from using the customData object. Whether this is easily possible depends on the details of what you need and what you are trying to achieve.
  • Set a tag on each MediaSource (or MediaItem) that can be retrieved by Player.getCurrentTag() in onPositionDiscontinuity.

@Tolriq
Copy link
Contributor Author

Tolriq commented Sep 22, 2020

@tonihei Ok so let me try to better explain the need that is.

The player can play media from many different sources and some of them can transcode the media on the fly.
The transcoding or not decision is made at the DataSource.open to avoid wasting server resources.
When transcoding some server for some media type and transcoded media can generate non seekable media via normal player seek functions.
I can detect and know this only when transcoding start so in DataSource.open

But I need to know this at the player / UI side to either disable the seek functions or intercept the seek to be actual restart of the media at the proper new starting point.

The problem is that with gapless / ConcateningMediaSource the DataSource.open is called independently of the active media.

And from DataSource.open I can't access the corresponding MediaItem/MediaSource to update the tag that I could then use in onPositionDiscontinuity

So TL;DR I need to access the MediaSource/MediaItem from the DataSource.open not sure ResolvingDataSource brings anything here as it's before the open.

@tonihei
Copy link
Collaborator

tonihei commented Sep 22, 2020

ResolvingDataSource is essentially just an easy wrapper to intercept the DataSpec to the DataSource. If the actual information you need is only available afterwards, you would probably need to follow @AquilesCanta's advice and use a DataSource.Factory for each of your DataSources that has access to your tag object:

MediaSource mediaSource = 
    new ProgressiveMediaSource.Factory(() -> new MyCustomDataSource(tag))
      .setTag(tag)
      .createMediaSource(MediaItem.forUri(uri));

Aside: If you make the tag object mutable be aware that the loading takes place on another thread, so you need additional thread safety around the updates.

@Tolriq
Copy link
Contributor Author

Tolriq commented Sep 22, 2020

Thanks that's what I do, but the new playlist api is all about MediaItem directly no? Or I can use MediaSources directly and still use the new playlist api instead of concateningmediasource?

@tonihei
Copy link
Collaborator

tonihei commented Sep 22, 2020

Yes, you can. The ExoPlayer interface defines all relevant methods for that (e.g. setMediaSource, addMediaSource etc)

@Tolriq
Copy link
Contributor Author

Tolriq commented Sep 22, 2020

Ok thanks, closing this one too as there's no other way and factory are small :)

@Tolriq Tolriq closed this as completed Sep 22, 2020
@google google locked and limited conversation to collaborators Nov 22, 2020
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Projects
None yet
Development

No branches or pull requests

4 participants