mirror of
https://github.com/streamyfin/streamyfin.git
synced 2025-08-20 18:37:18 +02:00
fix: fixes non-optimized downloads (#500)
This commit is contained in:
@@ -153,7 +153,7 @@ export default function IndexLayout() {
|
||||
disabled={settings.libraryOptions.imageStyle === "poster"}
|
||||
key="show-titles-option"
|
||||
value={settings.libraryOptions.showTitles}
|
||||
onValueChange={(newValue) => {
|
||||
onValueChange={(newValue: string) => {
|
||||
if (settings.libraryOptions.imageStyle === "poster")
|
||||
return;
|
||||
updateSettings({
|
||||
@@ -172,7 +172,7 @@ export default function IndexLayout() {
|
||||
<DropdownMenu.CheckboxItem
|
||||
key="show-stats-option"
|
||||
value={settings.libraryOptions.showStats}
|
||||
onValueChange={(newValue) => {
|
||||
onValueChange={(newValue: string) => {
|
||||
updateSettings({
|
||||
libraryOptions: {
|
||||
...settings.libraryOptions,
|
||||
|
||||
@@ -70,9 +70,9 @@ export default function page() {
|
||||
const progress = useSharedValue(0);
|
||||
const isSeeking = useSharedValue(false);
|
||||
const cacheProgress = useSharedValue(0);
|
||||
|
||||
let getDownloadedItem = null;
|
||||
if (!Platform.isTV) {
|
||||
const getDownloadedItem = downloadProvider.useDownload();
|
||||
getDownloadedItem = downloadProvider.useDownload();
|
||||
}
|
||||
|
||||
const revalidateProgressCache = useInvalidatePlaybackProgressCache();
|
||||
@@ -386,16 +386,16 @@ export default function page() {
|
||||
|
||||
const allSubs =
|
||||
stream?.mediaSource.MediaStreams?.filter(
|
||||
(sub) => sub.Type === "Subtitle"
|
||||
(sub: { Type: string; }) => sub.Type === "Subtitle"
|
||||
) || [];
|
||||
const chosenSubtitleTrack = allSubs.find(
|
||||
(sub) => sub.Index === subtitleIndex
|
||||
(sub: { Index: number; }) => sub.Index === subtitleIndex
|
||||
);
|
||||
const allAudio =
|
||||
stream?.mediaSource.MediaStreams?.filter(
|
||||
(audio) => audio.Type === "Audio"
|
||||
(audio: { Type: string; }) => audio.Type === "Audio"
|
||||
) || [];
|
||||
const chosenAudioTrack = allAudio.find((audio) => audio.Index === audioIndex);
|
||||
const chosenAudioTrack = allAudio.find((audio: { Index: number | undefined; }) => audio.Index === audioIndex);
|
||||
|
||||
// Direct playback CASE
|
||||
if (!bitrateValue) {
|
||||
|
||||
@@ -64,14 +64,14 @@ function useNotificationObserver() {
|
||||
useEffect(() => {
|
||||
let isMounted = true;
|
||||
|
||||
function redirect(notification: Notifications.Notification) {
|
||||
function redirect(notification: typeof Notifications.Notification) {
|
||||
const url = notification.request.content.data?.url;
|
||||
if (url) {
|
||||
router.push(url);
|
||||
}
|
||||
}
|
||||
|
||||
Notifications.getLastNotificationResponseAsync().then((response) => {
|
||||
Notifications.getLastNotificationResponseAsync().then((response: { notification: any; }) => {
|
||||
if (!isMounted || !response?.notification) {
|
||||
return;
|
||||
}
|
||||
@@ -79,7 +79,7 @@ function useNotificationObserver() {
|
||||
});
|
||||
|
||||
const subscription = Notifications.addNotificationResponseReceivedListener(
|
||||
(response) => {
|
||||
(response: { notification: any; }) => {
|
||||
redirect(response.notification);
|
||||
}
|
||||
);
|
||||
@@ -127,7 +127,7 @@ if (!Platform.isTV) {
|
||||
const downloadUrl = url + "download/" + job.id;
|
||||
const tasks = await BackGroundDownloader.checkForExistingDownloads();
|
||||
|
||||
if (tasks.find((task) => task.id === job.id)) {
|
||||
if (tasks.find((task: { id: string; }) => task.id === job.id)) {
|
||||
console.log("TaskManager ~ Download already in progress: ", job.id);
|
||||
continue;
|
||||
}
|
||||
@@ -163,9 +163,9 @@ if (!Platform.isTV) {
|
||||
trigger: null,
|
||||
});
|
||||
})
|
||||
.error((error) => {
|
||||
.error((error: any) => {
|
||||
console.log("TaskManager ~ Download error: ", job.id, error);
|
||||
completeHandler(job.id);
|
||||
BackGroundDownloader.completeHandler(job.id);
|
||||
Notifications.scheduleNotificationAsync({
|
||||
content: {
|
||||
title: job.item.Name,
|
||||
|
||||
@@ -9,7 +9,7 @@ const BackGroundDownloader = !Platform.isTV
|
||||
: null;
|
||||
import { useMutation, useQueryClient } from "@tanstack/react-query";
|
||||
import { useRouter } from "expo-router";
|
||||
const FFmpegKit = !Platform.isTV ? require("ffmpeg-kit-react-native") : null;
|
||||
const FFmpegKitProvider = !Platform.isTV ? require("ffmpeg-kit-react-native") : null;
|
||||
import { useAtom } from "jotai";
|
||||
import {
|
||||
ActivityIndicator,
|
||||
@@ -42,7 +42,7 @@ export const ActiveDownloads: React.FC<Props> = ({ ...props }) => {
|
||||
<View {...props} className="bg-neutral-900 p-4 rounded-2xl">
|
||||
<Text className="text-lg font-bold mb-2">{t("home.downloads.active_downloads")}</Text>
|
||||
<View className="space-y-2">
|
||||
{processes?.map((p) => (
|
||||
{processes?.map((p: JobStatus) => (
|
||||
<DownloadCard key={p.item.Id} process={p} />
|
||||
))}
|
||||
</View>
|
||||
@@ -80,8 +80,8 @@ const DownloadCard = ({ process, ...props }: DownloadCardProps) => {
|
||||
await queryClient.refetchQueries({ queryKey: ["jobs"] });
|
||||
}
|
||||
} else {
|
||||
FFmpegKit.cancel(Number(id));
|
||||
setProcesses((prev) => prev.filter((p) => p.id !== id));
|
||||
FFmpegKitProvider.FFmpegKit.cancel(Number(id));
|
||||
setProcesses((prev: any[]) => prev.filter((p: { id: string; }) => p.id !== id));
|
||||
}
|
||||
},
|
||||
onSuccess: () => {
|
||||
|
||||
@@ -20,7 +20,7 @@ export const useHaptic = (feedbackType: HapticFeedbackType = "selection") => {
|
||||
}
|
||||
|
||||
const createHapticHandler = useCallback(
|
||||
(type: Haptics.ImpactFeedbackStyle) => {
|
||||
(type: typeof Haptics.ImpactFeedbackStyle) => {
|
||||
return Platform.OS === "web" || Platform.isTV
|
||||
? () => {}
|
||||
: () => Haptics.impactAsync(type);
|
||||
@@ -28,7 +28,7 @@ export const useHaptic = (feedbackType: HapticFeedbackType = "selection") => {
|
||||
[]
|
||||
);
|
||||
const createNotificationFeedback = useCallback(
|
||||
(type: Haptics.NotificationFeedbackType) => {
|
||||
(type: typeof Haptics.NotificationFeedbackType) => {
|
||||
return Platform.OS === "web" || Platform.isTV
|
||||
? () => {}
|
||||
: () => Haptics.notificationAsync(type);
|
||||
|
||||
@@ -70,7 +70,7 @@ export const useImageColors = ({
|
||||
fallback: "#fff",
|
||||
cache: false,
|
||||
})
|
||||
.then((colors) => {
|
||||
.then((colors: { platform: string; dominant: string; vibrant: string; detail: string; primary: string; }) => {
|
||||
let primary: string = "#fff";
|
||||
let text: string = "#000";
|
||||
let backup: string = "#fff";
|
||||
@@ -104,7 +104,7 @@ export const useImageColors = ({
|
||||
storage.set(`${source.uri}-text`, text);
|
||||
}
|
||||
})
|
||||
.catch((error) => {
|
||||
.catch((error: any) => {
|
||||
console.error("Error getting colors", error);
|
||||
});
|
||||
}
|
||||
|
||||
@@ -9,8 +9,9 @@ import {
|
||||
import { useQueryClient } from "@tanstack/react-query";
|
||||
import * as FileSystem from "expo-file-system";
|
||||
import { useRouter } from "expo-router";
|
||||
|
||||
// import { FFmpegKit, FFmpegSession, Statistics } from "ffmpeg-kit-react-native";
|
||||
const FFmpegKit = !Platform.isTV ? require("ffmpeg-kit-react-native") : null;
|
||||
const FFMPEGKitReactNative = !Platform.isTV ? require("ffmpeg-kit-react-native") : null;
|
||||
import { useAtomValue } from "jotai";
|
||||
import { useCallback } from "react";
|
||||
import { toast } from "sonner-native";
|
||||
@@ -22,6 +23,9 @@ import { JobStatus } from "@/utils/optimize-server";
|
||||
import { Platform } from "react-native";
|
||||
import { useTranslation } from "react-i18next";
|
||||
|
||||
type FFmpegSession = typeof FFMPEGKitReactNative.FFmpegSession;
|
||||
type Statistics = typeof FFMPEGKitReactNative.Statistics
|
||||
const FFmpegKit = FFMPEGKitReactNative.FFmpegKit;
|
||||
const createFFmpegCommand = (url: string, output: string) => [
|
||||
"-y", // overwrite output files without asking
|
||||
"-thread_queue_size 512", // https://ffmpeg.org/ffmpeg.html#toc-Advanced-options
|
||||
@@ -96,8 +100,8 @@ export const useRemuxHlsToMp4 = () => {
|
||||
toast.success(t("home.downloads.toasts.download_completed"));
|
||||
}
|
||||
|
||||
setProcesses((prev) => {
|
||||
return prev.filter((process) => process.itemId !== item.Id);
|
||||
setProcesses((prev: any[]) => {
|
||||
return prev.filter((process: { itemId: string | undefined; }) => process.itemId !== item.Id);
|
||||
});
|
||||
} catch (e) {
|
||||
console.error(e);
|
||||
@@ -121,8 +125,8 @@ export const useRemuxHlsToMp4 = () => {
|
||||
totalFrames > 0 ? Math.floor((processedFrames / totalFrames) * 100) : 0;
|
||||
|
||||
if (!item.Id) throw new Error("Item is undefined");
|
||||
setProcesses((prev) => {
|
||||
return prev.map((process) => {
|
||||
setProcesses((prev: any[]) => {
|
||||
return prev.map((process: { itemId: string | undefined; }) => {
|
||||
if (process.itemId === item.Id) {
|
||||
return {
|
||||
...process,
|
||||
@@ -181,13 +185,13 @@ export const useRemuxHlsToMp4 = () => {
|
||||
};
|
||||
|
||||
writeInfoLog(`useRemuxHlsToMp4 ~ startRemuxing for item ${item.Name}`);
|
||||
setProcesses((prev) => [...prev, job]);
|
||||
setProcesses((prev: any) => [...prev, job]);
|
||||
|
||||
await FFmpegKit.executeAsync(
|
||||
createFFmpegCommand(url, output).join(" "),
|
||||
(session) => completeCallback(session, item),
|
||||
(session: any) => completeCallback(session, item),
|
||||
undefined,
|
||||
(s) => statisticsCallback(s, item)
|
||||
(s: any) => statisticsCallback(s, item)
|
||||
);
|
||||
} catch (e) {
|
||||
const error = e as Error;
|
||||
@@ -196,8 +200,8 @@ export const useRemuxHlsToMp4 = () => {
|
||||
`useRemuxHlsToMp4 ~ remuxing failed for item: ${item.Name},
|
||||
Error: ${error.message}, Stack: ${error.stack}`
|
||||
);
|
||||
setProcesses((prev) => {
|
||||
return prev.filter((process) => process.itemId !== item.Id);
|
||||
setProcesses((prev: any[]) => {
|
||||
return prev.filter((process: { itemId: string | undefined; }) => process.itemId !== item.Id);
|
||||
});
|
||||
throw error; // Re-throw the error to propagate it to the caller
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user