-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathuseCustomBufferFetcher.tsx
More file actions
79 lines (69 loc) · 2.63 KB
/
useCustomBufferFetcher.tsx
File metadata and controls
79 lines (69 loc) · 2.63 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
import { useAtomValue } from "jotai";
import {
getByteRangeToBlockNumberRange,
getFileDetails,
sliceByteRangeFromBlockData,
} from "./utils";
import { blockSizeAtom, configAtom, formatAtom } from "../ConfigModifier/atoms";
import { useEffect, useRef } from "react";
export const useCustomBufferFetcher = (downloadUptoEnd = true) => {
const config = useAtomValue(configAtom);
const blockSize = useAtomValue(blockSizeAtom);
const downloadBlocks = async (startBlockNum: number, endBlockNum: number) => {
const fileName = config.url.split("/").pop();
const dataShardCount = config.dataShardCount;
const json = { fileName, startBlockNum, endBlockNum, dataShardCount };
const res = await fetch("http://localhost:3000/media/blocks", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify(json),
});
const uint8Data = new Uint8Array(await res.arrayBuffer());
return uint8Data;
};
const downloadByteRange = async (startByte: number, endByte: number) => {
const [blockRange, sliceIndices] = //
getByteRangeToBlockNumberRange(startByte, endByte, blockSize);
const blockData = await downloadBlocks(...blockRange);
return sliceByteRangeFromBlockData(
blockData,
sliceIndices,
downloadUptoEnd
);
};
const isOnlineHosted = useAtomValue(formatAtom) === "hosted-online";
const fileSize = useRef(0);
useEffect(() => void (fileSize.current = 0), [config.url]); // Reset fileSize on url change
const abortableDownloadByteRange = async (
startByte: number,
endByte: number,
signal: AbortSignal
) => {
if (!fileSize.current) {
const { size } = await getFileDetails(config.url);
if(!size) return console.error("Invalid file size");
fileSize.current = size;
}
return new Promise((resolve, reject) => {
let errMsg = "";
if (isOnlineHosted)
errMsg = "Cannot do custom fetching for online hosted videos";
if (fileSize.current <= 0)
errMsg = `Range request was aborted because fileSize is invalid. File Size: ${fileSize.current}.`;
if (errMsg) {
reject(new DOMException(errMsg, "AbortError"));
return;
}
let isAborted = false;
signal?.addEventListener("abort", () => {
isAborted = true;
reject(new DOMException("Range request was aborted", "AbortError"));
});
downloadByteRange(startByte, endByte).then((uint8Data) => {
if (isAborted) return;
resolve({ buffer: uint8Data.buffer, totalLength: fileSize.current });
});
});
};
return { downloadByteRange, abortableDownloadByteRange };
};