domain: neutral StreamKind for media streams (phase 4d)
Add StreamKind enum (audio/video/subtitle/other) to the domain module with a total stream_kind_from_jellyfin mapper. MediaStream gains a kind field (dual-carry), populated at the mapping seam. Frontend VideoPlayer track/ subtitle selection and the channel-video check now use stream.kind instead of the Jellyfin stream.type string. Rust 456 (+ stream_kinds_map test), frontend 644, check clean.
This commit is contained in:
+19
-1
@@ -1912,7 +1912,16 @@ export type MediaSource = { id: string; name: string; container?: string | null;
|
||||
/**
|
||||
* Media stream information (audio, video, subtitle tracks)
|
||||
*/
|
||||
export type MediaStream = { type: string; codec?: string | null; language?: string | null; displayTitle?: string | null; index: number; isDefault: boolean; isForced: boolean }
|
||||
export type MediaStream = {
|
||||
/**
|
||||
* Legacy Jellyfin stream type string ("Audio"/"Video"/"Subtitle"). Being
|
||||
* replaced by `kind`; dual-carried while the frontend migrates.
|
||||
*/
|
||||
type: string;
|
||||
/**
|
||||
* Provider-neutral stream classification — replaces `stream_type`.
|
||||
*/
|
||||
kind?: StreamKind; codec?: string | null; language?: string | null; displayTitle?: string | null; index: number; isDefault: boolean; isForced: boolean }
|
||||
export type MediaType = "audio" | "video"
|
||||
/**
|
||||
* Lightweight media item for merged playback state
|
||||
@@ -2516,6 +2525,15 @@ export type SmartCacheStats = { total_size: number; storage_limit: number; avail
|
||||
* Storage statistics for downloads
|
||||
*/
|
||||
export type StorageStats = { total_bytes: number; total_items: number; albums: AlbumStorageInfo[] }
|
||||
/**
|
||||
* The kind of a media stream within an item (audio track, video track,
|
||||
* subtitle, …) — provider-neutral, replacing the stringly Jellyfin stream type.
|
||||
*/
|
||||
export type StreamKind = "audio" | "video" | "subtitle" |
|
||||
/**
|
||||
* Any stream kind we do not model explicitly (e.g. embedded image, data).
|
||||
*/
|
||||
"other"
|
||||
/**
|
||||
* Represents a subtitle track
|
||||
*/
|
||||
|
||||
@@ -180,7 +180,7 @@
|
||||
console.log("[VideoPlayer] No media or mediaStreams available");
|
||||
return [];
|
||||
}
|
||||
const tracks = media.mediaStreams.filter(stream => stream.type === "Audio");
|
||||
const tracks = media.mediaStreams.filter(stream => stream.kind === "audio");
|
||||
console.log("[VideoPlayer] Found audio tracks:", tracks.length, tracks);
|
||||
return tracks;
|
||||
});
|
||||
@@ -243,7 +243,7 @@
|
||||
console.log("[VideoPlayer] No media or mediaStreams available for subtitles");
|
||||
return [];
|
||||
}
|
||||
const tracks = media.mediaStreams.filter(stream => stream.type === "Subtitle");
|
||||
const tracks = media.mediaStreams.filter(stream => stream.kind === "subtitle");
|
||||
console.log("[VideoPlayer] Found subtitle tracks:", tracks.length, tracks);
|
||||
return tracks;
|
||||
});
|
||||
@@ -520,7 +520,7 @@
|
||||
// Build subtitle tracks for native player
|
||||
const subtitleTracks = [];
|
||||
if (media.mediaStreams && mediaSourceId) {
|
||||
const subtitles = media.mediaStreams.filter(s => s.type === "Subtitle");
|
||||
const subtitles = media.mediaStreams.filter(s => s.kind === "subtitle");
|
||||
for (const sub of subtitles) {
|
||||
try {
|
||||
const url = await getSubtitleUrl(sub.index);
|
||||
|
||||
Reference in New Issue
Block a user