google / google/ExoPlayer

Player is accessed on the wrong thread.

Open
#10,333 9 comments 0 reactions 1 assignee Claimed by @marcbaechinger View on GitHub
bug
Dominant language
Java
Stars
21.9k
Forks
6k
PR merge metrics
No merged PRs in 30d

Description

### ExoPlayer Version

2.17.1

### Devices that reproduce the issue

Vivo V2027 Android 12 (SDK 31)
Vivo V2130 Android 12 (SDK 31)
Vivo V2132 Android 12 (SDK 31)
Vivo X80 Android 12 (SDK 31)
Vivo V2146 Android 11 (SDK 30)

### Devices that do not reproduce the issue

POCO X3 Android 12 (SDK 31)
Samsung A32 Android 11 (SDK 30)
Infinix Note 7 Android 10 (SDK 29)
Sony Xperia ZX3 Android 10 (SDK 29)

### Reproducible in the demo app?

No

### Reproduction steps

none

### Expected result

don't crash

### Actual result

```
exception.class.missing._Unknown_: java.lang.IllegalStateException Player is accessed on the wrong thread.
at android.app.ActivityThread.handleStopService (ActivityThread.java:5021)
at android.app.ActivityThread.access$2400 (ActivityThread.java:284)
at android.app.ActivityThread$H.handleMessage (ActivityThread.java:2327)
at android.os.Handler.dispatchMessage (Handler.java:106)
at android.os.Looper.loopOnce (Looper.java:233)
at android.os.Looper.loop (Looper.java:334)
at android.app.ActivityThread.main (ActivityThread.java:8399)
at java.lang.reflect.Method.invoke (Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run (RuntimeInit.java:582)
at com.android.internal.os.ZygoteInit.main (ZygoteInit.java:1068)
Caused by: java.lang.IllegalStateException:
at com.google.android.exoplayer2.ExoPlayerImpl.verifyApplicationThread (ExoPlayerImpl.java)
at com.google.android.exoplayer2.ExoPlayerImpl.getCurrentTimeline (ExoPlayerImpl.java)
at com.google.android.exoplayer2.analytics.DefaultAnalyticsCollector.K (DefaultAnalyticsCollector.java:25)
at com.google.android.exoplayer2.analytics.DefaultAnalyticsCollector.generateEventTime (DefaultAnalyticsCollector.java)
at com.google.android.exoplayer2.analytics.DefaultAnalyticsCollector.generateReadingMediaPeriodEventTime (DefaultAnalyticsCollector.java)
at com.google.android.exoplayer2.analytics.DefaultAnalyticsCollector.onSurfaceSizeChanged (DefaultAnalyticsCollector.java)
at com.google.android.exoplayer2.ExoPlayerImpl.lambda$maybeNotifySurfaceSizeChanged$28 (ExoPlayerImpl.java)
at com.google.android.exoplayer2.ExoPlayerImpl$$InternalSyntheticLambda$0$2d4737b778d7b8503f2f9305c33da9d50db855343d46ce9f1ebd9b998f070724$0.invoke (ExoPlayerImpl.java)
at com.google.android.exoplayer2.util.ListenerSet$ListenerHolder.invoke (ListenerSet.java)
at com.google.android.exoplayer2.util.ListenerSet.lambda$queueEvent$0 (ListenerSet.java)
at com.google.android.exoplayer2.util.ListenerSet$$InternalSyntheticLambda$1$4aa6d67c50ced20c53fd0cecd314136314e77eb5e787a34f9137864aa48c8e5a$0.run (ListenerSet.java)
at com.google.android.exoplayer2.util.ListenerSet.flushEvents (ListenerSet.java:66)
at com.google.android.exoplayer2.util.ListenerSet.sendEvent (ListenerSet.java)
at com.google.android.exoplayer2.ExoPlayerImpl.maybeNotifySurfaceSizeChanged (ExoPlayerImpl.java)
at com.google.android.exoplayer2.ExoPlayerImpl.access$1800 (ExoPlayerImpl.java)
at com.google.android.exoplayer2.ExoPlayerImpl$ComponentListener.surfaceDestroyed (ExoPlayerImpl.java)
at android.service.wallpaper.WallpaperService$Engine.reportSurfaceDestroyed (WallpaperService.java:1945)
at android.service.wallpaper.WallpaperService$Engine.detach (WallpaperService.java:1971)
at android.service.wallpaper.WallpaperService.onDestroy (WallpaperService.java:2400)
at android.app.ActivityThread.handleStopService (ActivityThread.java:5001)
at android.app.ActivityThread.access$2400 (ActivityThread.java:284)
at android.app.ActivityThread$H.handleMessage (ActivityThread.java:2327)
at android.os.Handler.dispatchMessage (Handler.java:106)
at android.os.Looper.loopOnce (Looper.java:233)
at android.os.Looper.loop (Looper.java:334)
at android.app.ActivityThread.main (ActivityThread.java:8399)
at java.lang.reflect.Method.invoke (Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run (RuntimeInit.java:582)
at com.android.internal.os.ZygoteInit.main (ZygoteInit.java:1068)
```

### Code

```
open class MovieLiveWallpaperService : WallpaperService() {
private var contexts: Activity? = null

enum class Mode {
FIT_CENTER,
FIT_START,
FIT_END,
FIT_XY,
CENTER_CROP
}

private val mode: Mode
get() = AppSharedPreferences
.getStringDefValue(this,"scale_type", Mode.CENTER_CROP.name).let(
Mode::valueOf)

fun setToWallPaper(activity: Activity) {
Utility.sendEvent("Live_Engine")
contexts = activity
try {
val intent = Intent(WallpaperManager.ACTION_CHANGE_LIVE_WALLPAPER)
intent.putExtra(
WallpaperManager.EXTRA_LIVE_WALLPAPER_COMPONENT, ComponentName(
activity,
MovieLiveWallpaperService::class.java
)
)
activity.startActivity(intent)
} catch (ignore: ActivityNotFoundException) {
}
}

override fun onCreateEngine(): Engine = GlEngine()

protected fun initExoMediaPlayer(): ExoPlayer {
val player = this.let { ExoPlayer.Builder(it).build() }
player.videoScalingMode = C.VIDEO_SCALING_MODE_SCALE_TO_FIT
player.playWhenReady = true
player.repeatMode = Player.REPEAT_MODE_ONE
player.volume = 0f
if (mode == Mode.CENTER_CROP) {
player.videoScalingMode = C.VIDEO_SCALING_MODE_SCALE_TO_FIT_WITH_CROPPING
} else {
player.videoScalingMode = C.VIDEO_SCALING_MODE_SCALE_TO_FIT
}
if (mode == Mode.FIT_CENTER) {
player.addListener(object : Player.Listener {
override fun onPlayerError(error: PlaybackException) {
super.onPlayerError(error)
contexts?.let {
Toast.makeText(
it,
"${error.message} Something Went Wrong!",
Toast.LENGTH_SHORT
).show()
}
}
})

}
return player
}

inner class GlEngine : WallpaperService.Engine() {

private var exoMediaPlayer = initExoMediaPlayer()

override fun onVisibilityChanged(visible: Boolean) {
exoMediaPlayer.playWhenReady = visible
if (visible) onResume()
else onPause()
}

@Synchronized
override fun onSurfaceCreated(holder: SurfaceHolder) {
kotlin.runCatching {
if (mode == Mode.FIT_CENTER) {
exoMediaPlayer.setVideoSurface(holder.surface)
} else {
exoMediaPlayer.setVideoSurfaceHolder(holder)
}
val videoUri = this@MovieLiveWallpaperService.let {
AppSharedPreferences.getString(
it,
"absolutePath"
)
}
val isLocalVideo =
AppSharedPreferences.getBool(this@MovieLiveWallpaperService, "isLocalVideo")
when {
isLocalVideo -> exoMediaPlayer.setMediaSource(
buildMediaSourceForLocal(
Uri.parse(
videoUri
)
)
)
!isLocalVideo -> exoMediaPlayer.setMediaSource(
buildMediaSource(
Uri.parse(
videoUri
)
)
)
}

exoMediaPlayer.prepare()
exoMediaPlayer.play()
}
}

private fun buildMediaSource(uri: Uri): MediaSource {
val userAgent = "exoplayer-liveWallpaper"
val media_item: MediaItem = MediaItem.fromUri(uri)
val cache_datasource_factory = CacheDataSource.Factory()
.setCache(EngineVideoCache.getInstance(this@MovieLiveWallpaperService))
.setUpstreamDataSourceFactory(
DefaultHttpDataSource.Factory()
.setUserAgent(userAgent)
)
return ProgressiveMediaSource.Factory(cache_datasource_factory)
.createMediaSource(media_item)
}

private fun buildMediaSourceForLocal(uri: Uri): MediaSource {
val media_item: MediaItem = MediaItem.fromUri(uri)
val dataSource = CacheDataSource.Factory()
.setCache(EngineVideoCache.getInstance(this@MovieLiveWallpaperService))
.setUpstreamDataSourceFactory(DefaultDataSource.Factory(this@MovieLiveWallpaperService))
return ProgressiveMediaSource.Factory(dataSource)
.createMediaSource(media_item)
}

override fun onSurfaceChanged(
holder: SurfaceHolder?,
format: Int,
width: Int,
height: Int
) {
}

@Synchronized
override fun onSurfaceDestroyed(holder: SurfaceHolder?) {
}

override fun onDestroy() {
kotlin.runCatching {
super.onDestroy()
exoMediaPlayer.stop()
exoMediaPlayer.release()
}
}

private fun onPause() {
kotlin.runCatching {
exoMediaPlayer.pause()
}
}

private fun onResume() {
kotlin.runCatching {
exoMediaPlayer.play()
}
}
}
}
```

### Bug Report

- [ ] You will email the zip file produced by `adb bugreport` to dev.exoplayer@gmail.com after filing this issue.

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.