mirror of
https://github.com/streamyfin/streamyfin.git
synced 2026-01-15 23:59:08 +00:00
wip
This commit is contained in:
@@ -33,18 +33,17 @@ export const getStreamUrl = async ({
|
||||
forceDirectPlay?: boolean;
|
||||
height?: number;
|
||||
mediaSourceId?: string | null;
|
||||
}) => {
|
||||
}): Promise<{
|
||||
url: string | null | undefined;
|
||||
sessionId: string | null | undefined;
|
||||
} | null> => {
|
||||
if (!api || !userId || !item?.Id) {
|
||||
console.log("getStreamUrl: missing params", {
|
||||
api: api?.basePath,
|
||||
userId,
|
||||
item: item?.Id,
|
||||
});
|
||||
return null;
|
||||
}
|
||||
|
||||
let mediaSource: MediaSourceInfo | undefined;
|
||||
let url: string | null | undefined;
|
||||
let sessionId: string | null | undefined;
|
||||
|
||||
if (item.Type === "Program") {
|
||||
const res0 = await getMediaInfoApi(api).getPlaybackInfo(
|
||||
@@ -67,35 +66,67 @@ export const getStreamUrl = async ({
|
||||
}
|
||||
);
|
||||
const transcodeUrl = res0.data.MediaSources?.[0].TranscodingUrl;
|
||||
if (transcodeUrl) return `${api.basePath}${transcodeUrl}`;
|
||||
sessionId = res0.data.PlaySessionId;
|
||||
|
||||
if (transcodeUrl) {
|
||||
return { url: `${api.basePath}${transcodeUrl}`, sessionId };
|
||||
}
|
||||
}
|
||||
|
||||
const itemId = item.Id;
|
||||
|
||||
const res2 = await api.axiosInstance.post(
|
||||
`${api.basePath}/Items/${itemId}/PlaybackInfo`,
|
||||
// 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(
|
||||
{
|
||||
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,
|
||||
userId,
|
||||
itemId: item.Id!,
|
||||
},
|
||||
{
|
||||
headers: getAuthHeaders(api),
|
||||
method: "POST",
|
||||
data: {
|
||||
deviceProfile,
|
||||
userId,
|
||||
maxStreamingBitrate,
|
||||
startTimeTicks,
|
||||
enableTranscoding: maxStreamingBitrate ? true : undefined,
|
||||
autoOpenLiveStream: true,
|
||||
mediaSourceId,
|
||||
allowVideoStreamCopy: maxStreamingBitrate ? false : true,
|
||||
audioStreamIndex,
|
||||
subtitleStreamIndex,
|
||||
deInterlace: true,
|
||||
breakOnNonKeyFrames: false,
|
||||
copyTimestamps: false,
|
||||
enableMpegtsM2TsMode: false,
|
||||
},
|
||||
}
|
||||
);
|
||||
|
||||
mediaSource = res2.data.MediaSources.find(
|
||||
sessionId = res2.data.PlaySessionId;
|
||||
|
||||
mediaSource = res2.data.MediaSources?.find(
|
||||
(source: MediaSourceInfo) => source.Id === mediaSourceId
|
||||
);
|
||||
|
||||
@@ -136,5 +167,8 @@ export const getStreamUrl = async ({
|
||||
return null;
|
||||
}
|
||||
|
||||
return url;
|
||||
return {
|
||||
url,
|
||||
sessionId,
|
||||
};
|
||||
};
|
||||
|
||||
@@ -1,68 +0,0 @@
|
||||
import { Api } from "@jellyfin/sdk";
|
||||
import { AxiosError } from "axios";
|
||||
import { getAuthHeaders } from "../jellyfin";
|
||||
|
||||
interface PlaybackStoppedParams {
|
||||
api: Api | null | undefined;
|
||||
sessionId: string | null | undefined;
|
||||
itemId: string | null | undefined;
|
||||
positionTicks: number | null | undefined;
|
||||
}
|
||||
|
||||
/**
|
||||
* Reports playback stopped event to the Jellyfin server.
|
||||
*
|
||||
* @param {PlaybackStoppedParams} params - The parameters for the report.
|
||||
* @param {Api} params.api - The Jellyfin API instance.
|
||||
* @param {string} params.sessionId - The session ID.
|
||||
* @param {string} params.itemId - The item ID.
|
||||
* @param {number} params.positionTicks - The playback position in ticks.
|
||||
*/
|
||||
export const reportPlaybackStopped = async ({
|
||||
api,
|
||||
sessionId,
|
||||
itemId,
|
||||
positionTicks,
|
||||
}: PlaybackStoppedParams): Promise<void> => {
|
||||
if (!positionTicks || positionTicks === 0) return;
|
||||
|
||||
if (!api) {
|
||||
console.error("Missing api");
|
||||
return;
|
||||
}
|
||||
|
||||
if (!sessionId) {
|
||||
console.error("Missing sessionId", sessionId);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!itemId) {
|
||||
console.error("Missing itemId");
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
const url = `${api.basePath}/PlayingItems/${itemId}`;
|
||||
const params = {
|
||||
playSessionId: sessionId,
|
||||
positionTicks: Math.round(positionTicks),
|
||||
MediaSourceId: itemId,
|
||||
IsPaused: true,
|
||||
};
|
||||
const headers = getAuthHeaders(api);
|
||||
|
||||
// Send DELETE request to report playback stopped
|
||||
await api.axiosInstance.delete(url, { params, headers });
|
||||
} catch (error) {
|
||||
// Log the error with additional context
|
||||
if (error instanceof AxiosError) {
|
||||
console.error(
|
||||
"Failed to report playback progress",
|
||||
error.message,
|
||||
error.response?.data
|
||||
);
|
||||
} else {
|
||||
console.error("Failed to report playback progress", error);
|
||||
}
|
||||
}
|
||||
};
|
||||
Reference in New Issue
Block a user