mirror of
https://github.com/JustinZeus/Wholphin.git
synced 2026-07-08 15:50:16 +02:00
Fixed a bug with libass integration where the background thread responsible for drawing the ASS subtitles (AssRenderThread) has been shut down, but ExoPlayer is still actively running and trying to push video time updates to it. Added fallback for software rendering on older android versions that can have broken OpenGl implementation.This should address much of issue #1049. ## Description Essentially, debug logs showed repeated: 3145 3920 W MessageQueue: Handler (android.os.Handler) {4ba3c72} sending message to a Handler on a dead thread 3145 3920 W MessageQueue: java.lang.IllegalStateException: Handler (android.os.Handler) {4ba3c72} sending message to a Handler on a dead thread Essentially this was a lifecycle bug where the libass-android thread was created, but was detaching from the window, shutting down when it does so. It was still registered to ExoPlayer, but since there was no thread to send to, it just repeatedly kept failing, never spinning back up to display any subtitles. It seems just about any ui change can cause this detachment, but in this case it seems it was right from the moment the loading spinner shows up (making libass-android fail before video starts playing). Fixed by ensuring TextureView's visibility wasn't changed to invisible, which ends up destroying the canvas that libass-android attaches itself to. Hid the canvas using graphicsLayer (so the user can't see it, but it's still alive and active). Also changed resizing logic to prevent Android from seeing a 0x0 TextureView as "destroyed". Since I discovered in testing how terribly my TV's OpenGl was handling this, I added an additional fallback for Android versions < 9. Older TV's can fallback to software rendering when using libass-android. ### Related issues #### Issue #1049 : **Fixes:** - the issue where libass-android (when enabled) fails to load any subtitles in ExoPlayer DirectPlay. **Not Fixed from issue #1049 :** - Issues around accented characters. - Any issues surrounding MPV (I have no way of testing, MPV never worked on any player for me) - Fallback mode (libass-android disabled) where subtitles aren't rendering properly **Added:** - While testing, discovered older Android versions have trouble with reliable OpenGl rendering. Thus I added a fallback for older Android versions to use libass-android in software rendering mode (AssRenderType.OVERLAY_CANVAS) ### Testing - Tested and confirmed flawlessly to work on Android 9 TCL Smart TV (AssRenderType.OVERLAY_CANVAS) - Tested on Android 14 Chromecast (AssRenderType.OVERLAY_OPEN_GL). Slightly less perfect (font not always a match, less fancy shadows) but most ASS/SSA effects work well. May be worth testing other AssRenderType options to compare features and performance on other machines. ## AI or LLM usage Google Gemini Pro in tracing down the cause and fine-tuning the fixes. --------- Co-authored-by: Damontecres <damontecres@gmail.com>
This commit is contained in:
parent
8b9b0ddec8
commit
96f94feac2
2 changed files with 20 additions and 7 deletions
|
|
@ -106,7 +106,13 @@ class PlayerFactory
|
|||
.setExtensionRendererMode(rendererMode)
|
||||
val mediaSourceFactory =
|
||||
if (useLibAss) {
|
||||
assHandler = AssHandler(AssRenderType.OVERLAY_OPEN_GL)
|
||||
val renderType =
|
||||
if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.P) {
|
||||
AssRenderType.OVERLAY_CANVAS
|
||||
} else {
|
||||
AssRenderType.OVERLAY_OPEN_GL
|
||||
}
|
||||
assHandler = AssHandler(renderType)
|
||||
val assSubtitleParserFactory = AssSubtitleParserFactory(assHandler)
|
||||
renderersFactory = AssRenderersFactory(assHandler, renderersFactory)
|
||||
DefaultMediaSourceFactory(
|
||||
|
|
|
|||
|
|
@ -439,6 +439,9 @@ fun PlaybackPageContent(
|
|||
val subtitleMaxSize by animateFloatAsState(if (controllerViewState.controlsVisible) .7f else 1f)
|
||||
val isImageSubtitles = remember(cues) { cues.firstOrNull()?.bitmap != null }
|
||||
var cueCount by remember { mutableIntStateOf(0) }
|
||||
|
||||
val subtitleVisible = skipIndicatorDuration == 0L && currentItemPlayback.subtitleIndexEnabled && !presentationState.coverSurface
|
||||
|
||||
AndroidView(
|
||||
factory = { context ->
|
||||
SubtitleView(context).apply {
|
||||
|
|
@ -465,10 +468,6 @@ fun PlaybackPageContent(
|
|||
}
|
||||
},
|
||||
update = { subtitleView ->
|
||||
val subtitleVisible =
|
||||
skipIndicatorDuration == 0L && currentItemPlayback.subtitleIndexEnabled && !presentationState.coverSurface
|
||||
subtitleView.visibility = if (subtitleVisible) View.VISIBLE else View.INVISIBLE
|
||||
|
||||
subtitleView.setCues(cues)
|
||||
if (cues.size > cueCount) {
|
||||
// The output creates a painter for each cue, so need to apply the changes when the number of cues increases
|
||||
|
|
@ -480,7 +479,8 @@ fun PlaybackPageContent(
|
|||
(it as? AssSubtitleView)?.apply {
|
||||
val resized =
|
||||
layoutParams.let { it.width != playerSurfaceSize.width || it.height != playerSurfaceSize.height }
|
||||
if (resized) {
|
||||
|
||||
if (resized && playerSurfaceSize.width > 0 && playerSurfaceSize.height > 0) {
|
||||
Timber.v("Resizing AssSubtitleView: %s", playerSurfaceSize)
|
||||
layoutParams =
|
||||
FrameLayout
|
||||
|
|
@ -501,7 +501,14 @@ fun PlaybackPageContent(
|
|||
.align(Alignment.TopCenter)
|
||||
.background(Color.Transparent)
|
||||
.graphicsLayer {
|
||||
alpha = if (isImageSubtitles) subtitleImageOpacity else 1f
|
||||
alpha =
|
||||
if (!subtitleVisible) {
|
||||
0f
|
||||
} else if (isImageSubtitles) {
|
||||
subtitleImageOpacity
|
||||
} else {
|
||||
1f
|
||||
}
|
||||
},
|
||||
)
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue