refactor: make hls downloads also use background task

This commit is contained in:
Adrian Castro
2024-03-28 01:07:11 +01:00
parent 1f7e8f4d86
commit d82f5a4573

View File

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