mirror of
https://github.com/movie-web/native-app.git
synced 2025-09-13 16:33:26 +00:00
refactor: make hls downloads also use background task
This commit is contained in:
@@ -1,7 +1,7 @@
|
|||||||
import type { DownloadTask } from "@kesha-antonov/react-native-background-downloader";
|
import type { DownloadTask } from "@kesha-antonov/react-native-background-downloader";
|
||||||
import type { Asset } from "expo-media-library";
|
import type { Asset } from "expo-media-library";
|
||||||
import type { ReactNode } from "react";
|
import type { ReactNode } from "react";
|
||||||
import React, { createContext, useCallback, useContext, useEffect, useState } from "react";
|
import React, { createContext, useContext, useEffect, useState } from "react";
|
||||||
import * as FileSystem from "expo-file-system";
|
import * as FileSystem from "expo-file-system";
|
||||||
import * as MediaLibrary from "expo-media-library";
|
import * as MediaLibrary from "expo-media-library";
|
||||||
import {
|
import {
|
||||||
@@ -88,26 +88,26 @@ export const DownloadManagerProvider: React.FC<{ children: ReactNode }> = ({
|
|||||||
useDownloadHistoryStore.setState({ downloads });
|
useDownloadHistoryStore.setState({ downloads });
|
||||||
}, [downloads]);
|
}, [downloads]);
|
||||||
|
|
||||||
const checkRunningTasks = useCallback(async () => {
|
|
||||||
const existingTasks = await checkForExistingDownloads();
|
|
||||||
existingTasks.forEach((task) => {
|
|
||||||
task
|
|
||||||
.progress(({ bytesDownloaded, bytesTotal }) => {
|
|
||||||
const progress = bytesDownloaded / bytesTotal;
|
|
||||||
updateDownloadItem(task.id, { progress });
|
|
||||||
})
|
|
||||||
.done(() => {
|
|
||||||
completeHandler(task.id);
|
|
||||||
})
|
|
||||||
.error(({ error, errorCode }) => {
|
|
||||||
console.error(`Download error: ${errorCode} - ${error}`);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}, []);
|
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
void checkRunningTasks();
|
const checkRunningTasks = async () => {
|
||||||
}, [checkRunningTasks]);
|
const existingTasks = await checkForExistingDownloads();
|
||||||
|
existingTasks.forEach((task) => {
|
||||||
|
task
|
||||||
|
.progress(({ bytesDownloaded, bytesTotal }) => {
|
||||||
|
const progress = bytesDownloaded / bytesTotal;
|
||||||
|
updateDownloadItem(task.id, { progress });
|
||||||
|
})
|
||||||
|
.done(() => {
|
||||||
|
completeHandler(task.id);
|
||||||
|
})
|
||||||
|
.error(({ error, errorCode }) => {
|
||||||
|
console.error(`Download error: ${errorCode} - ${error}`);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
void checkRunningTasks();
|
||||||
|
}, []);
|
||||||
|
|
||||||
const cancellationFlags = useState<Record<string, boolean>>({})[0];
|
const cancellationFlags = useState<Record<string, boolean>>({})[0];
|
||||||
|
|
||||||
@@ -291,15 +291,15 @@ export const DownloadManagerProvider: React.FC<{ children: ReactNode }> = ({
|
|||||||
localSegmentPaths.push(segmentFile);
|
localSegmentPaths.push(segmentFile);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
await downloadSegment(segment, segmentFile, headers);
|
await downloadSegment(segment, segmentFile, headers, downloadId, () => {
|
||||||
|
segmentsDownloaded++;
|
||||||
|
updateProgress();
|
||||||
|
});
|
||||||
|
|
||||||
if (getCancellationFlag(downloadId)) {
|
if (getCancellationFlag(downloadId)) {
|
||||||
await cleanupDownload(segmentDir, downloadId);
|
await cleanupDownload(segmentDir, downloadId);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
segmentsDownloaded++;
|
|
||||||
updateProgress();
|
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.error(e);
|
console.error(e);
|
||||||
if (getCancellationFlag(downloadId)) {
|
if (getCancellationFlag(downloadId)) {
|
||||||
@@ -329,13 +329,27 @@ export const DownloadManagerProvider: React.FC<{ children: ReactNode }> = ({
|
|||||||
segmentUrl: string,
|
segmentUrl: string,
|
||||||
segmentFile: string,
|
segmentFile: string,
|
||||||
headers: Record<string, string>,
|
headers: Record<string, string>,
|
||||||
|
downloadId: string,
|
||||||
|
onSegmentDownloadComplete: () => void,
|
||||||
) => {
|
) => {
|
||||||
const downloadResumable = FileSystem.createDownloadResumable(
|
return new Promise<void>((resolve, reject) => {
|
||||||
segmentUrl,
|
const task = download({
|
||||||
segmentFile,
|
id: `${downloadId}-${segmentUrl.split("/").pop()}`,
|
||||||
{ headers },
|
url: segmentUrl,
|
||||||
);
|
destination: segmentFile,
|
||||||
await downloadResumable.downloadAsync();
|
headers: headers,
|
||||||
|
});
|
||||||
|
|
||||||
|
task
|
||||||
|
.done(() => {
|
||||||
|
onSegmentDownloadComplete();
|
||||||
|
resolve();
|
||||||
|
})
|
||||||
|
.error((error) => {
|
||||||
|
console.error(error);
|
||||||
|
reject(error);
|
||||||
|
});
|
||||||
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
const cleanupDownload = async (segmentDir: string, downloadId: string) => {
|
const cleanupDownload = async (segmentDir: string, downloadId: string) => {
|
||||||
|
Reference in New Issue
Block a user