From 6688469b6c261e3454d8d9ef9e207ea4498d713f Mon Sep 17 00:00:00 2001 From: Simon Eklundh Date: Sun, 9 Feb 2025 10:43:42 +0100 Subject: [PATCH] fix: fixes non-optimized downloads (#500) --- app/(auth)/(tabs)/(libraries)/_layout.tsx | 4 ++-- app/(auth)/player/direct-player.tsx | 12 ++++++------ app/_layout.tsx | 12 ++++++------ components/downloads/ActiveDownloads.tsx | 8 ++++---- hooks/useHaptic.ts | 4 ++-- hooks/useImageColors.ts | 4 ++-- hooks/useRemuxHlsToMp4.ts | 24 +++++++++++++---------- 7 files changed, 36 insertions(+), 32 deletions(-) diff --git a/app/(auth)/(tabs)/(libraries)/_layout.tsx b/app/(auth)/(tabs)/(libraries)/_layout.tsx index 84beca5a..3406bb09 100644 --- a/app/(auth)/(tabs)/(libraries)/_layout.tsx +++ b/app/(auth)/(tabs)/(libraries)/_layout.tsx @@ -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() { { + onValueChange={(newValue: string) => { updateSettings({ libraryOptions: { ...settings.libraryOptions, diff --git a/app/(auth)/player/direct-player.tsx b/app/(auth)/player/direct-player.tsx index 6dc96f2b..4a85bcaa 100644 --- a/app/(auth)/player/direct-player.tsx +++ b/app/(auth)/player/direct-player.tsx @@ -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) { diff --git a/app/_layout.tsx b/app/_layout.tsx index 8553f275..e360df9c 100644 --- a/app/_layout.tsx +++ b/app/_layout.tsx @@ -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, diff --git a/components/downloads/ActiveDownloads.tsx b/components/downloads/ActiveDownloads.tsx index 960cc3f2..7b6316f8 100644 --- a/components/downloads/ActiveDownloads.tsx +++ b/components/downloads/ActiveDownloads.tsx @@ -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 }) => { {t("home.downloads.active_downloads")} - {processes?.map((p) => ( + {processes?.map((p: JobStatus) => ( ))} @@ -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: () => { diff --git a/hooks/useHaptic.ts b/hooks/useHaptic.ts index 5e7f7e65..51b26f83 100644 --- a/hooks/useHaptic.ts +++ b/hooks/useHaptic.ts @@ -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); diff --git a/hooks/useImageColors.ts b/hooks/useImageColors.ts index b3a8ff90..4928ccc7 100644 --- a/hooks/useImageColors.ts +++ b/hooks/useImageColors.ts @@ -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); }); } diff --git a/hooks/useRemuxHlsToMp4.ts b/hooks/useRemuxHlsToMp4.ts index 9c03a5ba..925d9778 100644 --- a/hooks/useRemuxHlsToMp4.ts +++ b/hooks/useRemuxHlsToMp4.ts @@ -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 }