BigDataPolyp/src/routes/api/video-preview/+server.ts
2025-10-22 00:22:33 +00:00

58 lines
2.1 KiB
TypeScript

// ✅ 수정된 /api/video-preview/+server.ts (SvelteKit 2.x / Kit 1.x 호환)
import { error } from '@sveltejs/kit';
import * as fs from 'fs';
import * as path from 'path';
import { Readable } from 'stream';
// process.mp4 파일이 있는 실제 경로로 수정하세요
const TEMP_BASE_DIR = 'tmp'; // 예시 경로
const videoPath = path.join(TEMP_BASE_DIR, 'process.mp4');
export const GET: import('@sveltejs/kit').RequestHandler = ({ request }) => {
let stats: fs.Stats;
try {
stats = fs.statSync(videoPath);
} catch (e) {
throw error(404, 'Video file not found');
}
const fileSize = stats.size;
const range = request.headers.get('Range');
const responseHeaders = {
'Content-Type': 'video/mp4',
'Accept-Ranges': 'bytes'
};
if (range) {
// Range 요청 처리 (Firefox가 요구하는 부분)
const parts = range.replace(/bytes=/, "").split("-");
const start = parseInt(parts[0], 10);
const end = parts[1] ? parseInt(parts[1], 10) : fileSize - 1;
if (start >= fileSize) {
return new Response(null, {
status: 416, // Range Not Satisfiable
headers: { 'Content-Range': `bytes */${fileSize}` }
});
}
const chunkSize = (end - start) + 1;
const fileStream = fs.createReadStream(videoPath, { start, end });
Object.assign(responseHeaders, {
'Content-Range': `bytes ${start}-${end}/${fileSize}`,
'Content-Length': chunkSize.toString(),
});
return new Response(Readable.toWeb(fileStream) as ReadableStream, { status: 206, headers: responseHeaders }); // 206 Partial Content
} else {
// 전체 파일 요청 (Chrome이 fallback하는 부분)
Object.assign(responseHeaders, {
'Content-Length': fileSize.toString(),
});
const fileStream = fs.createReadStream(videoPath);
return new Response(Readable.toWeb(fileStream) as ReadableStream, { status: 200, headers: responseHeaders }); // 200 OK
}
};