import * as path from 'path'; import * as fs from 'fs'; import md5 from 'md5'; import FFmpeg from '@ownzones/fluent-ffmpeg'; import { v4 as uuid } from 'uuid'; import { s3 } from '@ownzones/lib'; import { config, log } from '../../config'; export async function ffprobe(url: string): Promise> { const input: string = url.indexOf('s3://') === 0 ? await s3.signUrl(url) : url; return new Promise((resolve, reject) => { FFmpeg.ffprobe(input, (error, response) => { if (error) { reject(error); } const stream = response.streams[0]; if (stream.codec_type === 'video') { const result = { width: stream.width, height: stream.height, duration: stream.duration, fieldOrder: stream.field_order, frameRate: stream.r_frame_rate, }; resolve(result); } if (stream.codec_type === 'audio') { resolve({ startTime: stream.start_time, duration: stream.duration, }); } }); }); } export async function getFrameHash(url: string, startTime: number): Promise { const input: string = url.indexOf('s3://') === 0 ? await s3.signUrl(url) : url; const framePath = path.join(config.mediaPath, `${uuid()}.yuv`); return new Promise((resolve, reject) => { FFmpeg({ logger: log }) .input(input) .outputOptions([ '-ss', startTime.toString(), '-vframes', '1', ]) .on('start', (cmdline: string) => { log.info(`command line: ${cmdline}`); }) .on('error', (error) => { reject(error); }) .on('end', () => { const frameHash = md5(fs.readFileSync(framePath)); resolve(frameHash); }) .format('rawvideo') .save(framePath); }); }