mirror of
https://github.com/streamyfin/streamyfin.git
synced 2026-01-16 16:18:09 +00:00
Compare commits
6 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
36304ad58e | ||
|
|
baeb83581e | ||
|
|
05b7a4c50d | ||
|
|
28b67f3ad6 | ||
|
|
51cd195bfe | ||
|
|
0184e266a0 |
2
.github/workflows/linting.yml
vendored
2
.github/workflows/linting.yml
vendored
@@ -107,7 +107,7 @@ jobs:
|
|||||||
fetch-depth: 0
|
fetch-depth: 0
|
||||||
|
|
||||||
- name: "🟢 Setup Node.js"
|
- name: "🟢 Setup Node.js"
|
||||||
uses: actions/setup-node@395ad3262231945c25e8478fd5baf05154b1d79f # v6.1.0
|
uses: actions/setup-node@6044e13b5dc448c55e2357c09f80417699197238 # v6.2.0
|
||||||
with:
|
with:
|
||||||
node-version: '24.x'
|
node-version: '24.x'
|
||||||
|
|
||||||
|
|||||||
2
.github/workflows/update-issue-form.yml
vendored
2
.github/workflows/update-issue-form.yml
vendored
@@ -21,7 +21,7 @@ jobs:
|
|||||||
uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
|
uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
|
||||||
|
|
||||||
- name: "🟢 Setup Node.js"
|
- name: "🟢 Setup Node.js"
|
||||||
uses: actions/setup-node@395ad3262231945c25e8478fd5baf05154b1d79f # v6.1.0
|
uses: actions/setup-node@6044e13b5dc448c55e2357c09f80417699197238 # v6.2.0
|
||||||
with:
|
with:
|
||||||
node-version: '24.x'
|
node-version: '24.x'
|
||||||
cache: 'npm'
|
cache: 'npm'
|
||||||
|
|||||||
@@ -531,7 +531,11 @@ export default function page() {
|
|||||||
subtitleIndex,
|
subtitleIndex,
|
||||||
isTranscoding,
|
isTranscoding,
|
||||||
);
|
);
|
||||||
const initialAudioId = getMpvAudioId(mediaSource, audioIndex);
|
const initialAudioId = getMpvAudioId(
|
||||||
|
mediaSource,
|
||||||
|
audioIndex,
|
||||||
|
isTranscoding,
|
||||||
|
);
|
||||||
|
|
||||||
// Calculate start position directly here to avoid timing issues
|
// Calculate start position directly here to avoid timing issues
|
||||||
const startTicks = playbackPositionFromUrl
|
const startTicks = playbackPositionFromUrl
|
||||||
|
|||||||
4
bun.lock
4
bun.lock
@@ -74,7 +74,7 @@
|
|||||||
"react-native-ios-context-menu": "^3.2.1",
|
"react-native-ios-context-menu": "^3.2.1",
|
||||||
"react-native-ios-utilities": "5.2.0",
|
"react-native-ios-utilities": "5.2.0",
|
||||||
"react-native-mmkv": "4.1.1",
|
"react-native-mmkv": "4.1.1",
|
||||||
"react-native-nitro-modules": "0.32.1",
|
"react-native-nitro-modules": "0.33.1",
|
||||||
"react-native-pager-view": "^6.9.1",
|
"react-native-pager-view": "^6.9.1",
|
||||||
"react-native-reanimated": "~4.1.1",
|
"react-native-reanimated": "~4.1.1",
|
||||||
"react-native-reanimated-carousel": "4.0.3",
|
"react-native-reanimated-carousel": "4.0.3",
|
||||||
@@ -1678,7 +1678,7 @@
|
|||||||
|
|
||||||
"react-native-mmkv": ["react-native-mmkv@4.1.1", "", { "peerDependencies": { "react": "*", "react-native": "*", "react-native-nitro-modules": "*" } }, "sha512-nYFjM27l7zVhIiyAqWEFRagGASecb13JMIlzAuOeakRRz9GMJ49hCQntUBE2aeuZRE4u4ehSqTOomB0mTF56Ew=="],
|
"react-native-mmkv": ["react-native-mmkv@4.1.1", "", { "peerDependencies": { "react": "*", "react-native": "*", "react-native-nitro-modules": "*" } }, "sha512-nYFjM27l7zVhIiyAqWEFRagGASecb13JMIlzAuOeakRRz9GMJ49hCQntUBE2aeuZRE4u4ehSqTOomB0mTF56Ew=="],
|
||||||
|
|
||||||
"react-native-nitro-modules": ["react-native-nitro-modules@0.32.1", "", { "peerDependencies": { "react": "*", "react-native": "*" } }, "sha512-V+Vy76e4fxRxgVGu5Uh3cBPvuFQW8fM1OUKk1mqEA/JawjhX+hxHtBhpfuvNjV0BnV/uXCIg8/eK+rTpB6tqFg=="],
|
"react-native-nitro-modules": ["react-native-nitro-modules@0.33.1", "", { "peerDependencies": { "react": "*", "react-native": "*" } }, "sha512-Kdo8qiqlkGAEs7fq29i0yiZs0Gf7ucmMiFsH8PH4uzsnSGEt2CQRBJGnQKKMl9vJYL8e7rzA0TZKRwO/L8G/Sg=="],
|
||||||
|
|
||||||
"react-native-pager-view": ["react-native-pager-view@6.9.1", "", { "peerDependencies": { "react": "*", "react-native": "*" } }, "sha512-uUT0MMMbNtoSbxe9pRvdJJKEi9snjuJ3fXlZhG8F2vVMOBJVt/AFtqMPUHu9yMflmqOr08PewKzj9EPl/Yj+Gw=="],
|
"react-native-pager-view": ["react-native-pager-view@6.9.1", "", { "peerDependencies": { "react": "*", "react-native": "*" } }, "sha512-uUT0MMMbNtoSbxe9pRvdJJKEi9snjuJ3fXlZhG8F2vVMOBJVt/AFtqMPUHu9yMflmqOr08PewKzj9EPl/Yj+Gw=="],
|
||||||
|
|
||||||
|
|||||||
@@ -94,7 +94,7 @@
|
|||||||
"react-native-ios-context-menu": "^3.2.1",
|
"react-native-ios-context-menu": "^3.2.1",
|
||||||
"react-native-ios-utilities": "5.2.0",
|
"react-native-ios-utilities": "5.2.0",
|
||||||
"react-native-mmkv": "4.1.1",
|
"react-native-mmkv": "4.1.1",
|
||||||
"react-native-nitro-modules": "0.32.1",
|
"react-native-nitro-modules": "0.33.1",
|
||||||
"react-native-pager-view": "^6.9.1",
|
"react-native-pager-view": "^6.9.1",
|
||||||
"react-native-reanimated": "~4.1.1",
|
"react-native-reanimated": "~4.1.1",
|
||||||
"react-native-reanimated-carousel": "4.0.3",
|
"react-native-reanimated-carousel": "4.0.3",
|
||||||
|
|||||||
@@ -147,7 +147,7 @@ export const JellyfinProvider: React.FC<{ children: ReactNode }> = ({
|
|||||||
}, [api, deviceId, headers]);
|
}, [api, deviceId, headers]);
|
||||||
|
|
||||||
const pollQuickConnect = useCallback(async () => {
|
const pollQuickConnect = useCallback(async () => {
|
||||||
if (!api || !secret) return;
|
if (!api || !secret || !jellyfin) return;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const response = await api.axiosInstance.get(
|
const response = await api.axiosInstance.get(
|
||||||
@@ -169,8 +169,8 @@ export const JellyfinProvider: React.FC<{ children: ReactNode }> = ({
|
|||||||
);
|
);
|
||||||
|
|
||||||
const { AccessToken, User } = authResponse.data;
|
const { AccessToken, User } = authResponse.data;
|
||||||
api.accessToken = AccessToken;
|
|
||||||
setUser(User);
|
setUser(User);
|
||||||
|
setApi(jellyfin.createApi(api.basePath, AccessToken));
|
||||||
storage.set("token", AccessToken);
|
storage.set("token", AccessToken);
|
||||||
storage.set("user", JSON.stringify(User));
|
storage.set("user", JSON.stringify(User));
|
||||||
return true;
|
return true;
|
||||||
@@ -186,7 +186,7 @@ export const JellyfinProvider: React.FC<{ children: ReactNode }> = ({
|
|||||||
console.error("Error polling Quick Connect:", error);
|
console.error("Error polling Quick Connect:", error);
|
||||||
throw error;
|
throw error;
|
||||||
}
|
}
|
||||||
}, [api, secret, headers]);
|
}, [api, secret, headers, jellyfin]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
(async () => {
|
(async () => {
|
||||||
|
|||||||
@@ -91,21 +91,32 @@ export const getMpvSubtitleId = (
|
|||||||
/**
|
/**
|
||||||
* Calculate the MPV track ID for a given Jellyfin audio index.
|
* Calculate the MPV track ID for a given Jellyfin audio index.
|
||||||
*
|
*
|
||||||
* Audio tracks are simpler - they're always in MPV (no burn-in like image subs).
|
* For direct play: Audio tracks map to their position in the file (1-based).
|
||||||
|
* For transcoding: Only ONE audio track exists in the HLS stream (the selected one),
|
||||||
|
* so we should return 1 or undefined to use the default track.
|
||||||
|
*
|
||||||
* MPV track IDs are 1-based.
|
* MPV track IDs are 1-based.
|
||||||
*
|
*
|
||||||
* @param mediaSource - The media source containing audio streams
|
* @param mediaSource - The media source containing audio streams
|
||||||
* @param jellyfinAudioIndex - The Jellyfin server-side audio index
|
* @param jellyfinAudioIndex - The Jellyfin server-side audio index
|
||||||
|
* @param isTranscoding - Whether the stream is being transcoded
|
||||||
* @returns MPV track ID (1-based), or undefined if not found
|
* @returns MPV track ID (1-based), or undefined if not found
|
||||||
*/
|
*/
|
||||||
export const getMpvAudioId = (
|
export const getMpvAudioId = (
|
||||||
mediaSource: MediaSourceInfo | null | undefined,
|
mediaSource: MediaSourceInfo | null | undefined,
|
||||||
jellyfinAudioIndex: number | undefined,
|
jellyfinAudioIndex: number | undefined,
|
||||||
|
isTranscoding: boolean,
|
||||||
): number | undefined => {
|
): number | undefined => {
|
||||||
if (jellyfinAudioIndex === undefined) {
|
if (jellyfinAudioIndex === undefined) {
|
||||||
return undefined;
|
return undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// When transcoding, Jellyfin only includes the selected audio track in the HLS stream.
|
||||||
|
// So there's only 1 audio track - no need to specify an ID.
|
||||||
|
if (isTranscoding) {
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
|
||||||
const allAudio =
|
const allAudio =
|
||||||
mediaSource?.MediaStreams?.filter((s) => s.Type === "Audio") || [];
|
mediaSource?.MediaStreams?.filter((s) => s.Type === "Audio") || [];
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user