fix(android): subtitles on the picture, not on a black bar
🏗️ Build and Test JellyTau / Run Tests (push) Successful in 15m35s
🏗️ Build and Test JellyTau / Supply Chain (push) Successful in 40s
Publish Documentation / Build & publish docs to gitea-pages (push) Successful in 5m34s
Traceability Validation / Check Requirement Traces (push) Successful in 12s
🏗️ Build and Test JellyTau / Android Compile Check (push) Successful in 4m30s
🏗️ Build and Test JellyTau / Run Tests (push) Successful in 15m35s
🏗️ Build and Test JellyTau / Supply Chain (push) Successful in 40s
Publish Documentation / Build & publish docs to gitea-pages (push) Successful in 5m34s
Traceability Validation / Check Requirement Traces (push) Successful in 12s
🏗️ Build and Test JellyTau / Android Compile Check (push) Successful in 4m30s
Every subtitle line arrived in an opaque black box wide enough to sit across the picture. That box is what Android hands back when the viewer has set no captioning preferences: SubtitleView.setUserDefaultStyle() reads the system style and falls back to media3's DEFAULT, which is white on opaque black. Dropping the box is not the same as replacing the style. Someone who has configured captions in accessibility settings has said something specific about colour, typeface and edges, and overriding all of it to remove a background would answer a question they did not ask. Their style is kept and only the two colours that paint a box — background and window — are cleared. A style specifying no edge gets a black outline, since without a box the text must supply its own contrast or it is unreadable over a bright scene. One that already names an edge keeps it: that viewer has said how they want their captions separated from the picture. Compiles and packages, but NOT yet seen on a device — the tablet was disconnected before it could be deployed, so the requirement is recorded as "Done (pending device verification)" and this must not be tagged into a release until someone has looked at it. TRACES: UR-020 | DR-261
This commit is contained in:
@@ -1330,10 +1330,8 @@ class JellyTauPlayer(private val appContext: Context) {
|
||||
ViewGroup.LayoutParams.MATCH_PARENT,
|
||||
ViewGroup.LayoutParams.MATCH_PARENT
|
||||
)
|
||||
// Honour the viewer's system captioning preferences (size,
|
||||
// colour, edge style) and whatever styling the track carries —
|
||||
// the same defaults a PlayerView would have applied.
|
||||
setUserDefaultStyle()
|
||||
// Text over the picture, not a black bar across it. (DR-261)
|
||||
setStyle(captionStyle())
|
||||
setUserDefaultTextSize()
|
||||
}
|
||||
android.util.Log.d("JellyTauPlayer", "SubtitleView created")
|
||||
@@ -1341,6 +1339,61 @@ class JellyTauPlayer(private val appContext: Context) {
|
||||
return videoView!!.hashCode()
|
||||
}
|
||||
|
||||
/**
|
||||
* The caption style to draw cues in: the viewer's own, with the background
|
||||
* taken out.
|
||||
*
|
||||
* `setUserDefaultStyle()` reads Android's captioning preferences and falls
|
||||
* back to media3's `DEFAULT` when the viewer has set none — and that
|
||||
* default is white on **opaque black**, which is what put a black box under
|
||||
* every line, wide enough to sit across the picture.
|
||||
*
|
||||
* Dropping the box is not the same as replacing the style. A viewer who has
|
||||
* configured captions in accessibility settings has said something specific
|
||||
* about colour, typeface and edges, and overriding all of that to get a
|
||||
* transparent background would be answering a question they did not ask. So
|
||||
* their style is kept and only the two colours that paint a box —
|
||||
* background and window — are cleared.
|
||||
*
|
||||
* With no box the text supplies its own contrast or it is unreadable over a
|
||||
* bright scene, so a style that asked for no edge gets a black outline. One
|
||||
* that already specifies an edge keeps it: that viewer has already said how
|
||||
* they want their captions separated from the picture.
|
||||
*
|
||||
* TRACES: UR-020 | DR-261
|
||||
*/
|
||||
private fun captionStyle(): androidx.media3.ui.CaptionStyleCompat {
|
||||
val base = try {
|
||||
val captioning = appContext.getSystemService(Context.CAPTIONING_SERVICE)
|
||||
as? android.view.accessibility.CaptioningManager
|
||||
if (captioning != null && captioning.isEnabled) {
|
||||
androidx.media3.ui.CaptionStyleCompat.createFromCaptionStyle(captioning.userStyle)
|
||||
} else {
|
||||
androidx.media3.ui.CaptionStyleCompat.DEFAULT
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
// A captioning service that refuses to answer is not a reason to
|
||||
// draw nothing; fall back to the same default media3 would use.
|
||||
android.util.Log.w("JellyTauPlayer", "Captioning preferences unavailable", e)
|
||||
androidx.media3.ui.CaptionStyleCompat.DEFAULT
|
||||
}
|
||||
|
||||
val needsOwnEdge = base.edgeType == androidx.media3.ui.CaptionStyleCompat.EDGE_TYPE_NONE
|
||||
|
||||
return androidx.media3.ui.CaptionStyleCompat(
|
||||
base.foregroundColor,
|
||||
android.graphics.Color.TRANSPARENT,
|
||||
android.graphics.Color.TRANSPARENT,
|
||||
if (needsOwnEdge) {
|
||||
androidx.media3.ui.CaptionStyleCompat.EDGE_TYPE_OUTLINE
|
||||
} else {
|
||||
base.edgeType
|
||||
},
|
||||
if (needsOwnEdge) android.graphics.Color.BLACK else base.edgeColor,
|
||||
base.typeface
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* The view that draws subtitle cues, for VideoOverlayManager to attach
|
||||
* directly above the video and below the WebView. Null before the first
|
||||
|
||||
Reference in New Issue
Block a user