@@ -20,18 +20,68 @@ const FFMPEG_BASE_ARGS = ['-y', '-nostdin'] as const
2020 */
2121const INPUT_PROTOCOL_WHITELIST = [ '-protocol_whitelist' , 'file,pipe' ] as const
2222
23- /** FFmpeg argv: base flags, then `args` with the protocol whitelist before every input. */
23+ /**
24+ * Demuxers an input may probe as: media containers that read only the bytes
25+ * they are given. FFmpeg picks the demuxer from content, not the file name, and
26+ * the bytes are user-supplied, so without this an upload can select a demuxer
27+ * that opens further local paths (`concat`, `hls`, `dash`, `imf`) and the only
28+ * barrier left is that demuxer's own upstream defaults. Any other input fails
29+ * with "Format not on whitelist" before the demuxer opens anything.
30+ */
31+ const MEDIA_DEMUXERS = [
32+ 'mov' ,
33+ 'matroska' ,
34+ 'avi' ,
35+ 'flv' ,
36+ 'asf' ,
37+ 'mpegts' ,
38+ 'mpeg' ,
39+ 'mp3' ,
40+ 'wav' ,
41+ 'ogg' ,
42+ 'flac' ,
43+ 'aac' ,
44+ 'aiff' ,
45+ 'amr' ,
46+ 'caf' ,
47+ 'png_pipe' ,
48+ 'apng' ,
49+ 'jpeg_pipe' ,
50+ 'webp_pipe' ,
51+ 'bmp_pipe' ,
52+ 'tiff_pipe' ,
53+ 'ico' ,
54+ 'gif' ,
55+ 'image2' ,
56+ ] . join ( ',' )
57+
58+ /**
59+ * FFmpeg argv: base flags, then `args` with the protocol and format whitelists
60+ * before every input. A demuxer the caller forces with `-f` (the concat list,
61+ * the `lavfi` silence source) is added to that input's format whitelist, so
62+ * the inputs it opens in turn are still held to media demuxers.
63+ */
2464export function ffmpegArgs ( args : readonly string [ ] ) : string [ ] {
25- return [
26- ...FFMPEG_BASE_ARGS ,
27- ...args . flatMap ( ( arg ) => ( arg === '-i' ? [ ...INPUT_PROTOCOL_WHITELIST , arg ] : [ arg ] ) ) ,
28- ]
65+ const argv : string [ ] = [ ...FFMPEG_BASE_ARGS ]
66+ let forcedDemuxer : string | undefined
67+ for ( const [ index , arg ] of args . entries ( ) ) {
68+ if ( arg === '-f' ) forcedDemuxer = args [ index + 1 ]
69+ if ( arg === '-i' ) {
70+ const formats = forcedDemuxer ? `${ forcedDemuxer } ,${ MEDIA_DEMUXERS } ` : MEDIA_DEMUXERS
71+ argv . push ( ...INPUT_PROTOCOL_WHITELIST , '-format_whitelist' , formats )
72+ forcedDemuxer = undefined
73+ }
74+ argv . push ( arg )
75+ }
76+ return argv
2977}
3078
3179/** FFprobe argv that prints the format and streams of `filePath` as JSON. */
3280export function ffprobeJsonArgs ( filePath : string ) : string [ ] {
3381 return [
3482 ...INPUT_PROTOCOL_WHITELIST ,
83+ '-format_whitelist' ,
84+ MEDIA_DEMUXERS ,
3585 '-v' ,
3686 'error' ,
3787 '-print_format' ,
0 commit comments