Test new stream logic

This commit is contained in:
mbaharip
2024-05-05 23:47:17 +07:00
parent b08d6cedde
commit a0441387d0
2 changed files with 110 additions and 47 deletions
+1 -6
View File
@@ -8,8 +8,6 @@ import { cn } from "~/utils";
import Icon from "~/components/Icon";
import { decryptData } from "~/utils/encryptionHelper/hash";
import { CreateDownloadToken } from "./actions";
const Plyr = dynamic(() => import("plyr-react"), {
@@ -32,10 +30,6 @@ export default function PreviewVideo({ file }: Props) {
return;
}
const token = await CreateDownloadToken();
const id = await decryptData(file.encryptedId);
// setVideoSrc(
// `https://drive.usercontent.google.com/download?id=${id}&export=download&authuser=0`,
// );
setVideoSrc(`/api/stream/${file.encryptedId}?token=${token}`);
} catch (error) {
const e = error as Error;
@@ -85,6 +79,7 @@ export default function PreviewVideo({ file }: Props) {
},
],
}}
// crossOrigin='anonymous'
options={{
toggleInvert: true,
settings: ["quality", "speed"],
+109 -41
View File
@@ -7,8 +7,6 @@ import { gdriveNoCache as gdrive } from "~/utils/gdriveInstance";
import config from "~/config/gIndex.config";
import { streamFile } from "./helper";
export const dynamic = "force-dynamic";
export async function GET(
@@ -35,12 +33,33 @@ export async function GET(
if (!tokenValidity.success) throw new Error(tokenValidity.message);
const decryptedId = await decryptData(encryptedId);
const _fileMeta = gdrive.files.get({
const fileMeta = await gdrive.files.get({
fileId: decryptedId,
fields: "id, name, mimeType, size, fileExtension, webContentLink",
supportsAllDrives: config.apiConfig.isTeamDrive,
});
const _fileContent = gdrive.files.get(
const fileSize = Number(fileMeta.data.size || 0);
if (!fileMeta.data.webContentLink)
throw new Error("No download link found");
const ranges = request.headers.get("Range") || "bytes=0-";
let rangeStart = 0;
let rangeEnd = fileSize - 1;
const rangeRegex = /bytes=(\d+)-(\d+)?/;
const rangeSize = ranges.match(rangeRegex);
if (rangeSize) {
rangeStart = parseInt(rangeSize[1], 10);
rangeEnd = rangeSize ? parseInt(rangeSize[2], 10) : fileSize - 1;
}
const contentRange = `bytes=${rangeStart}-${Math.min(
rangeEnd,
fileSize - 1,
)}/${fileSize}`;
const contentLength = rangeEnd ? rangeEnd - rangeStart + 1 : fileSize;
const fileContent = await gdrive.files.get(
{
fileId: decryptedId,
alt: "media",
@@ -48,49 +67,98 @@ export async function GET(
},
{
responseType: "stream",
headers: {
"Accept-Ranges": "bytes",
"Range": ranges,
},
},
);
const [fileMeta, fileContent] = await Promise.all([
_fileMeta,
_fileContent,
]);
const stream = fileContent.data as NodeJS.ReadableStream;
const fileRange = fileContent.headers["content-range"];
const fileLength = fileContent.headers["content-length"];
const fileSize = Number(fileMeta.data.size || 0);
if (!fileMeta.data.webContentLink)
throw new Error("No download link found");
const stream: ReadableStream = streamFile(fileContent.data);
const ranges = request.headers.get("Range");
if (ranges) {
const [start, end] = ranges.replace(/bytes=/, "").split("-");
const startByte = parseInt(start, 10);
const endByte = end ? parseInt(end, 10) : fileSize - 1;
return new NextResponse(stream, {
status: 206,
headers: {
"Content-Type": fileMeta.data.mimeType || "application/octet-stream",
"Content-Disposition": `attachment; filename="${encodeURIComponent(
fileMeta.data.name || `Untitled.${fileMeta.data.fileExtension}`,
)}"`,
"Content-Length": (endByte - startByte + 1).toString(),
"Accept-Ranges": "bytes",
"Content-Range": `bytes ${startByte}-${endByte}/${fileSize}`,
},
});
}
return new NextResponse(stream, {
status: 200,
headers: {
"Content-Type": fileMeta.data.mimeType || "application/octet-stream",
"Content-Disposition": `attachment; filename="${encodeURIComponent(
fileMeta.data.name || `Untitled.${fileMeta.data.fileExtension}`,
)}"`,
"Content-Length": fileSize.toString(),
"Accept-Ranges": "bytes",
const readable = new ReadableStream({
start(controller) {
stream.on("data", (chunk) => {
controller.enqueue(chunk);
});
stream.on("end", () => {
controller.close();
});
stream.on("error", (error) => {
controller.error(error);
});
},
});
return new NextResponse(readable, {
status: 206,
headers: {
"Content-Range": fileRange || contentRange,
"Content-Length": fileLength || contentLength.toString(),
"Content-Type": fileMeta.data.mimeType || "application/octet-stream",
"Accept-Ranges": "bytes",
// 'Content-Disposition': `attachment; filename="${encodeURIComponent(fileMeta.data.name || `Untitled.${fileMeta.data.fileExtension}`)}"`,
},
});
// async function* readStream() {
// for await (const chunk of fileContent.data as any) {
// yield chunk;
// }
// }
// function iteratorToStream(iterator: AsyncGenerator<any>) {
// return new ReadableStream({
// async pull(controller) {
// const { done, value } = await iterator.next();
// if (done) {
// controller.close();
// } else {
// controller.enqueue(value);
// }
// },
// });
// }
// const stream: ReadableStream = iteratorToStream(readStream());
// const res = new Response(stream, {
// status: 206,
// headers: {
// "Content-Type": fileMeta.data.mimeType || "application/octet-stream",
// "Content-Disposition": `attachment; filename="${encodeURIComponent(
// fileMeta.data.name || `Untitled.${fileMeta.data.fileExtension}`,
// )}"`,
// "Content-Length": contentLength.toString(),
// "Content-Range": ranges ? contentRange : "",
// },
// });
// NextResponse.next(res);
// new NextResponse(stream, {
// status: request.headers.get("Range") ? 206 : 200,
// headers: {
// "Content-Type": fileMeta.data.mimeType || "application/octet-stream",
// "Content-Disposition": `attachment; filename="${encodeURIComponent(
// fileMeta.data.name || `Untitled.${fileMeta.data.fileExtension}`,
// )}"`,
// "Content-Length": fileSize.toString(),
// "Accept-Ranges": "bytes",
// "Range": ranges ? `bytes ${rangeStart}-${rangeEnd}/${fileSize}` : "",
// },
// });
// return new NextResponse(stream, {
// status: 206,
// headers: {
// "Content-Type": fileMeta.data.mimeType || "application/octet-stream",
// "Content-Disposition": `attachment; filename="${encodeURIComponent(
// fileMeta.data.name || `Untitled.${fileMeta.data.fileExtension}`,
// )}"`,
// "Content-Length": fileSize.toString(),
// "Accept-Ranges": "bytes",
// "Range": ranges ? `bytes ${rangeStart}-${rangeEnd}/${fileSize}` : "",
// },
// });
} catch (error) {
const e = error as Error;
console.error(e.message);