v0.1.0-W2 (vc=11): fix playback — TV+Ios YT clients + visible play errors

Black-screen-on-play bug: rustypipe's default player() uses YT's Web
client, which serves stream URLs that are session/UA-locked. ExoPlayer
fetching with a different UA gets a silent 403 from googlevideo and
renders a black surface.

Fix: pin stream_info() to player_from_clients(id, [Tv, Ios]) — the
TVHTML5 + iOS Innertube clients serve direct-play URLs that work in
any HTTP player. Same trick NewPipe uses. No Apple/iOS code involved
— it's just the API client identifier rustypipe sends to YT.

Also added a Player.Listener in PlayerScreen that Toasts any
PlaybackException (codeName + message) so future stream failures don't
look like silent black screens. Logs to logcat 'StrawPlayer' too.
This commit is contained in:
Kayos 2026-05-24 09:33:34 -07:00
parent a13896f5e9
commit 5be7d4c276
3 changed files with 34 additions and 4 deletions

View file

@ -121,6 +121,28 @@ fun PlayerScreen(
}
}
// Surface playback errors so a 403/404 from googlevideo doesn't show
// as a silent black screen. Captures everything ExoPlayer's renderer
// pipeline raises.
DisposableEffect(exoPlayer) {
val listener = object : Player.Listener {
override fun onPlayerError(error: androidx.media3.common.PlaybackException) {
val msg = buildString {
append("play err ")
append(error.errorCodeName)
append(": ")
append(error.message ?: error.cause?.message ?: "?")
}
com.sulkta.straw.util.strawLogW("StrawPlayer") { "$msg" }
runCatching {
Toast.makeText(context, msg.take(160), Toast.LENGTH_LONG).show()
}
}
}
exoPlayer.addListener(listener)
onDispose { exoPlayer.removeListener(listener) }
}
// PiP setup: on Android 12+ tell the OS this activity can auto-enter
// PiP, so when the user presses Home or swipes away the video shrinks
// into a floating window instead of pausing/exiting. Aspect ratio is