The failure path now falls back to a message carrying the HTTP status
when the body has no detail/error and the raw body is blank, and the
large mylist fixture moves to TorboxCloudLibraryFixtures.kt so the
test file stays scannable.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Android httpRequestRaw capped response bodies at 1 MiB and appended a
truncation marker, corrupting large Torbox mylist JSON. The decode error
was swallowed, so the cloud library rendered as silently empty. Read the
full body like iOS/desktop already do, and surface undecodable Torbox
list responses as a provider error instead of an empty library.
Fixes#1216
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The stop-scrobble path snapshots its inputs via
snapshotTraktScrobbleItemInputs() returning a TraktScrobbleItemInputs
holder instead of seven loose locals, so adding a field to the item
cannot silently miss the snapshot.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Addons that embed the torrent identity in the url field (torrent://<hash>[/<fileIdx>]) with a null infoHash were treated as direct HTTP streams: playableDirectUrl surfaced the raw torrent:// string to the player, isTorrentStream missed it so debrid never engaged, and p2pInfoHash could not extract a hash so the p2p engine never engaged. Equivalent of NuvioTV#2174: classify torrent:// URLs as torrents, never surface them as playable, extract a validated info hash (40-char hex or 32-char base32) and trailing file index for the p2p path, and build proper magnet URIs for debrid from the effective hash. torrent://null and other unextractable URLs yield a null hash and stay unselectable.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
streamType is now trimmed, lowercased, and blanked to null by a shared
normalizeStreamType helper at all four ingestion sites, and the player
derives a single normalized value for both its rebuild keys and MIME
inference, so values like " HLS " cannot cause key churn or missed
mappings. The helper lives in commonMain and is covered by commonTest
together with a parser round-trip for a padded uppercase type.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Plugin scrapers (and some non-standard addons) declare the manifest
format of their links via a "type" field ("hls", "dash") on the
stream object. PluginRuntime already parses it into
PluginRuntimeResult.type, but both toStreamItem conversions dropped
it, and PlayerEngine.android.kt built MediaItems with no MIME type,
leaving ExoPlayer to infer the format from the URL extension. For
HLS links whose URL hides the .m3u8 behind tokens or rewriters
(https://cdn.example.com/playlist?token=…), inference fails and
playback errors or stalls.
This change:
- Adds a streamType field to StreamItem, populated from stream.type
in StreamParser, MetaDetailsParser embedded streams, and both
PluginRuntimeResult.toStreamItem conversions (StreamsRepository and
PlayerStreamsRepository).
- Plumbs the value through PlayerLaunch / PlayerScreen /
PlatformPlayerSurface and the in-player source-switch paths.
Switches to P2P sentinels and downloaded local files reset the
value to null so a stale "hls" can never mislabel the next source.
streamType participates in the player rebuild keys so a source
change always rebuilds with the right MIME.
- Persists streamType in the Reuse Last Link cache (defaulted
serializable field, old payloads stay decodable) so a typed HLS
stream that played once keeps working through link reuse.
- In playbackMediaItemFromUrl, the declared type takes precedence
over response-header and URL-path inference, mapping "hls"/"m3u8" →
APPLICATION_M3U8, "dash"/"mpd" → APPLICATION_MPD,
"ss"/"smoothstreaming" → APPLICATION_SS. Unrecognized values
(including Stremio's content-type semantics like "movie"/"series")
fall through to the existing inference chain unchanged.
The official Stremio stream spec defines no top-level type field, so
the Stremio-addon parsing is best-effort; the reliable emitters are
plugin scrapers, whose results previously lost the field entirely.
Scopes down to #1244 only. #1246 (User-Agent override) is already
fixed in the current PlayerPlaybackNetworking.createHttpDataSourceFactory,
which skips setUserAgent when caller-supplied headers declare one.
Fixes#1244
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>