mirror of
https://github.com/streamyfin/streamyfin.git
synced 2026-01-29 06:28:24 +00:00
fix(player): handle remote streams and live tv containers correctly
This commit is contained in:
@@ -262,6 +262,7 @@ export default function page() {
|
||||
mediaSource: MediaSourceInfo;
|
||||
sessionId: string;
|
||||
url: string;
|
||||
requiredHttpHeaders?: Record<string, string>;
|
||||
}
|
||||
|
||||
const [stream, setStream] = useState<Stream | null>(null);
|
||||
@@ -324,7 +325,7 @@ export default function page() {
|
||||
deviceProfile: generateDeviceProfile(),
|
||||
});
|
||||
if (!res) return null;
|
||||
const { mediaSource, sessionId, url } = res;
|
||||
const { mediaSource, sessionId, url, requiredHttpHeaders } = res;
|
||||
|
||||
if (!sessionId || !mediaSource || !url) {
|
||||
Alert.alert(
|
||||
@@ -333,7 +334,7 @@ export default function page() {
|
||||
);
|
||||
return null;
|
||||
}
|
||||
result = { mediaSource, sessionId, url };
|
||||
result = { mediaSource, sessionId, url, requiredHttpHeaders };
|
||||
}
|
||||
setStream(result);
|
||||
setStreamStatus({ isLoading: false, isError: false });
|
||||
@@ -601,17 +602,32 @@ export default function page() {
|
||||
source.externalSubtitles = externalSubs;
|
||||
}
|
||||
|
||||
// Add auth headers only for online streaming (not for local file:// URLs)
|
||||
if (!offline && api?.accessToken) {
|
||||
source.headers = {
|
||||
Authorization: `MediaBrowser Token="${api.accessToken}"`,
|
||||
};
|
||||
// Add headers for online streaming (not for local file:// URLs)
|
||||
if (!offline) {
|
||||
const headers: Record<string, string> = {};
|
||||
const isRemoteStream =
|
||||
mediaSource?.IsRemote && mediaSource?.Protocol === "Http";
|
||||
|
||||
// Add auth header only for Jellyfin API requests (not for external/remote streams)
|
||||
if (api?.accessToken && !isRemoteStream) {
|
||||
headers.Authorization = `MediaBrowser Token="${api.accessToken}"`;
|
||||
}
|
||||
|
||||
// Add any required headers from the media source (e.g., for external/remote streams)
|
||||
if (stream?.requiredHttpHeaders) {
|
||||
Object.assign(headers, stream.requiredHttpHeaders);
|
||||
}
|
||||
|
||||
if (Object.keys(headers).length > 0) {
|
||||
source.headers = headers;
|
||||
}
|
||||
}
|
||||
|
||||
return source;
|
||||
}, [
|
||||
stream?.url,
|
||||
stream?.mediaSource,
|
||||
stream?.requiredHttpHeaders,
|
||||
item?.UserData?.PlaybackPositionTicks,
|
||||
playbackPositionFromUrl,
|
||||
api?.basePath,
|
||||
|
||||
@@ -12,6 +12,7 @@ interface StreamResult {
|
||||
url: string;
|
||||
sessionId: string | null;
|
||||
mediaSource: MediaSourceInfo | undefined;
|
||||
requiredHttpHeaders?: Record<string, string>;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -50,10 +51,24 @@ const getPlaybackUrl = (
|
||||
return `${api.basePath}${transcodeUrl}`;
|
||||
}
|
||||
|
||||
// Handle remote/external streams (like live TV with external URLs)
|
||||
// These have Protocol "Http" and IsRemote true, with the actual URL in Path
|
||||
if (
|
||||
mediaSource?.IsRemote &&
|
||||
mediaSource?.Protocol === "Http" &&
|
||||
mediaSource?.Path
|
||||
) {
|
||||
console.log("Video is remote stream, using direct Path:", mediaSource.Path);
|
||||
return mediaSource.Path;
|
||||
}
|
||||
|
||||
// Fall back to direct play
|
||||
// Use the mediaSource's actual container when available (important for live TV
|
||||
// where the container may be ts/hls, not mp4)
|
||||
const container = params.container || mediaSource?.Container || "mp4";
|
||||
const streamParams = new URLSearchParams({
|
||||
static: params.static || "true",
|
||||
container: params.container || "mp4",
|
||||
container,
|
||||
mediaSourceId: mediaSource?.Id || "",
|
||||
subtitleStreamIndex: params.subtitleStreamIndex?.toString() || "",
|
||||
audioStreamIndex: params.audioStreamIndex?.toString() || "",
|
||||
@@ -163,6 +178,7 @@ export const getStreamUrl = async ({
|
||||
url: string | null;
|
||||
sessionId: string | null;
|
||||
mediaSource: MediaSourceInfo | undefined;
|
||||
requiredHttpHeaders?: Record<string, string>;
|
||||
} | null> => {
|
||||
if (!api || !userId || !item?.Id) {
|
||||
console.warn("Missing required parameters for getStreamUrl");
|
||||
@@ -210,6 +226,9 @@ export const getStreamUrl = async ({
|
||||
url,
|
||||
sessionId: sessionId || null,
|
||||
mediaSource,
|
||||
requiredHttpHeaders: mediaSource?.RequiredHttpHeaders as
|
||||
| Record<string, string>
|
||||
| undefined,
|
||||
};
|
||||
}
|
||||
|
||||
@@ -254,6 +273,9 @@ export const getStreamUrl = async ({
|
||||
url,
|
||||
sessionId: sessionId || null,
|
||||
mediaSource,
|
||||
requiredHttpHeaders: mediaSource?.RequiredHttpHeaders as
|
||||
| Record<string, string>
|
||||
| undefined,
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user