Reputation: 3753
I have ExoPlayerWrapper
class which is wrapper for ExoPlayer
and is singleton injected by Dagger. Init block in ExoPlayerWrapper
class looks in the following way:
@Singleton
class ExoPlayerWrapper @Inject constructor(
context: Context,
userAgentInfo: UserAgentInfo
) {
private val exoPlayer: ExoPlayer
private val httpDataSource: HttpDataSource
private val mediaSourceFactory: ExtractorMediaSource.Factory
override val exoPlayerInstance: ExoPlayer
get() = exoPlayer
init {
...
exoPlayer = ExoPlayerFactory.newSimpleInstance(renderersFactory, trackSelector)
httpDataSource = CustomHttpDataSource(userAgentInfo.userAgent, null)
mediaSourceFactory = ExtractorMediaSource.Factory { httpDataSource }
state = Player.STATE_IDLE
}
override fun playFromUrl(uri: Uri, headers: Map<String, String>) {
reset()
...
val mediaSource = mediaSourceFactory.createMediaSource(uri)
exoPlayer.prepare(mediaSource)
exoPlayer.playWhenReady = true
}
override fun pause() {
exoPlayer.playWhenReady = false
}
override fun reset() {
stop()
state = Player.STATE_IDLE
}
override fun stop() {
exoPlayer.stop()
exoPlayer.seekTo(0)
}
override fun seekTo(position: Long) {
exoPlayer.seekTo(position)
}
...
override fun release() {
exoPlayer.release()
state = Player.STATE_RELEASED
}
And in onCreate()
method of Activity
I have the following code:
public override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_video_player)
...
if (savedInstanceState != null) {
initialized = savedInstanceState.getBoolean(INITIALIZED)
}
if (!initialized) {
val uri = Uri.parse(attachedVideo?.uri)
player.playFromUrl(uri, sessionStore.sessionHeaders)
videoView.requestFocus()
initialized = true
}
videoView.player = player.exoPlayerInstance
backBtn.setOnClickListener{ _ ->
player.release()
finish()
}
}
But in this case I can play only one video after click on backBtn
button, other videos after that aren't played until I close app and reopen app again. And if I change backBtn's OnClickListener
in the following way:
backBtn.setOnClickListener{ _ ->
player.pause()
finish()
}
all works fine, other videos are played after click on backBtn
button. So it seems to be problem with reinitializing ExoPlayer
after release()
method invocation. And how correctly to reinitialize ExoPlayer after releasing?
UPD
And after release()
invocation and after attempt to open video again I see the following error in Logcat:
java.lang.IllegalStateException: Handler (android.os.Handler) {81fa8ef} sending message to a Handler on a dead thread at android.os.MessageQueue.enqueueMessage(MessageQueue.java:545) at android.os.Handler.enqueueMessage(Handler.java:661) at android.os.Handler.sendMessageAtTime(Handler.java:630) at android.os.Handler.sendMessageDelayed(Handler.java:600) at android.os.Handler.sendMessage(Handler.java:537) at android.os.Message.sendToTarget(Message.java:418) at com.google.android.exoplayer2.ExoPlayerImplInternal.stop(ExoPlayerImplInternal.java:207) at com.google.android.exoplayer2.ExoPlayerImpl.stop(ExoPlayerImpl.java:357) at com.google.android.exoplayer2.SimpleExoPlayer.stop(SimpleExoPlayer.java:777) at com.google.android.exoplayer2.SimpleExoPlayer.stop(SimpleExoPlayer.java:772) at package.ExoPlayerWrapper.stop(ExoPlayerWrapper.kt:xx) at package.ExoPlayerWrapper.reset(ExoPlayerWrapper.kt:xx) at package.ExoPlayerWrapper.playFromUrl(ExoPlayerWrapper.kt:xx) at package.VideoPlayerActivity.onCreate(VideoPlayerActivity.kt:xx)
Upvotes: 3
Views: 8994
Reputation: 81
The issue arises from trying to use a player whose resources have already been released. Because:
exoPlayer = ExoPlayerFactory.newSimpleInstance(renderersFactory, trackSelector)
only gets called once, during the initialization of ExoPlayerWrapper
. If your activity is not restarted, then that instance of ExoPlayerWrapper
sticks around with the released player.
Either create a new instance of ExoPlayerWrapper
whenever you go to play your video, or create a player initialization method inside ExoPlayerWrapper
, which you can call just before playing the video.
Upvotes: 2
Reputation: 449
For your requirement no need to use release method. If you are using this method you should reinitialize exoplayer again.
You can use stop() method to stop the exoplayer.
Upvotes: 0