mirror of
https://github.com/streamyfin/streamyfin.git
synced 2026-04-17 14:31:58 +01:00
wip
This commit is contained in:
63
utils/jellyfin/getDefaultPlaySettings.ts
Normal file
63
utils/jellyfin/getDefaultPlaySettings.ts
Normal file
@@ -0,0 +1,63 @@
|
||||
// utils/getDefaultPlaySettings.ts
|
||||
import { BITRATES } from "@/components/BitrateSelector";
|
||||
import {
|
||||
BaseItemDto,
|
||||
MediaSourceInfo,
|
||||
} from "@jellyfin/sdk/lib/generated-client";
|
||||
import { Settings } from "../atoms/settings";
|
||||
|
||||
interface PlaySettings {
|
||||
item: BaseItemDto;
|
||||
bitrate: (typeof BITRATES)[0];
|
||||
mediaSource: MediaSourceInfo | undefined;
|
||||
audioIndex?: number | null;
|
||||
subtitleIndex?: number | null;
|
||||
}
|
||||
|
||||
export function getDefaultPlaySettings(
|
||||
item: BaseItemDto,
|
||||
settings: Settings
|
||||
): PlaySettings {
|
||||
if (item.Type === "Program") {
|
||||
return {
|
||||
item,
|
||||
bitrate: BITRATES[0],
|
||||
mediaSource: undefined,
|
||||
audioIndex: undefined,
|
||||
subtitleIndex: undefined,
|
||||
};
|
||||
}
|
||||
|
||||
// 1. Get first media source
|
||||
const mediaSource = item.MediaSources?.[0];
|
||||
|
||||
if (!mediaSource) throw new Error("No media source found");
|
||||
|
||||
// 2. Get default or preferred audio
|
||||
const defaultAudioIndex = mediaSource?.DefaultAudioStreamIndex;
|
||||
const preferedAudioIndex = mediaSource?.MediaStreams?.find(
|
||||
(x) => x.Language === settings?.defaultAudioLanguage
|
||||
)?.Index;
|
||||
const firstAudioIndex = mediaSource?.MediaStreams?.find(
|
||||
(x) => x.Type === "Audio"
|
||||
)?.Index;
|
||||
|
||||
// 3. Get default or preferred subtitle
|
||||
const preferedSubtitleIndex = mediaSource?.MediaStreams?.find(
|
||||
(x) => x.Language === settings?.defaultSubtitleLanguage?.value
|
||||
)?.Index;
|
||||
const defaultSubtitleIndex = mediaSource?.MediaStreams?.find(
|
||||
(stream) => stream.Type === "Subtitle" && stream.IsDefault
|
||||
)?.Index;
|
||||
|
||||
// 4. Get default bitrate
|
||||
const bitrate = BITRATES[0];
|
||||
|
||||
return {
|
||||
item,
|
||||
bitrate,
|
||||
mediaSource,
|
||||
audioIndex: preferedAudioIndex ?? defaultAudioIndex ?? firstAudioIndex,
|
||||
subtitleIndex: preferedSubtitleIndex ?? defaultSubtitleIndex ?? -1,
|
||||
};
|
||||
}
|
||||
@@ -34,8 +34,8 @@ export const getStreamUrl = async ({
|
||||
height?: number;
|
||||
mediaSourceId?: string | null;
|
||||
}): Promise<{
|
||||
url: string | null | undefined;
|
||||
sessionId: string | null | undefined;
|
||||
url: string | null;
|
||||
sessionId: string | null;
|
||||
} | null> => {
|
||||
if (!api || !userId || !item?.Id) {
|
||||
return null;
|
||||
@@ -66,7 +66,7 @@ export const getStreamUrl = async ({
|
||||
}
|
||||
);
|
||||
const transcodeUrl = res0.data.MediaSources?.[0].TranscodingUrl;
|
||||
sessionId = res0.data.PlaySessionId;
|
||||
sessionId = res0.data.PlaySessionId || null;
|
||||
|
||||
if (transcodeUrl) {
|
||||
return { url: `${api.basePath}${transcodeUrl}`, sessionId };
|
||||
@@ -75,29 +75,6 @@ export const getStreamUrl = async ({
|
||||
|
||||
const itemId = item.Id;
|
||||
|
||||
// const res2 = await api.axiosInstance.post(
|
||||
// `${api.basePath}/Items/${itemId}/PlaybackInfo`,
|
||||
// {
|
||||
// DeviceProfile: deviceProfile,
|
||||
// UserId: userId,
|
||||
// MaxStreamingBitrate: maxStreamingBitrate,
|
||||
// StartTimeTicks: startTimeTicks,
|
||||
// EnableTranscoding: maxStreamingBitrate ? true : undefined,
|
||||
// AutoOpenLiveStream: true,
|
||||
// MediaSourceId: mediaSourceId,
|
||||
// AllowVideoStreamCopy: maxStreamingBitrate ? false : true,
|
||||
// AudioStreamIndex: audioStreamIndex,
|
||||
// SubtitleStreamIndex: subtitleStreamIndex,
|
||||
// DeInterlace: true,
|
||||
// BreakOnNonKeyFrames: false,
|
||||
// CopyTimestamps: false,
|
||||
// EnableMpegtsM2TsMode: false,
|
||||
// },
|
||||
// {
|
||||
// headers: getAuthHeaders(api),
|
||||
// }
|
||||
// );
|
||||
|
||||
const res2 = await getMediaInfoApi(api).getPlaybackInfo(
|
||||
{
|
||||
userId,
|
||||
@@ -120,55 +97,64 @@ export const getStreamUrl = async ({
|
||||
breakOnNonKeyFrames: false,
|
||||
copyTimestamps: false,
|
||||
enableMpegtsM2TsMode: false,
|
||||
|
||||
},
|
||||
}
|
||||
);
|
||||
|
||||
sessionId = res2.data.PlaySessionId;
|
||||
sessionId = res2.data.PlaySessionId || null;
|
||||
|
||||
mediaSource = res2.data.MediaSources?.find(
|
||||
(source: MediaSourceInfo) => source.Id === mediaSourceId
|
||||
);
|
||||
|
||||
if (mediaSource?.SupportsDirectPlay || forceDirectPlay === true) {
|
||||
if (item.MediaType === "Video") {
|
||||
url = `${api.basePath}/Videos/${itemId}/stream.mp4?playSessionId=${sessionData?.PlaySessionId}&mediaSourceId=${mediaSource?.Id}&static=true&subtitleStreamIndex=${subtitleStreamIndex}&audioStreamIndex=${audioStreamIndex}&deviceId=${api.deviceInfo.id}&api_key=${api.accessToken}`;
|
||||
} else if (item.MediaType === "Audio") {
|
||||
const searchParams = new URLSearchParams({
|
||||
UserId: userId,
|
||||
DeviceId: api.deviceInfo.id,
|
||||
MaxStreamingBitrate: "140000000",
|
||||
Container:
|
||||
"opus,webm|opus,mp3,aac,m4a|aac,m4b|aac,flac,webma,webm|webma,wav,ogg",
|
||||
TranscodingContainer: "mp4",
|
||||
TranscodingProtocol: "hls",
|
||||
AudioCodec: "aac",
|
||||
api_key: api.accessToken,
|
||||
PlaySessionId: sessionData?.PlaySessionId || "",
|
||||
StartTimeTicks: "0",
|
||||
EnableRedirection: "true",
|
||||
EnableRemoteMedia: "false",
|
||||
});
|
||||
url = `${
|
||||
api.basePath
|
||||
}/Audio/${itemId}/universal?${searchParams.toString()}`;
|
||||
console.log("getStreamUrl ~ ", item.MediaType);
|
||||
|
||||
if (item.MediaType === "Video") {
|
||||
if (mediaSource?.TranscodingUrl) {
|
||||
return {
|
||||
url: `${api.basePath}${mediaSource.TranscodingUrl}`,
|
||||
sessionId: sessionId,
|
||||
};
|
||||
}
|
||||
|
||||
if (mediaSource?.SupportsDirectPlay || forceDirectPlay === true) {
|
||||
return {
|
||||
url: `${api.basePath}/Videos/${itemId}/stream.mp4?playSessionId=${sessionData?.PlaySessionId}&mediaSourceId=${mediaSource?.Id}&static=true&subtitleStreamIndex=${subtitleStreamIndex}&audioStreamIndex=${audioStreamIndex}&deviceId=${api.deviceInfo.id}&api_key=${api.accessToken}`,
|
||||
sessionId: sessionId,
|
||||
};
|
||||
}
|
||||
} else if (mediaSource?.TranscodingUrl) {
|
||||
url = `${api.basePath}${mediaSource.TranscodingUrl}`;
|
||||
}
|
||||
|
||||
if (!url) {
|
||||
console.log("getStreamUrl: no url found", {
|
||||
api: api.basePath,
|
||||
userId,
|
||||
item: item.Id,
|
||||
mediaSourceId,
|
||||
if (item.MediaType === "Audio") {
|
||||
console.log("getStreamUrl ~ Audio");
|
||||
|
||||
if (mediaSource?.TranscodingUrl) {
|
||||
return { url: `${api.basePath}${mediaSource.TranscodingUrl}`, sessionId };
|
||||
}
|
||||
|
||||
const searchParams = new URLSearchParams({
|
||||
UserId: userId,
|
||||
DeviceId: api.deviceInfo.id,
|
||||
MaxStreamingBitrate: "140000000",
|
||||
Container:
|
||||
"opus,webm|opus,mp3,aac,m4a|aac,m4b|aac,flac,webma,webm|webma,wav,ogg",
|
||||
TranscodingContainer: "mp4",
|
||||
TranscodingProtocol: "hls",
|
||||
AudioCodec: "aac",
|
||||
api_key: api.accessToken,
|
||||
PlaySessionId: sessionData?.PlaySessionId || "",
|
||||
StartTimeTicks: "0",
|
||||
EnableRedirection: "true",
|
||||
EnableRemoteMedia: "false",
|
||||
});
|
||||
return null;
|
||||
return {
|
||||
url: `${
|
||||
api.basePath
|
||||
}/Audio/${itemId}/universal?${searchParams.toString()}`,
|
||||
sessionId,
|
||||
};
|
||||
}
|
||||
|
||||
return {
|
||||
url,
|
||||
sessionId,
|
||||
};
|
||||
throw new Error("Unsupported media type");
|
||||
};
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import { itemRouter } from "@/components/common/TouchableItemRouter";
|
||||
import { BaseItemDto } from "@jellyfin/sdk/lib/generated-client";
|
||||
import axios from "axios";
|
||||
import { writeToLog } from "./log";
|
||||
|
||||
interface IJobInput {
|
||||
deviceId?: string | null;
|
||||
@@ -108,6 +109,7 @@ export async function cancelAllJobs({ authHeader, url, deviceId }: IJobInput) {
|
||||
});
|
||||
});
|
||||
} catch (error) {
|
||||
writeToLog("ERROR", "Failed to cancel all jobs", error);
|
||||
console.error(error);
|
||||
return false;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user