add endpoint & update tos
This commit is contained in:
parent
0aaadabf5c
commit
4a2324deaf
69
src/routes/api/video/[filename].ts
Normal file
69
src/routes/api/video/[filename].ts
Normal file
@ -0,0 +1,69 @@
|
|||||||
|
import { promises as fsPromises } from 'fs';
|
||||||
|
import fs from 'fs';
|
||||||
|
import fetch from 'node-fetch';
|
||||||
|
import type { RequestHandler } from '@sveltejs/kit';
|
||||||
|
|
||||||
|
const CHUNK_SIZE = 1 * 1024 * 1024; // 1MB in bytes
|
||||||
|
|
||||||
|
const parseRange = (range: string) => {
|
||||||
|
const [start, end] = range.replace(/bytes=/, '').split('-').map(Number);
|
||||||
|
return { start, end: end || undefined };
|
||||||
|
};
|
||||||
|
|
||||||
|
const createResponse = (body: ReadableStream | Buffer, headers: Record<string, string>, status = 206) =>
|
||||||
|
new Response(body, { status, headers });
|
||||||
|
|
||||||
|
const streamRemoteFile = async (url: string, range: string) => {
|
||||||
|
const { start, end } = parseRange(range);
|
||||||
|
const response = await fetch(url, {
|
||||||
|
headers: { Range: `bytes=${start}-${end || ''}` }
|
||||||
|
});
|
||||||
|
|
||||||
|
return createResponse(response.body, {
|
||||||
|
'Content-Range': response.headers.get('Content-Range') || '',
|
||||||
|
'Accept-Ranges': 'bytes',
|
||||||
|
'Content-Length': response.headers.get('Content-Length') || '',
|
||||||
|
'Content-Type': response.headers.get('Content-Type') || '',
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
const streamLocalFile = async (filePath: string, range: string) => {
|
||||||
|
const fileSize = (await fsPromises.stat(filePath)).size;
|
||||||
|
const { start, end } = parseRange(range);
|
||||||
|
const chunkEnd = end || Math.min(start + CHUNK_SIZE - 1, fileSize - 1);
|
||||||
|
|
||||||
|
if (start >= fileSize) {
|
||||||
|
return new Response(`Requested range not satisfiable\n${start} >= ${fileSize}`, {
|
||||||
|
status: 416,
|
||||||
|
headers: { 'Content-Range': `bytes */${fileSize}` },
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
const stream = fs.createReadStream(filePath, { start, end: chunkEnd });
|
||||||
|
|
||||||
|
return createResponse(stream, {
|
||||||
|
'Content-Range': `bytes ${start}-${chunkEnd}/${fileSize}`,
|
||||||
|
'Accept-Ranges': 'bytes',
|
||||||
|
'Content-Length': (chunkEnd - start + 1).toString(),
|
||||||
|
'Content-Type': 'video/mp4',
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
export const GET: RequestHandler = async ({ params, request }) => {
|
||||||
|
const { filename } = params;
|
||||||
|
const range = request.headers.get('range');
|
||||||
|
|
||||||
|
if (!range) {
|
||||||
|
return new Response('Requires Range header', { status: 400 });
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
const videoPath = filename.startsWith('http') ? filename : `static/${filename}`;
|
||||||
|
return filename.startsWith('http') ?
|
||||||
|
await streamRemoteFile(videoPath, range) :
|
||||||
|
await streamLocalFile(videoPath, range);
|
||||||
|
} catch (error) {
|
||||||
|
console.error('Error streaming video:', error);
|
||||||
|
return new Response('File not found or error streaming video', { status: 404 });
|
||||||
|
}
|
||||||
|
};
|
||||||
@ -165,7 +165,10 @@
|
|||||||
<br>
|
<br>
|
||||||
<br>
|
<br>
|
||||||
You may be held accountable for damages (including costs and attorneys' fees) for misrepresentation or bad-faith claims on the infringement of any Content found on and/or through Service on your copyright.
|
You may be held accountable for damages (including costs and attorneys' fees) for misrepresentation or bad-faith claims on the infringement of any Content found on and/or through Service on your copyright.
|
||||||
</p>
|
<br>
|
||||||
|
<br>
|
||||||
|
On this website we use some images on this website from <a href="https://de.freepik.com/" class="text-blue-400 sm:hover:text-white">FreePik</a>.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
|
||||||
<h3 class="text-2xl font-medium text-white text-start underline">
|
<h3 class="text-2xl font-medium text-white text-start underline">
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user