-
Notifications
You must be signed in to change notification settings - Fork 6k
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
Is it ok to use runBlocking{}
on ExoPlayer's playback thread?
#10907
Comments
Technically, you won't get an ANR when blocking the playback thread because it is a separate thread that is started by the player. However, you would block the playback thread which blocks playback. The system doesn't care, but your user would (I see there is probably nothing playing when you execute the above code but still, in the future you may). Besides this I actually don't think that So I would discourage to block the execution in I wonder why you don't just do the network call on separate thread before you set the
|
The intention is to use ExoPlayer's own playlist, and use The network call So if we get ExoPlayer to do that network call when it needs it for any playlist item, that would give us a cleaner structure, and hopefully fix playback issues we have with long playlists. |
I don't see a way to do this from the top of my head with shortly lifing tokens I'm afraid. As far as I understand you'd have to make your own So increasing the life time of the tokens would make your life much easier. |
Thanks for your help 👍 To make life difficult, I might still implement a custom My question would then become: My code would be something like override fun prepareSourceInternal(mediaTransferListener: TransferListener?) {
super.prepareSourceInternal(mediaTransferListener)
val builder = mediaItem.buildUpon()
// Does this block the playback or the loader thread?
val remoteData = runBlocking {
fetchPlayableMedia()
}
remoteData?.let {
builder.setUri(it.mediaUri)
.setAdsConfiguration(it.toAdsConfiguration())
.setDrmConfiguration(it.toDrmConfiguration())
}
prepareChildSource(null, updateInternalMediaSource(builder))
}
private fun updateInternalMediaSource(builder: MediaItem.Builder): MediaSource { … }
private suspend fun fetchPlayableMedia(): PlayableMedia? { … } |
A |
After some testing, I can confirm that My solution would be to have the PlaylistManager start with Not the easiest solution as I'll have to handle token expiry and the Previous button, but I hope this will help with wakelock and buffering.. Thanks again for your answers 👍 |
You can start a separate thread in ExoPlayer/library/dash/src/main/java/com/google/android/exoplayer2/source/dash/DashMediaSource.java Line 458 in 3a654c1
|
I'm looking into extending
So I'm wondering what's the correct way to mark the source as prepared? I've tried delaying I also looked into implementing a Loader with a Loadable, EventDispatcher etc. I do reach |
So I think you need to subclass |
Things are looking better, thanks again for your help 👍 This is what my (simplified) code looks like class CustomMediaSource : CompositeMediaSource<Void?>() {
private val loader: Loader
private val loadable: LoadablePlayableMedia
private val loaderCallback = object : Loader.Callback<LoadablePlayableMedia> {
override fun onLoadCompleted(
loadable: LoadablePlayableMedia, elapsedRealtimeMs: Long, loadDurationMs: Long
) {
loadable.playableMedia?.let { playableMedia ->
mediaSource = mediaSourceFactory.createMediaSource(playableMedia.toMediaItem())
prepareChildSource(null, mediaSource)
}
}
}
override fun onChildSourceInfoRefreshed(
id: Void?,
mediaSource: MediaSource,
timeline: Timeline
) {
refreshSourceInfo(timeline)
}
override fun prepareSourceInternal(mediaTransferListener: TransferListener?) {
super.prepareSourceInternal(mediaTransferListener)
loader.startLoading(loadable, loaderCallback, 0)
}
}
And the suspending network method is handled by the loadable class LoadablePlayableMedia : Loadable {
var playableMedia: PlayableMedia? = null
private set
override fun load() {
runBlocking {
playableMedia = fetchPlayableMedia()
}
}
private suspend fun fetchPlayableMedia(): PlayableMedia? { ... }
} The network call is done on the background thread, then The last issue I'm still working on is how to get back to the main thread when I call |
You can create a To work together well with IMA I'd do something like this in the constructor:
|
Didn't get any answers to my stackoverflow question 😞 so here goes again!
I need to make a network call just before playback (similar in part to this issue). In this case, the network result is also used to to build
AdsConfiguration
andDrmConfiguration
, which are provided to theMediaItem.Builder
.The following code works fine, but I cannot find documentation that confirms it's ok!
MediaSource doc says
which is different from the background thread.
I tried using a
ResolvingDataSource
, where documentation forresolveDataSpec()
clearly mentionsBut
resolveDataSpec()
is called only aftercreateMediaSource(mediaItem)
, so it seems too late to set Ads/DRM configuration.The
DataSourceFactory
does callcreateDataSource()
, but I'm not sure ifhttpDataSource.setRequestProperty()
can be used to configure Ads/DRM.To put it differently: how can one do a network call on ExoPlayer's background thread, just before playback, and use the data to set Ads/DRM configuration?
The text was updated successfully, but these errors were encountered: