Support readable in extractVideoFrame

This commit is contained in:
Alex Gleason 2025-02-28 20:52:11 -06:00
parent a28e6509fd
commit 2533d2f469
No known key found for this signature in database
GPG key ID: 7211D1F99744FBB7
3 changed files with 15 additions and 5 deletions

View file

@ -38,7 +38,13 @@ export function ffmpeg(input: URL | ReadableStream<Uint8Array>, flags: FFmpegFla
// Pipe the input stream into FFmpeg stdin and ensure completion // Pipe the input stream into FFmpeg stdin and ensure completion
if (input instanceof ReadableStream) { if (input instanceof ReadableStream) {
input.pipeTo(child.stdin); input.pipeTo(child.stdin).catch((e: unknown) => {
if (e instanceof Error && e.name === 'BrokenPipe') {
// Ignore. ffprobe closes the pipe once it has read the metadata.
} else {
throw e;
}
});
} }
// Return the FFmpeg stdout stream // Return the FFmpeg stdout stream

View file

@ -1,8 +1,9 @@
import { extractVideoFrame } from './frame.ts'; import { extractVideoFrame } from './frame.ts';
Deno.test('extractVideoFrame', async () => { Deno.test('extractVideoFrame', async () => {
const uri = new URL('./buckbunny.mp4', import.meta.url); await using file = await Deno.open(new URL('./buckbunny.mp4', import.meta.url));
const result = await extractVideoFrame(uri);
const result = await extractVideoFrame(file.readable);
await Deno.mkdir(new URL('./tmp', import.meta.url), { recursive: true }); await Deno.mkdir(new URL('./tmp', import.meta.url), { recursive: true });
await Deno.writeFile(new URL('./tmp/buckbunny-poster.jpg', import.meta.url), result); await Deno.writeFile(new URL('./tmp/buckbunny-poster.jpg', import.meta.url), result);

View file

@ -1,7 +1,10 @@
import { ffmpeg } from './ffmpeg.ts'; import { ffmpeg } from './ffmpeg.ts';
export function extractVideoFrame(file: URL, ss: string = '00:00:01'): Promise<Uint8Array> { export function extractVideoFrame(
const output = ffmpeg(file, { input: URL | ReadableStream<Uint8Array>,
ss: string = '00:00:01',
): Promise<Uint8Array> {
const output = ffmpeg(input, {
'ss': ss, // Seek to timestamp 'ss': ss, // Seek to timestamp
'frames:v': '1', // Extract only 1 frame 'frames:v': '1', // Extract only 1 frame
'q:v': '2', // High-quality JPEG (lower = better quality) 'q:v': '2', // High-quality JPEG (lower = better quality)