fix: download url not correct for direct streams

This commit is contained in:
Fredrik Burmester
2024-08-29 12:58:51 +02:00
parent dc02db6463
commit 78189c8246
9 changed files with 47 additions and 34 deletions

View File

@@ -2,7 +2,7 @@
"expo": { "expo": {
"name": "Streamyfin", "name": "Streamyfin",
"slug": "streamyfin", "slug": "streamyfin",
"version": "0.10.1", "version": "0.10.2",
"orientation": "default", "orientation": "default",
"icon": "./assets/images/icon.png", "icon": "./assets/images/icon.png",
"scheme": "streamyfin", "scheme": "streamyfin",
@@ -33,7 +33,7 @@
}, },
"android": { "android": {
"jsEngine": "hermes", "jsEngine": "hermes",
"versionCode": 30, "versionCode": 31,
"adaptiveIcon": { "adaptiveIcon": {
"foregroundImage": "./assets/images/icon.png" "foregroundImage": "./assets/images/icon.png"
}, },

View File

@@ -65,15 +65,14 @@ const downloads: React.FC = () => {
} }
return ( return (
<ScrollView> <ScrollView
<View contentContainerStyle={{
className="px-4 py-4" paddingLeft: insets.left,
style={{ paddingRight: insets.right,
paddingLeft: insets.left, paddingBottom: 100,
paddingRight: insets.right, }}
paddingBottom: 100, >
}} <View className="px-4 py-4">
>
<View className="mb-4 flex flex-col space-y-4"> <View className="mb-4 flex flex-col space-y-4">
<View> <View>
<Text className="text-2xl font-bold mb-2">Queue</Text> <Text className="text-2xl font-bold mb-2">Queue</Text>

View File

@@ -27,9 +27,15 @@ export default function settings() {
const insets = useSafeAreaInsets(); const insets = useSafeAreaInsets();
return ( return (
<ScrollView> <ScrollView
contentContainerStyle={{
paddingLeft: insets.left,
paddingRight: insets.right,
paddingBottom: 100,
}}
>
<View <View
className="p-4 flex flex-col gap-y-4 pb-12" className="p-4 flex flex-col gap-y-4"
style={{ style={{
paddingLeft: insets.left, paddingLeft: insets.left,
paddingRight: insets.right, paddingRight: insets.right,

View File

@@ -145,15 +145,13 @@ export const DownloadItem: React.FC<DownloadProps> = ({ item, ...props }) => {
item.Id item.Id
}/universal?${searchParams.toString()}`; }/universal?${searchParams.toString()}`;
} }
} } else if (mediaSource.TranscodingUrl) {
if (mediaSource.TranscodingUrl) {
console.log("Using transcoded stream!"); console.log("Using transcoded stream!");
url = `${api.basePath}${mediaSource.TranscodingUrl}`; url = `${api.basePath}${mediaSource.TranscodingUrl}`;
} else {
throw new Error("No transcoding url");
} }
if (!url) throw new Error("No url");
return await startRemuxing(url); return await startRemuxing(url);
}, [ }, [
api, api,

View File

@@ -36,6 +36,14 @@ export const MediaSourceSelector: React.FC<Props> = ({
if (mediaSources?.length) onChange(mediaSources[0]); if (mediaSources?.length) onChange(mediaSources[0]);
}, [mediaSources]); }, [mediaSources]);
const name = (name?: string | null) => {
if (name && name.length > 40)
return (
name.substring(0, 20) + " [...] " + name.substring(name.length - 20)
);
return name;
};
return ( return (
<View <View
className="flex shrink" className="flex shrink"
@@ -69,7 +77,9 @@ export const MediaSourceSelector: React.FC<Props> = ({
onChange(source); onChange(source);
}} }}
> >
<DropdownMenu.ItemTitle>{source.Name}</DropdownMenu.ItemTitle> <DropdownMenu.ItemTitle>
{name(source.Name)}
</DropdownMenu.ItemTitle>
</DropdownMenu.Item> </DropdownMenu.Item>
))} ))}
</DropdownMenu.Content> </DropdownMenu.Content>

View File

@@ -1,11 +1,9 @@
import { useImageColors } from "@/hooks/useImageColors"; import { useImageColors } from "@/hooks/useImageColors";
import { apiAtom } from "@/providers/JellyfinProvider"; import { apiAtom } from "@/providers/JellyfinProvider";
import { itemThemeColorAtom } from "@/utils/atoms/primaryColor";
import { BaseItemDto } from "@jellyfin/sdk/lib/generated-client/models"; import { BaseItemDto } from "@jellyfin/sdk/lib/generated-client/models";
import { Image, ImageProps, ImageSource } from "expo-image"; import { Image, ImageProps, ImageSource } from "expo-image";
import { useAtom } from "jotai"; import { useAtom } from "jotai";
import { useEffect, useMemo } from "react"; import { useMemo } from "react";
import { getColors } from "react-native-image-colors";
interface Props extends ImageProps { interface Props extends ImageProps {
item: BaseItemDto; item: BaseItemDto;

View File

@@ -21,13 +21,13 @@
} }
}, },
"production": { "production": {
"channel": "0.10.1", "channel": "0.10.2",
"android": { "android": {
"image": "latest" "image": "latest"
} }
}, },
"production-apk": { "production-apk": {
"channel": "0.10.1", "channel": "0.10.2",
"android": { "android": {
"buildType": "apk", "buildType": "apk",
"image": "latest" "image": "latest"

View File

@@ -62,7 +62,7 @@ export const JellyfinProvider: React.FC<{ children: ReactNode }> = ({
setJellyfin( setJellyfin(
() => () =>
new Jellyfin({ new Jellyfin({
clientInfo: { name: "Streamyfin", version: "0.10.1" }, clientInfo: { name: "Streamyfin", version: "0.10.2" },
deviceInfo: { name: Platform.OS === "ios" ? "iOS" : "Android", id }, deviceInfo: { name: Platform.OS === "ios" ? "iOS" : "Android", id },
}) })
); );
@@ -80,7 +80,7 @@ export const JellyfinProvider: React.FC<{ children: ReactNode }> = ({
return { return {
authorization: `MediaBrowser Client="Streamyfin", Device=${ authorization: `MediaBrowser Client="Streamyfin", Device=${
Platform.OS === "android" ? "Android" : "iOS" Platform.OS === "android" ? "Android" : "iOS"
}, DeviceId="${deviceId}", Version="0.10.1"`, }, DeviceId="${deviceId}", Version="0.10.2"`,
}; };
}, [deviceId]); }, [deviceId]);

View File

@@ -76,10 +76,12 @@ export const getStreamUrl = async ({
throw new Error("no PlaySessionId"); throw new Error("no PlaySessionId");
} }
let url: string | null | undefined;
if (mediaSource.SupportsDirectPlay || forceDirectPlay === true) { if (mediaSource.SupportsDirectPlay || forceDirectPlay === true) {
if (item.MediaType === "Video") { if (item.MediaType === "Video") {
console.log("Using direct stream for video!"); console.log("Using direct stream for video!");
return `${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}`; 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") { } else if (item.MediaType === "Audio") {
console.log("Using direct stream for audio!"); console.log("Using direct stream for audio!");
const searchParams = new URLSearchParams({ const searchParams = new URLSearchParams({
@@ -97,16 +99,16 @@ export const getStreamUrl = async ({
EnableRedirection: "true", EnableRedirection: "true",
EnableRemoteMedia: "false", EnableRemoteMedia: "false",
}); });
return `${ url = `${
api.basePath api.basePath
}/Audio/${itemId}/universal?${searchParams.toString()}`; }/Audio/${itemId}/universal?${searchParams.toString()}`;
} }
} else if (mediaSource.TranscodingUrl) {
console.log("Using transcoded stream!");
url = `${api.basePath}${mediaSource.TranscodingUrl}`;
} }
if (mediaSource.TranscodingUrl) { if (!url) throw new Error("No url");
console.log("Using transcoded stream!");
return `${api.basePath}${mediaSource.TranscodingUrl}`; return url;
} else {
throw new Error("No transcoding url");
}
}; };