fix: fixes non-optimized downloads (#500)

This commit is contained in:
Simon Eklundh
2025-02-09 10:43:42 +01:00
committed by GitHub
parent ae9c30aa6d
commit 6688469b6c
7 changed files with 36 additions and 32 deletions

View File

@@ -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,

View File

@@ -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) {

View File

@@ -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,

View File

@@ -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: () => {

View File

@@ -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);

View File

@@ -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);
});
}

View File

@@ -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
}