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:
parent
ab37d534d5
commit
04b0a8dbe9
3 changed files with 34 additions and 4 deletions
|
|
@ -15,6 +15,6 @@ const val NEWPIPE_APPLICATION_ID_OLD = "org.schabi.newpipe"
|
||||||
const val NEWPIPE_APPLICATION_ID_NEW = "net.newpipe.app"
|
const val NEWPIPE_APPLICATION_ID_NEW = "net.newpipe.app"
|
||||||
|
|
||||||
// Sulkta fork — Straw
|
// Sulkta fork — Straw
|
||||||
const val STRAW_VERSION_CODE = 10
|
const val STRAW_VERSION_CODE = 11
|
||||||
const val STRAW_VERSION_NAME = "0.1.0-W"
|
const val STRAW_VERSION_NAME = "0.1.0-W2"
|
||||||
const val STRAW_APPLICATION_ID = "com.sulkta.straw"
|
const val STRAW_APPLICATION_ID = "com.sulkta.straw"
|
||||||
|
|
|
||||||
|
|
@ -17,7 +17,7 @@
|
||||||
|
|
||||||
use crate::error::StrawcoreError;
|
use crate::error::StrawcoreError;
|
||||||
use crate::search::SearchItem;
|
use crate::search::SearchItem;
|
||||||
use rustypipe::client::RustyPipe;
|
use rustypipe::client::{ClientType, RustyPipe};
|
||||||
|
|
||||||
#[derive(Debug, Clone, uniffi::Record)]
|
#[derive(Debug, Clone, uniffi::Record)]
|
||||||
pub struct StreamInfo {
|
pub struct StreamInfo {
|
||||||
|
|
@ -129,7 +129,15 @@ pub async fn stream_info(url: String) -> Result<StreamInfo, StrawcoreError> {
|
||||||
log::info!("strawcore::stream_info id={}", id);
|
log::info!("strawcore::stream_info id={}", id);
|
||||||
let rp = RustyPipe::new();
|
let rp = RustyPipe::new();
|
||||||
|
|
||||||
let player = rp.query().player(&id).await?;
|
// rustypipe's default `player()` uses the Web client first. Those URLs
|
||||||
|
// come back signed against the Web fetch's session/UA — ExoPlayer can't
|
||||||
|
// replay them (404/403/black screen). Force the TV embedded + iOS
|
||||||
|
// clients, both of which return ungated direct-play URLs the way
|
||||||
|
// NewPipe's resolver does.
|
||||||
|
let player = rp
|
||||||
|
.query()
|
||||||
|
.player_from_clients(&id, &[ClientType::Tv, ClientType::Ios])
|
||||||
|
.await?;
|
||||||
let details = &player.details;
|
let details = &player.details;
|
||||||
|
|
||||||
// Progressive (combined audio+video) goes through video_streams; the
|
// Progressive (combined audio+video) goes through video_streams; the
|
||||||
|
|
|
||||||
|
|
@ -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 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
|
// PiP, so when the user presses Home or swipes away the video shrinks
|
||||||
// into a floating window instead of pausing/exiting. Aspect ratio is
|
// into a floating window instead of pausing/exiting. Aspect ratio is
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue