@@ -2,7 +2,7 @@ import { IFFmpegConfiguration } from './interfaces';
22import { FFmpegBase } from './ffmpeg-base' ;
33import * as types from './types' ;
44import configs from './ffmpeg-config' ;
5- import { noop } from './utils' ;
5+ import { noop , parseMetadata } from './utils' ;
66
77export class FFmpeg <
88 Config extends IFFmpegConfiguration <
@@ -220,6 +220,82 @@ export class FFmpeg<
220220 return file ;
221221 }
222222
223+ /**
224+ * Get the meta data of a the specified file.
225+ * Returns information such as codecs, fps, bitrate etc.
226+ */
227+ public async meta ( source : string | Blob ) : Promise < types . Metadata > {
228+ await this . writeFile ( 'probe' , source ) ;
229+ const meta : types . Metadata = {
230+ streams : { audio : [ ] , video : [ ] } ,
231+ } ;
232+ const callback = parseMetadata ( meta ) ;
233+ ffmpeg . onMessage ( callback ) ;
234+ await this . exec ( [ '-i' , 'probe' ] ) ;
235+ ffmpeg . removeOnMessage ( callback ) ;
236+ this . clearMemory ( ) ;
237+ return meta ;
238+ }
239+
240+ /**
241+ * Generate a series of thumbnails
242+ * @param source Your input file
243+ * @param count The number of thumbnails to generate
244+ * @param start Lower time limit in seconds
245+ * @param stop Upper time limit in seconds
246+ * @example
247+ * // type AsyncGenerator<Blob, void, void>
248+ * const generator = ffmpeg.thumbnails('/samples/video.mp4');
249+ *
250+ * for await (const image of generator) {
251+ * const img = document.createElement('img');
252+ * img.src = URL.createObjectURL(image);
253+ * document.body.appendChild(img);
254+ * }
255+ */
256+ public async * thumbnails (
257+ source : string | Blob ,
258+ count : number = 5 ,
259+ start : number = 0 ,
260+ stop ?: number
261+ ) : AsyncGenerator < Blob , void , void > {
262+ // make sure start and stop are defined
263+ if ( ! stop ) {
264+ const { duration } = await this . meta ( source ) ;
265+
266+ // make sure the duration is defined
267+ if ( duration ) stop = duration ;
268+ else {
269+ console . warn (
270+ 'Could not extract duration from meta data please provide a stop argument. Falling back to 1sec otherwise.'
271+ ) ;
272+ stop = 1 ;
273+ }
274+ }
275+
276+ // get the time increase for each iteration
277+ const step = ( stop - start ) / count ;
278+
279+ await this . writeFile ( 'input' , source ) ;
280+
281+ for ( let i = start ; i < stop ; i += step ) {
282+ await ffmpeg . exec ( [
283+ '-ss' ,
284+ i . toString ( ) ,
285+ '-i' ,
286+ 'input' ,
287+ '-frames:v' ,
288+ '1' ,
289+ 'image.jpg' ,
290+ ] ) ;
291+ try {
292+ const res = await ffmpeg . readFile ( 'image.jpg' ) ;
293+ yield new Blob ( [ res ] , { type : 'image/jpeg' } ) ;
294+ } catch ( e ) { }
295+ }
296+ this . clearMemory ( ) ;
297+ }
298+
223299 private parseOutputOptions ( ) : string [ ] {
224300 if ( ! this . _output ) {
225301 throw new Error ( 'Please define the output first' ) ;
0 commit comments