mirror of
https://gitlab.com/soapbox-pub/ditto.git
synced 2025-12-06 03:19:46 +00:00
Add ffprobe module
This commit is contained in:
parent
e46b7bfa85
commit
8f02c4125a
4 changed files with 56 additions and 18 deletions
|
|
@ -1,11 +1,11 @@
|
|||
import { assertEquals } from '@std/assert';
|
||||
|
||||
import { ffmpegDim } from './analyze.ts';
|
||||
import { getVideoDimensions } from './analyze.ts';
|
||||
|
||||
Deno.test('ffmpegDim', async () => {
|
||||
await using file = await Deno.open(new URL('./buckbunny.mp4', import.meta.url));
|
||||
Deno.test('getVideoDimensions', async () => {
|
||||
const uri = new URL('./buckbunny.mp4', import.meta.url);
|
||||
|
||||
const result = await ffmpegDim(file.readable);
|
||||
const dimensions = await getVideoDimensions(uri.href);
|
||||
|
||||
assertEquals(result, { width: 1280, height: 720 });
|
||||
assertEquals(dimensions, { width: 1920, height: 1080 });
|
||||
});
|
||||
|
|
|
|||
|
|
@ -1,17 +1,13 @@
|
|||
import { ffmpeg } from './ffmpeg.ts';
|
||||
import { ffprobe } from './ffprobe.ts';
|
||||
|
||||
export async function ffmpegDim(
|
||||
input: ReadableStream<Uint8Array>,
|
||||
): Promise<{ width: number; height: number } | undefined> {
|
||||
const result = ffmpeg(input, {
|
||||
'vf': 'showinfo', // Output as JSON
|
||||
'f': 'null', // Tell FFmpeg not to produce an output file
|
||||
export async function getVideoDimensions(path: string): Promise<{ width: number; height: number } | null> {
|
||||
const stream = ffprobe(path, {
|
||||
'v': 'error',
|
||||
'select_streams': 'v:0',
|
||||
'show_entries': 'stream=width,height',
|
||||
'of': 'json',
|
||||
});
|
||||
|
||||
const text = await new Response(result).json();
|
||||
console.log(text);
|
||||
const output = JSON.parse(text);
|
||||
|
||||
const [stream] = output.streams ?? [];
|
||||
return stream;
|
||||
const { streams: [result] } = await new Response(stream).json();
|
||||
return result ?? null;
|
||||
}
|
||||
|
|
|
|||
18
packages/transcode/ffprobe.test.ts
Normal file
18
packages/transcode/ffprobe.test.ts
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
import { assertEquals } from '@std/assert';
|
||||
|
||||
import { ffprobe } from './ffprobe.ts';
|
||||
|
||||
Deno.test('ffprobe', async () => {
|
||||
const uri = new URL('./buckbunny.mp4', import.meta.url);
|
||||
|
||||
const stream = ffprobe(uri, {
|
||||
'v': 'error',
|
||||
'select_streams': 'v:0',
|
||||
'show_entries': 'stream=width,height',
|
||||
'of': 'json',
|
||||
});
|
||||
|
||||
const { streams: [dimensions] } = await new Response(stream).json();
|
||||
|
||||
assertEquals(dimensions, { width: 1920, height: 1080 });
|
||||
});
|
||||
24
packages/transcode/ffprobe.ts
Normal file
24
packages/transcode/ffprobe.ts
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
export interface FFprobeFlags {
|
||||
'v'?: string;
|
||||
'select_streams'?: string;
|
||||
'show_entries'?: string;
|
||||
'of'?: string;
|
||||
[key: string]: string | undefined;
|
||||
}
|
||||
|
||||
export function ffprobe(path: URL | string, flags: FFprobeFlags): ReadableStream<Uint8Array> {
|
||||
const args = [];
|
||||
|
||||
for (const [key, value] of Object.entries(flags)) {
|
||||
if (typeof value === 'string') {
|
||||
args.push(`-${key}`, value);
|
||||
}
|
||||
}
|
||||
|
||||
args.push(path instanceof URL ? path.href : path);
|
||||
|
||||
const command = new Deno.Command('ffprobe', { args, stdout: 'piped' });
|
||||
const child = command.spawn();
|
||||
|
||||
return child.stdout;
|
||||
}
|
||||
Loading…
Add table
Reference in a new issue