mirror of
https://github.com/movie-web/native-app.git
synced 2025-09-13 18:13:25 +00:00
Compare commits
1 Commits
daba32627b
...
f6a265f17b
Author | SHA1 | Date | |
---|---|---|---|
|
f6a265f17b |
@@ -41,7 +41,7 @@ export default function Page() {
|
|||||||
title: download?.media.title ?? "Downloads",
|
title: download?.media.title ?? "Downloads",
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
<YStack gap="$4">
|
<YStack gap="$3">
|
||||||
{download?.downloads.map((download) => {
|
{download?.downloads.map((download) => {
|
||||||
return (
|
return (
|
||||||
<DownloadItem
|
<DownloadItem
|
||||||
|
@@ -37,7 +37,7 @@ const formatBytes = (bytes: number, decimals = 2) => {
|
|||||||
const dm = decimals < 0 ? 0 : decimals;
|
const dm = decimals < 0 ? 0 : decimals;
|
||||||
const sizes = ["Bytes", "KB", "MB", "GB", "TB", "PB", "EB", "ZB", "YB"];
|
const sizes = ["Bytes", "KB", "MB", "GB", "TB", "PB", "EB", "ZB", "YB"];
|
||||||
const i = Math.floor(Math.log(bytes) / Math.log(k));
|
const i = Math.floor(Math.log(bytes) / Math.log(k));
|
||||||
return `${parseFloat((bytes / Math.pow(k, i)).toFixed(dm))} ${sizes[i]}`;
|
return parseFloat((bytes / Math.pow(k, i)).toFixed(dm)) + " " + sizes[i];
|
||||||
};
|
};
|
||||||
|
|
||||||
export function DownloadItem(props: DownloadItemProps) {
|
export function DownloadItem(props: DownloadItemProps) {
|
||||||
@@ -100,19 +100,14 @@ export function DownloadItem(props: DownloadItemProps) {
|
|||||||
height="100%"
|
height="100%"
|
||||||
/>
|
/>
|
||||||
</View>
|
</View>
|
||||||
<YStack gap="$2" flex={1}>
|
<YStack gap="$2">
|
||||||
<XStack justifyContent="space-between" alignItems="center">
|
<XStack gap="$6" maxWidth="65%">
|
||||||
<Text
|
<Text fontWeight="$bold" ellipse flexGrow={1}>
|
||||||
fontWeight="$bold"
|
|
||||||
numberOfLines={1}
|
|
||||||
ellipsizeMode="tail"
|
|
||||||
flex={1}
|
|
||||||
>
|
|
||||||
{props.item.media.type === "show" &&
|
{props.item.media.type === "show" &&
|
||||||
`${mapSeasonAndEpisodeNumberToText(
|
mapSeasonAndEpisodeNumberToText(
|
||||||
props.item.media.season.number,
|
props.item.media.season.number,
|
||||||
props.item.media.episode.number,
|
props.item.media.episode.number,
|
||||||
)} `}
|
) + " "}
|
||||||
{props.item.media.title}
|
{props.item.media.title}
|
||||||
</Text>
|
</Text>
|
||||||
{props.item.type !== "hls" && (
|
{props.item.type !== "hls" && (
|
||||||
|
@@ -43,7 +43,7 @@ export default function ScreenLayout({
|
|||||||
start={[0, 0]}
|
start={[0, 0]}
|
||||||
end={[1, 1]}
|
end={[1, 1]}
|
||||||
flexGrow={1}
|
flexGrow={1}
|
||||||
paddingTop={showHeader ? insets.top + 16 : insets.top + 50}
|
paddingTop={showHeader ? insets.top : insets.top + 50}
|
||||||
>
|
>
|
||||||
{showHeader && <Header />}
|
{showHeader && <Header />}
|
||||||
<ScrollView
|
<ScrollView
|
||||||
|
@@ -28,9 +28,11 @@ export const BottomControls = () => {
|
|||||||
const { currentTime, remainingTime } = useMemo(() => {
|
const { currentTime, remainingTime } = useMemo(() => {
|
||||||
if (status?.isLoaded) {
|
if (status?.isLoaded) {
|
||||||
const current = mapMillisecondsToTime(status.positionMillis ?? 0);
|
const current = mapMillisecondsToTime(status.positionMillis ?? 0);
|
||||||
const remaining = `-${mapMillisecondsToTime(
|
const remaining =
|
||||||
|
"-" +
|
||||||
|
mapMillisecondsToTime(
|
||||||
(status.durationMillis ?? 0) - (status.positionMillis ?? 0),
|
(status.durationMillis ?? 0) - (status.positionMillis ?? 0),
|
||||||
)}`;
|
);
|
||||||
return { currentTime: current, remainingTime: remaining };
|
return { currentTime: current, remainingTime: remaining };
|
||||||
} else {
|
} else {
|
||||||
return { currentTime: "", remainingTime: "" };
|
return { currentTime: "", remainingTime: "" };
|
||||||
|
@@ -124,12 +124,11 @@ export const useDownloadManager = () => {
|
|||||||
[setDownloads],
|
[setDownloads],
|
||||||
);
|
);
|
||||||
|
|
||||||
const saveFileToMediaLibraryAndDeleteOriginal = useCallback(
|
const saveFileToMediaLibraryAndDeleteOriginal = async (
|
||||||
async (fileUri: string, download: Download): Promise<Asset | void> => {
|
fileUri: string,
|
||||||
console.log(
|
download: Download,
|
||||||
"Saving file to media library and deleting original",
|
): Promise<Asset | void> => {
|
||||||
fileUri,
|
console.log("Saving file to media library and deleting original", fileUri);
|
||||||
);
|
|
||||||
try {
|
try {
|
||||||
updateDownloadItem(download.id, { status: "importing" });
|
updateDownloadItem(download.id, { status: "importing" });
|
||||||
|
|
||||||
@@ -152,12 +151,9 @@ export const useDownloadManager = () => {
|
|||||||
burntOptions: { preset: "error" },
|
burntOptions: { preset: "error" },
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
},
|
};
|
||||||
[updateDownloadItem, showToast],
|
|
||||||
);
|
|
||||||
|
|
||||||
const downloadMP4 = useCallback(
|
const downloadMP4 = async (
|
||||||
async (
|
|
||||||
url: string,
|
url: string,
|
||||||
downloadItem: Download,
|
downloadItem: Download,
|
||||||
headers: Record<string, string>,
|
headers: Record<string, string>,
|
||||||
@@ -188,13 +184,13 @@ export const useDownloadManager = () => {
|
|||||||
lastTimestamp = currentTime;
|
lastTimestamp = currentTime;
|
||||||
};
|
};
|
||||||
|
|
||||||
const fileUri = `${FileSystem.cacheDirectory}movie-web/${url.split("/").pop()}`;
|
const fileUri = `${FileSystem.cacheDirectory}movie-web${url.split("/").pop()}`;
|
||||||
if (
|
if (
|
||||||
!(
|
!(await FileSystem.getInfoAsync(`${FileSystem.cacheDirectory}movie-web`))
|
||||||
await FileSystem.getInfoAsync(`${FileSystem.cacheDirectory}movie-web`)
|
.exists
|
||||||
).exists
|
|
||||||
) {
|
) {
|
||||||
await ensureDirExists(`${FileSystem.cacheDirectory}movie-web`);
|
console.error("Cache directory is unavailable");
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const downloadResumable = FileSystem.createDownloadResumable(
|
const downloadResumable = FileSystem.createDownloadResumable(
|
||||||
@@ -218,9 +214,7 @@ export const useDownloadManager = () => {
|
|||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.error(e);
|
console.error(e);
|
||||||
}
|
}
|
||||||
},
|
};
|
||||||
[updateDownloadItem, saveFileToMediaLibraryAndDeleteOriginal],
|
|
||||||
);
|
|
||||||
|
|
||||||
const cleanupDownload = useCallback(
|
const cleanupDownload = useCallback(
|
||||||
async (segmentDir: string, download: Download) => {
|
async (segmentDir: string, download: Download) => {
|
||||||
@@ -230,8 +224,7 @@ export const useDownloadManager = () => {
|
|||||||
[removeDownload],
|
[removeDownload],
|
||||||
);
|
);
|
||||||
|
|
||||||
const downloadHLS = useCallback(
|
const downloadHLS = async (
|
||||||
async (
|
|
||||||
url: string,
|
url: string,
|
||||||
download: Download,
|
download: Download,
|
||||||
headers: Record<string, string>,
|
headers: Record<string, string>,
|
||||||
@@ -296,23 +289,11 @@ export const useDownloadManager = () => {
|
|||||||
localSegmentPaths,
|
localSegmentPaths,
|
||||||
`${FileSystem.cacheDirectory}movie-web/output.mp4`,
|
`${FileSystem.cacheDirectory}movie-web/output.mp4`,
|
||||||
);
|
);
|
||||||
const asset = await saveFileToMediaLibraryAndDeleteOriginal(
|
const asset = await saveFileToMediaLibraryAndDeleteOriginal(uri, download);
|
||||||
uri,
|
|
||||||
download,
|
|
||||||
);
|
|
||||||
return asset;
|
return asset;
|
||||||
},
|
};
|
||||||
[
|
|
||||||
getCancellationFlag,
|
|
||||||
updateDownloadItem,
|
|
||||||
saveFileToMediaLibraryAndDeleteOriginal,
|
|
||||||
removeDownload,
|
|
||||||
cleanupDownload,
|
|
||||||
],
|
|
||||||
);
|
|
||||||
|
|
||||||
const startDownload = useCallback(
|
const startDownload = async (
|
||||||
async (
|
|
||||||
url: string,
|
url: string,
|
||||||
type: "mp4" | "hls",
|
type: "mp4" | "hls",
|
||||||
media: ScrapeMedia,
|
media: ScrapeMedia,
|
||||||
@@ -398,9 +379,7 @@ export const useDownloadManager = () => {
|
|||||||
const asset = await downloadHLS(url, newDownload, headers ?? {});
|
const asset = await downloadHLS(url, newDownload, headers ?? {});
|
||||||
return asset;
|
return asset;
|
||||||
}
|
}
|
||||||
},
|
};
|
||||||
[downloads, showToast, setDownloads, downloadMP4, downloadHLS],
|
|
||||||
);
|
|
||||||
|
|
||||||
const downloadSegment = async (
|
const downloadSegment = async (
|
||||||
segmentUrl: string,
|
segmentUrl: string,
|
||||||
|
@@ -29,7 +29,7 @@
|
|||||||
},
|
},
|
||||||
"prettier": "@movie-web/prettier-config",
|
"prettier": "@movie-web/prettier-config",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@movie-web/providers": "^2.3.0",
|
"@movie-web/providers": "^2.2.9",
|
||||||
"parse-hls": "^1.0.7",
|
"parse-hls": "^1.0.7",
|
||||||
"srt-webvtt": "^2.0.0",
|
"srt-webvtt": "^2.0.0",
|
||||||
"tmdb-ts": "^1.6.1"
|
"tmdb-ts": "^1.6.1"
|
||||||
|
@@ -228,7 +228,7 @@ export async function findHLSQuality(
|
|||||||
const chosenQuality = sortedStreams[highest ? 0 : sortedStreams.length - 1];
|
const chosenQuality = sortedStreams[highest ? 0 : sortedStreams.length - 1];
|
||||||
if (!chosenQuality) return null;
|
if (!chosenQuality) return null;
|
||||||
|
|
||||||
return constructFullUrl(playlistUrl, chosenQuality.uri);
|
return chosenQuality.uri;
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
590
pnpm-lock.yaml
generated
590
pnpm-lock.yaml
generated
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user