mirror of
https://github.com/Nezumi-2711/next-gdrive-index.git
synced 2026-09-22 20:01:36 +00:00
Test new stream logic
This commit is contained in:
@@ -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"],
|
||||
|
||||
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user