refactor(server): video transcode processor (#2163)

* refactor(server): video transcode processor

* refactor: rename shouldRotate to isVideoVertical, remove unnecessary await

* refactor: rename getOptions to getFfmpegOptions to be clearer in that context

* fix: optimal preset converting vertical videos already smaller than target resolution

---------

Co-authored-by: Zack Pollard <zackpollard@ymail.com>
This commit is contained in:
Jason Rasmussen
2023-04-04 10:48:02 -04:00
committed by GitHub
parent ec6a7ae97c
commit 48393c215b
9 changed files with 347 additions and 196 deletions

View File

@@ -1,7 +1,10 @@
import { IMediaRepository, ResizeOptions } from '@app/domain';
import { IMediaRepository, ResizeOptions, VideoInfo } from '@app/domain';
import { exiftool } from 'exiftool-vendored';
import ffmpeg from 'fluent-ffmpeg';
import ffmpeg, { FfprobeData } from 'fluent-ffmpeg';
import sharp from 'sharp';
import { promisify } from 'util';
const probe = promisify<string, FfprobeData>(ffmpeg.ffprobe);
export class MediaRepository implements IMediaRepository {
extractThumbnailFromExif(input: string, output: string): Promise<void> {
@@ -42,4 +45,31 @@ export class MediaRepository implements IMediaRepository {
.run();
});
}
async probe(input: string): Promise<VideoInfo> {
const results = await probe(input);
return {
streams: results.streams.map((stream) => ({
height: stream.height || 0,
width: stream.width || 0,
codecName: stream.codec_name,
codecType: stream.codec_type,
frameCount: Number.parseInt(stream.nb_frames ?? '0'),
rotation: Number.parseInt(`${stream.rotation ?? 0}`),
})),
};
}
transcode(input: string, output: string, options: string[]): Promise<void> {
return new Promise((resolve, reject) => {
ffmpeg(input)
//
.outputOptions(options)
.output(output)
.on('error', reject)
.on('end', resolve)
.run();
});
}
}