From d2980a511ea44671e6f8ace052c764fc2328cd6d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emrik=20=C3=96stling?= Date: Mon, 26 Oct 2026 22:07:02 +0100 Subject: [PATCH] resturcture ffmpeg properties --- src/converters/ffmpeg.ts | 1488 +++++++++-------- src/converters/main.ts | 30 +- tests/converters/ffmpeg.test.ts | 15 + tests/converters/main.test.ts | 27 + .../converters/all-formats.test.ts | 4 +- .../converters/expected-failures.json | 110 -- 6 files changed, 862 insertions(+), 812 deletions(-) diff --git a/src/converters/ffmpeg.ts b/src/converters/ffmpeg.ts index 8e5959a7..34bb7f8a 100644 --- a/src/converters/ffmpeg.ts +++ b/src/converters/ffmpeg.ts @@ -18,695 +18,811 @@ type FfmpegExecFile = ( callback: (err: Error | null, stdout: string, stderr: string) => void, ) => ChildProcess | void; -// This could be done dynamically by running `ffmpeg -formats` and parsing the output +const imageInputs = [ + "alias_pix", + "apng", + "art", + "avif", + "bmp", + "brender_pix", + "dds", + "dpic", + "dpx", + "dpx_pipe", + "exr", + "exr_pipe", + "fits", + "gif", + "hdr", + "ico", + "im1", + "im24", + "im8", + "image2", + "image2pipe", + "j2c", + "j2k", + "j2k_pipe", + "jls", + "jp2", + "jpeg", + "jpeg_pipe", + "jpegls_pipe", + "jpg", + "jxl", + "ljpg", + "mjpeg", + "mjpg", + "pam", + "pbm", + "pcd", + "pcx", + "pfm", + "pgm", + "pgmyuv", + "phm", + "pic", + "pictor", + "pix", + "png", + "png_pipe", + "pnm", + "ppm", + "ptx", + "qoi", + "qoi_pipe", + "ras", + "raw", + "rgb", + "rgba", + "rs", + "sgi", + "sgi_pipe", + "sun", + "sunras", + "svg", + "svg_pipe", + "svs", + "tga", + "tif", + "tiff", + "tiff_pipe", + "v210", + "v210x", + "v308", + "v408", + "v410", + "vbn", + "wbmp", + "webp", + "webp_pipe", + "xbm", + "xface", + "xpm", + "xwd", + "y", + "y41p", + "yuv", +]; + +const audioInputs = [ + "669", + "722", + "aa", + "aa3", + "aac", + "aax", + "ac3", + "ac4", + "ace", + "acm", + "act", + "adf", + "adp", + "ads", + "adts", + "adx", + "aea", + "afc", + "aif", + "aifc", + "aiff", + "aix", + "al", + "alaw", + "alp", + "alsa", + "amf", + "amr", + "amrnb", + "amrwb", + "ams", + "apac", + "apc", + "ape", + "apl", + "apm", + "aptx", + "aptxhd", + "ast", + "au", + "aud", + "avr", + "awb", + "bcstm", + "bfstm", + "binka", + "bit", + "bonk", + "brstm", + "c2", + "caf", + "cdda", + "cdg", + "chk", + "cvg", + "daud", + "derf", + "dfpwm", + "drc", + "dsf", + "dsm", + "dss", + "dtk", + "dtm", + "dts", + "dtshd", + "dvf", + "eac3", + "ec3", + "epaf", + "f32be", + "f32le", + "f64be", + "f64le", + "far", + "flac", + "fsb", + "fwse", + "g722", + "g723_1", + "g726", + "g726le", + "g729", + "genh", + "gsm", + "hca", + "hcom", + "iac", + "ilbc", + "ircam", + "iss", + "it", + "kss", + "latm", + "lbc", + "loas", + "lrc", + "m2a", + "m4a", + "m4b", + "m4r", + "mid", + "midi", + "mka", + "mlp", + "mmf", + "mod", + "mp1", + "mp2", + "mp3", + "mpa", + "mpc", + "mpc8", + "msbc", + "mtm", + "mulaw", + "musx", + "mvi", + "nist", + "oga", + "ogg", + "oma", + "omg", + "opus", + "paf", + "pcm", + "pvf", + "qcp", + "r16", + "r24", + "r32", + "ra", + "rak", + "rco", + "rmf", + "rso", + "s16be", + "s16le", + "s24be", + "s24le", + "s32be", + "s32le", + "s8", + "sb", + "sbc", + "sds", + "sdx", + "sf", + "sfx", + "sfx2", + "shn", + "siff", + "sln", + "sol", + "son", + "sox", + "spdif", + "sph", + "spx", + "ss2", + "stk", + "stm", + "str", + "svag", + "sw", + "tak", + "thd", + "truehd", + "tta", + "tun", + "u16be", + "u16le", + "u24be", + "u24le", + "u32be", + "u32le", + "u8", + "ub", + "ul", + "ult", + "umx", + "uw", + "vag", + "voc", + "vox", + "vpk", + "vqe", + "vqf", + "vql", + "w64", + "wa", + "wav", + "way", + "wma", + "wow", + "wsaud", + "wsd", + "wv", + "wve", + "xa", + "xl", + "xm", + "xmd", + "xmv", + "xpk", + "xvag", + "xwma", +]; + +const videoInputs = [ + "264", + "265", + "266", + "302", + "3dostr", + "3g2", + "3gp", + "4xm", + "anm", + "ans", + "argo_asf", + "argo_brp", + "asc", + "asf", + "asf_o", + "av1", + "avc", + "avi", + "avs", + "avs2", + "avs3", + "bethsoftvid", + "bfi", + "bin", + "bink", + "bitpacked", + "bmv", + "boa", + "c93", + "cavsvideo", + "cdata", + "cdxl", + "cgi", + "cif", + "cine", + "codec2", + "codec2raw", + "concat", + "cri", + "dash", + "dat", + "data", + "dav", + "dbm", + "dcstr", + "dfa", + "dhav", + "dif", + "digi", + "dirac", + "diz", + "dmf", + "dnxhd", + "dsicin", + "dv", + "dxa", + "ea", + "ea_cdata", + "evc", + "f4v", + "fap", + "fbdev", + "ffmetadata", + "film_cpk", + "filmstrip", + "flic", + "flm", + "flv", + "frm", + "gdm", + "gdv", + "gxf", + "h261", + "h263", + "h264", + "h265", + "h266", + "h26l", + "hevc", + "hls", + "hnm", + "ice", + "idcin", + "idf", + "iec61883", + "iff", + "ifv", + "imf", + "imx", + "ingenient", + "ipmovie", + "ipu", + "ism", + "isma", + "ismv", + "iv8", + "ivf", + "ivr", + "j2b", + "jack", + "jpegls", + "jv", + "kmsgrab", + "kux", + "kvag", + "laf", + "lavfi", + "lmlm4", + "luodat", + "lvf", + "lxf", + "m15", + "m2ts", + "m4v", + "mac", + "mca", + "mcc", + "mdl", + "med", + "mj2", + "mk3d", + "mks", + "mkv", + "mlv", + "mm", + "mmcmp", + "mms", + "mo3", + "mods", + "moflex", + "mov", + "mp4", + "mpeg", + "mpg", + "mpjpeg", + "mpo", + "mptm", + "msf", + "msnwctcp", + "msp", + "mt2", + "mtaf", + "mtv", + "mv", + "mxf", + "mxg", + "nc", + "nfo", + "nistsphere", + "nsp", + "nst", + "nsv", + "nut", + "nuv", + "obu", + "okt", + "openal", + "osq", + "oss", + "pdv", + "pgx", + "photocd", + "plm", + "pmp", + "pp", + "psd", + "psm", + "psp", + "psxstr", + "pt36", + "ptm", + "pulse", + "pva", + "qcif", + "qdraw", + "r3d", + "rawvideo", + "rcv", + "redspark", + "rka", + "rl2", + "rm", + "roq", + "rpl", + "rsd", + "rt", + "rtp", + "rtsp", + "s337m", + "s3m", + "sap", + "sbg", + "sdns", + "sdp", + "sdr2", + "ser", + "sga", + "smjpeg", + "smk", + "smush", + "sndio", + "st26", + "stp", + "swf", + "tco", + "thp", + "tiertexseq", + "tmv", + "ts", + "tty", + "txd", + "txt", + "ty", + "ty+", + "usm", + "v", + "vb", + "vc1", + "vc1test", + "vidc", + "video4linux2", + "viv", + "vividas", + "vivo", + "vmd", + "vob", + "vt", + "vvc", + "wc3movie", + "webm", + "wmv", + "wsvqa", + "wtv", + "x11grab", + "xbin", + "y4m", + "yop", + "yuv10", +]; + +const subtitleInputs = [ + "aqt", + "aqtitle", + "ass", + "cvd", + "dks", + "dvbsub", + "dvbtxt", + "idx", + "jacosub", + "js", + "jss", + "lrc", + "microdvd", + "mpl2", + "mpsub", + "pjs", + "realtext", + "sami", + "sbv", + "scc", + "smi", + "srt", + "ssa", + "stl", + "sub", + "subviewer", + "subviewer1", + "sup", + "tedcaptions", + "ttml", + "vobsub", + "vplayer", + "vtt", + "webvtt", + "xml", +]; + +const imageOutputs = [ + "apng", + "avif", + "bmp", + "dpx", + "exr", + "fits", + "gif", + "hdr", + "ico", + "im1", + "im24", + "im8", + "j2c", + "j2k", + "jls", + "jp2", + "jpeg", + "jpg", + "jxl", + "ljpg", + "mjpeg", + "mjpg", + "pam", + "pbm", + "pcx", + "pfm", + "pgm", + "pgmyuv", + "phm", + "pix", + "png", + "ppm", + "qoi", + "ras", + "rgb", + "rs", + "sgi", + "sun", + "sunras", + "tga", + "tif", + "tiff", + "vbn", + "wbmp", + "webp", + "xbm", + "xface", + "xwd", + "y", + "yuv", +]; + +const audioOutputs = [ + "aac", + "ac3", + "ac4", + "adts", + "adx", + "afc", + "aif", + "aifc", + "aiff", + "al", + "amr", + "apm", + "aptx", + "aptxhd", + "ast", + "au", + "aud", + "bit", + "c2", + "caf", + "chk", + "cvg", + "dfpwm", + "drc", + "dts", + "eac3", + "ec3", + "flac", + "g722", + "gsm", + "ircam", + "latm", + "lbc", + "loas", + "m2a", + "m4a", + "m4b", + "mka", + "mlp", + "mmf", + "mp2", + "mp3", + "mpa", + "msbc", + "oga", + "ogg", + "oma", + "opus", + "pcm", + "ra", + "rco", + "rso", + "sb", + "sbc", + "sf", + "sox", + "spdif", + "spx", + "sw", + "thd", + "tta", + "tun", + "ub", + "ul", + "uw", + "vag", + "voc", + "w64", + "wav", + "wma", + "wv", +]; + +const videoOutputs = [ + "264", + "265", + "266", + "302", + "3g2", + "3gp", + "a64", + "amv", + "asf", + "av1.mkv", + "av1.mp4", + "avi", + "avs", + "avs2", + "avs3", + "cavs", + "cpk", + "dnxhd", + "dnxhr", + "dv", + "dvd", + "evc", + "f4v", + "ffmeta", + "flm", + "flv", + "gxf", + "h261", + "h263", + "h264.mkv", + "h264.mp4", + "h265.mkv", + "h265.mp4", + "h266.mkv", + "hevc", + "isma", + "ismv", + "ivf", + "m1v", + "m2t", + "m2ts", + "m2v", + "m3u8", + "m4v", + "mkv", + "mov", + "mp4", + "mpd", + "mpeg", + "mpg", + "mts", + "mxf", + "nut", + "obu", + "ogv", + "psp", + "rcv", + "rm", + "roq", + "swf", + "tco", + "ts", + "vc1", + "vc2", + "vob", + "vvc", + "webm", + "wmv", + "wtv", + "y4m", +]; + +const subtitleOutputs = [ + "ass", + "js", + "jss", + "lrc", + "scc", + "srt", + "ssa", + "sub", + "sup", + "ttml", + "vtt", + "xml", +]; + export const properties = { from: { - muxer: [ - "264", - "265", - "266", - "302", - "3dostr", - "3g2", - "3gp", - "4xm", - "669", - "722", - "aa", - "aa3", - "aac", - "aax", - "ac3", - "ac4", - "ace", - "acm", - "act", - "adf", - "adp", - "ads", - "adx", - "aea", - "afc", - "aiff", - "aix", - "al", - "alaw", - "alias_pix", - "alp", - "alsa", - "amf", - "amr", - "amrnb", - "amrwb", - "ams", - "anm", - "ans", - "apc", - "ape", - "apl", - "apm", - "apng", - "aptx", - "aptxhd", - "aqt", - "aqtitle", - "argo_asf", - "argo_brp", - "art", - "asc", - "asf", - "asf_o", - "ass", - "ast", - "au", - "av1", - "avc", - "avi", - "avif", - "avr", - "avs", - "avs2", - "avs3", - "awb", - "bcstm", - "bethsoftvid", - "bfi", - "bfstm", - "bin", - "bink", - "binka", - "bit", - "bitpacked", - "bmv", - "bmp", - "bonk", - "boa", - "brender_pix", - "brstm", - "c2", - "c93", - "caf", - "cavsvideo", - "cdata", - "cdg", - "cdxl", - "cgi", - "cif", - "cine", - "codec2", - "codec2raw", - "concat", - "cri", - "dash", - "dat", - "data", - "daud", - "dav", - "dbm", - "dcstr", - "dds", - "derf", - "dfpwm", - "dfa", - "dhav", - "dif", - "digi", - "dirac", - "diz", - "dmf", - "dnxhd", - "dpx_pipe", - "dsf", - "dsicin", - "dsm", - "dss", - "dtk", - "dtm", - "dts", - "dtshd", - "dv", - "dvbsub", - "dvbtxt", - "dxa", - "ea", - "eac3", - "ea_cdata", - "epaf", - "exr_pipe", - "f32be", - "f32le", - "ec3", - "evc", - "f4v", - "f64be", - "f64le", - "fap", - "far", - "fbdev", - "ffmetadata", - "filmstrip", - "film_cpk", - "fits", - "flac", - "flic", - "flm", - "flv", - "frm", - "fsb", - "fwse", - "g722", - "g723_1", - "g726", - "g726le", - "g729", - "gdm", - "gdv", - "genh", - "gif", - "gsm", - "gxf", - "h261", - "h263", - "h264", - "h265", - "h266", - "h26l", - "hca", - "hcom", - "hevc", - "hls", - "hnm", - "ice", - "ico", - "idcin", - "idf", - "idx", - "iec61883", - "iff", - "ifv", - "ilbc", - "image2", - "imf", - "imx", - "ingenient", - "ipmovie", - "ipu", - "ircam", - "ism", - "isma", - "ismv", - "iss", - "it", - "iv8", - "ivf", - "ivr", - "j2b", - "j2k", - "jack", - "jacosub", - "jv", - "jpegls", - "jpeg", - "jxl", - "kmsgrab", - "kux", - "kvag", - "lavfi", - "laf", - "lmlm4", - "loas", - "lrc", - "luodat", - "lvf", - "lxf", - "m15", - "m2a", - "m2ts", - "m4a", - "m4b", - "m4v", - "mac", - "mca", - "mcc", - "mdl", - "med", - "microdvd", - "mj2", - "mjpeg", - "mjpg", - "mk3d", - "mka", - "mks", - "mkv", - "mlp", - "mlv", - "mm", - "mmcmp", - "mmf", - "mms", - "mo3", - "mod", - "mods", - "moflex", - "mov", - "mp2", - "mp3", - "mp4", - "mpa", - "mpc", - "mpc8", - "mpeg", - "mpg", - "mpjpeg", - "mpl2", - "mpo", - "mpsub", - "mptm", - "msbc", - "msf", - "msnwctcp", - "msp", - "mt2", - "mtaf", - "mtm", - "mtv", - "mulaw", - "musx", - "mv", - "mvi", - "mxf", - "mxg", - "nc", - "nfo", - "nist", - "nistsphere", - "nsp", - "nst", - "nsv", - "nut", - "nuv", - "obu", - "ogg", - "okt", - "oma", - "omg", - "opus", - "openal", - "oss", - "osq", - "paf", - "pdv", - "pam", - "pbm", - "pcx", - "pgmyuv", - "pgm", - "pgx", - "photocd", - "pictor", - "pjs", - "plm", - "pmp", - "png", - "ppm", - "pp", - "psd", - "psm", - "psp", - "psxstr", - "pt36", - "ptm", - "pulse", - "pva", - "pvf", - "qcif", - "qcp", - "qdraw", - "r3d", - "rawvideo", - "rco", - "rcv", - "realtext", - "redspark", - "rgb", - "rl2", - "rm", - "roq", - "rpl", - "rka", - "rsd", - "rso", - "rt", - "rtp", - "rtsp", - "s16be", - "s16le", - "s24be", - "s24le", - "s32be", - "s32le", - "s337m", - "s3m", - "s8", - "sami", - "sap", - "sb", - "sbc", - "sbg", - "scc", - "sdns", - "sdp", - "sdr2", - "sds", - "sdx", - "ser", - "sf", - "sfx", - "sfx2", - "sga", - "sgi", - "shn", - "siff", - "sln", - "smi", - "smjpeg", - "smk", - "smush", - "sndio", - "sol", - "son", - "sox", - "spdif", - "sph", - "srt", - "ss2", - "ssa", - "st26", - "stk", - "stl", - "stm", - "stp", - "str", - "sub", - "sup", - "svag", - "svg", - "svs", - "sw", - "swf", - "tak", - "tco", - "tedcaptions", - "thd", - "thp", - "tiertexseq", - "tif", - "tiff", - "tmv", - "truehd", - "ts", - "tta", - "tty", - "txd", - "txt", - "ty", - "ty+", - "u16be", - "u16le", - "u24be", - "u24le", - "u32be", - "u32le", - "u8", - "ub", - "ul", - "ult", - "umx", - "usm", - "uw", - "v", - "v210", - "v210x", - "vag", - "vb", - "vc1", - "vc1test", - "vidc", - "video4linux2", - "viv", - "vividas", - "vivo", - "vmd", - "vobsub", - "vob", - "voc", - "vpk", - "vplayer", - "vqe", - "vqf", - "vql", - "vt", - "vtt", - "vvc", - "w64", - "wa", - "wav", - "way", - "wc3movie", - "webm", - "webp", - "webvtt", - "wma", - "wmv", - "wow", - "wsaud", - "wsd", - "wsvqa", - "wtv", - "wv", - "wve", - "x11grab", - "xa", - "xbin", - "xl", - "xm", - "xmd", - "xmv", - "xpk", - "xvag", - "xwma", - "y4m", - "yop", - "yuv", - "yuv10", - ], + images: imageInputs, + audio: audioInputs, + video: videoInputs, + subtitles: subtitleInputs, }, to: { - muxer: [ - "264", - "265", - "266", - "302", - "3g2", - "3gp", - "a64", - "aac", - "ac3", - "ac4", - "adts", - "adx", - "afc", - "aif", - "aifc", - "aiff", - "al", - "amr", - "amv", - "apm", - "apng", - "aptx", - "aptxhd", - "asf", - "ass", - "ast", - "au", - "aud", - "av1.mkv", - "av1.mp4", - "avi", - "avif", - "avs", - "avs2", - "avs3", - "bit", - "bmp", - "c2", - "caf", - "cavs", - "chk", - "cpk", - "cvg", - "dfpwm", - "dnxhd", - "dnxhr", - "dpx", - "drc", - "dts", - "dv", - "dvd", - "eac3", - "ec3", - "evc", - "exr", - "f4v", - "ffmeta", - "fits", - "flac", - "flm", - "flv", - "g722", - "gif", - "gsm", - "gxf", - "h261", - "h263", - "h264.mkv", - "h264.mp4", - "h265.mkv", - "h265.mp4", - "h266.mkv", - "hdr", - "hevc", - "ico", - "im1", - "im24", - "im8", - "ircam", - "isma", - "ismv", - "ivf", - "j2c", - "j2k", - "jls", - "jp2", - "jpeg", - "jpg", - "js", - "jss", - "jxl", - "latm", - "lbc", - "ljpg", - "loas", - "lrc", - "m1v", - "m2a", - "m2t", - "m2ts", - "m2v", - "m3u8", - "m4a", - "m4b", - "m4v", - "mjpeg", - "mjpg", - "mka", - "mkv", - "mlp", - "mmf", - "mov", - "mp2", - "mp3", - "mp4", - "mpa", - "mpd", - "mpeg", - "mpg", - "msbc", - "mts", - "mxf", - "nut", - "obu", - "oga", - "ogg", - "ogv", - "oma", - "opus", - "pam", - "pbm", - "pcm", - "pcx", - "pfm", - "pgm", - "pgmyuv", - "phm", - "pix", - "png", - "ppm", - "psp", - "qoi", - "ra", - "ras", - "rco", - "rcv", - "rgb", - "rm", - "roq", - "rs", - "rso", - "sb", - "sbc", - "scc", - "sf", - "sgi", - "sox", - "spdif", - "spx", - "srt", - "ssa", - "sub", - "sun", - "sunras", - "sup", - "sw", - "swf", - "tco", - "tga", - "thd", - "tif", - "tiff", - "ts", - "tta", - "ttml", - "tun", - "ub", - "ul", - "uw", - "vag", - "vbn", - "vc1", - "vc2", - "vob", - "voc", - "vtt", - "vvc", - "w64", - "wav", - "wbmp", - "webm", - "webp", - "wma", - "wmv", - "wtv", - "wv", - "xbm", - "xface", - "xml", - "xwd", - "y", - "y4m", - "yuv", - ], + images: imageOutputs, + audio: Array.from(new Set([...audioOutputs, ...imageOutputs, ...videoOutputs])), + video: Array.from( + new Set([...videoOutputs, ...audioOutputs, ...imageOutputs, ...subtitleOutputs]), + ), + subtitles: subtitleOutputs, }, }; @@ -737,6 +853,8 @@ export async function convert( ); } else if (audioFormatsNoCover.includes(convertTo)) { extraArgs.push("-vn"); + } else if (imageOutputs.includes(convertTo) && audioInputs.includes(fileType)) { + extraArgs.push("-an"); } if (convertTo === "ico") { diff --git a/src/converters/main.ts b/src/converters/main.ts index d87ecd18..3ac17e74 100644 --- a/src/converters/main.ts +++ b/src/converters/main.ts @@ -315,7 +315,13 @@ for (const converterName in properties) { for (const ext of fromList) { if (!possibleTargets[ext]) possibleTargets[ext] = {}; - possibleTargets[ext][converterName] = [...toList]; + if (!possibleTargets[ext][converterName]) { + possibleTargets[ext][converterName] = [...toList]; + } else { + possibleTargets[ext][converterName] = [ + ...new Set([...possibleTargets[ext][converterName], ...toList]), + ]; + } } } } @@ -349,16 +355,13 @@ for (const converterName in properties) { if (!converterProperties) continue; + const targets = new Set(); for (const key in converterProperties.to) { - if (allTargets[converterName]) { - allTargets[converterName] = [ - ...allTargets[converterName], - ...(converterProperties.to[key] || []), - ]; - } else { - allTargets[converterName] = [...(converterProperties.to[key] || [])]; + for (const ext of converterProperties.to[key] || []) { + targets.add(ext); } } + allTargets[converterName] = Array.from(targets); } export const getAllTargets = () => { @@ -371,16 +374,13 @@ for (const converterName in properties) { if (!converterProperties) continue; + const inputs = new Set(); for (const key in converterProperties.from) { - if (allInputs[converterName]) { - allInputs[converterName] = [ - ...allInputs[converterName], - ...(converterProperties.from[key] || []), - ]; - } else { - allInputs[converterName] = converterProperties.from[key] || []; + for (const ext of converterProperties.from[key] || []) { + inputs.add(ext); } } + allInputs[converterName] = Array.from(inputs); } export const getAllInputs = (converter: string) => { diff --git a/tests/converters/ffmpeg.test.ts b/tests/converters/ffmpeg.test.ts index a6479cc9..aa4d3af5 100644 --- a/tests/converters/ffmpeg.test.ts +++ b/tests/converters/ffmpeg.test.ts @@ -117,6 +117,21 @@ test.each(["wav", "aac"])("drops video streams for %s output", async (ext) => { expect(calls[0]).toEqual(["-i", "in.mp3", "-vn", `out.${ext}`]); }); +test.each(["png", "jpg", "jpeg", "webp"])( + "drops audio streams when extracting cover art from audio to %s", + async (ext) => { + await convert("in.mp3", "mp3", ext, `out.${ext}`, undefined, mockExecFile); + + expect(calls[0]).toEqual(["-i", "in.mp3", "-an", `out.${ext}`]); + }, +); + +test.each(["png", "jpg", "jpeg", "webp"])("drops audio streams when extracting cover art from audio to %s", async (ext) => { + await convert("in.mp3", "mp3", ext, `out.${ext}`, undefined, mockExecFile); + + expect(calls[0]).toEqual(["-i", "in.mp3", "-an", `out.${ext}`]); +}); + test("places the cover art args after FFMPEG_OUTPUT_ARGS", async () => { process.env.FFMPEG_OUTPUT_ARGS = "-b:a 192k"; diff --git a/tests/converters/main.test.ts b/tests/converters/main.test.ts index 00b7bd92..453349c1 100644 --- a/tests/converters/main.test.ts +++ b/tests/converters/main.test.ts @@ -155,6 +155,33 @@ describe("converter registry", () => { expect(getPossibleTargets("jxl").libjxl).not.toContain("jxl"); expect(libreofficeProperties.from.text).not.toContain("xlsx"); expect(libreofficeProperties.to.text).not.toContain("xlsm"); + + // ffmpeg categories + const pngTargets = getPossibleTargets("png").ffmpeg ?? []; + expect(pngTargets).toContain("jpg"); + expect(pngTargets).toContain("webp"); + expect(pngTargets).toContain("gif"); + expect(pngTargets).not.toContain("mp3"); + expect(pngTargets).not.toContain("wav"); + expect(pngTargets).not.toContain("srt"); + expect(pngTargets).not.toContain("vtt"); + + const mp3Targets = getPossibleTargets("mp3").ffmpeg ?? []; + expect(mp3Targets).toContain("flac"); + expect(mp3Targets).toContain("wav"); + expect(mp3Targets).toContain("png"); + expect(mp3Targets).toContain("jpg"); + expect(mp3Targets).toContain("mp4"); + expect(mp3Targets).toContain("mkv"); + expect(mp3Targets).not.toContain("srt"); + expect(mp3Targets).not.toContain("vtt"); + + const srtTargets = getPossibleTargets("srt").ffmpeg ?? []; + expect(srtTargets).toContain("vtt"); + expect(srtTargets).toContain("ass"); + expect(srtTargets).not.toContain("png"); + expect(srtTargets).not.toContain("mp3"); + expect(srtTargets).not.toContain("mp4"); }); }); diff --git a/tests/integration/converters/all-formats.test.ts b/tests/integration/converters/all-formats.test.ts index 966c591b..ce443e7d 100644 --- a/tests/integration/converters/all-formats.test.ts +++ b/tests/integration/converters/all-formats.test.ts @@ -94,8 +94,8 @@ test("converts every saved PNG target for each converter", async () => { console.error = originalConsoleError; } - expect(testedTargets).toBe(558); - expect(successfulTargets).toBe(415); + expect(testedTargets).toBe(405); + expect(successfulTargets).toBe(370); expect(observedFailures.sort()).toEqual(expectedFailures); expect(failures).toEqual([]); }, 120000); diff --git a/tests/integration/converters/expected-failures.json b/tests/integration/converters/expected-failures.json index bc1399b7..c3a5498f 100644 --- a/tests/integration/converters/expected-failures.json +++ b/tests/integration/converters/expected-failures.json @@ -1,116 +1,6 @@ { "sample.png": [ - "ffmpeg:265", - "ffmpeg:266", - "ffmpeg:302", - "ffmpeg:3g2", - "ffmpeg:3gp", - "ffmpeg:aac", - "ffmpeg:ac3", - "ffmpeg:ac4", - "ffmpeg:adts", - "ffmpeg:adx", - "ffmpeg:afc", - "ffmpeg:aif", - "ffmpeg:aifc", - "ffmpeg:aiff", - "ffmpeg:al", - "ffmpeg:amr", - "ffmpeg:amv", - "ffmpeg:apm", - "ffmpeg:aptx", - "ffmpeg:aptxhd", - "ffmpeg:ass", - "ffmpeg:ast", - "ffmpeg:au", - "ffmpeg:aud", - "ffmpeg:avs", - "ffmpeg:avs2", - "ffmpeg:avs3", - "ffmpeg:bit", - "ffmpeg:c2", - "ffmpeg:caf", - "ffmpeg:cavs", - "ffmpeg:chk", - "ffmpeg:cvg", - "ffmpeg:dfpwm", - "ffmpeg:dnxhd", - "ffmpeg:dnxhr", - "ffmpeg:drc", - "ffmpeg:dts", - "ffmpeg:dv", - "ffmpeg:eac3", - "ffmpeg:ec3", - "ffmpeg:evc", - "ffmpeg:flac", - "ffmpeg:g722", - "ffmpeg:gsm", - "ffmpeg:gxf", - "ffmpeg:h261", - "ffmpeg:h263", - "ffmpeg:h265.mkv", - "ffmpeg:h265.mp4", - "ffmpeg:h266.mkv", - "ffmpeg:hevc", - "ffmpeg:ircam", - "ffmpeg:ivf", - "ffmpeg:js", - "ffmpeg:jss", - "ffmpeg:latm", - "ffmpeg:lbc", - "ffmpeg:loas", - "ffmpeg:lrc", - "ffmpeg:m2a", - "ffmpeg:m4a", - "ffmpeg:mka", - "ffmpeg:mlp", - "ffmpeg:mmf", - "ffmpeg:mp2", - "ffmpeg:mp3", - "ffmpeg:mpa", - "ffmpeg:msbc", - "ffmpeg:oga", - "ffmpeg:ogg", - "ffmpeg:oma", - "ffmpeg:opus", - "ffmpeg:pcm", - "ffmpeg:psp", - "ffmpeg:rco", - "ffmpeg:rcv", - "ffmpeg:rso", - "ffmpeg:sb", - "ffmpeg:sbc", - "ffmpeg:scc", - "ffmpeg:sf", - "ffmpeg:sox", - "ffmpeg:spdif", - "ffmpeg:spx", - "ffmpeg:srt", - "ffmpeg:ssa", - "ffmpeg:sub", - "ffmpeg:sup", - "ffmpeg:sw", - "ffmpeg:tco", - "ffmpeg:thd", - "ffmpeg:tta", - "ffmpeg:ttml", - "ffmpeg:tun", - "ffmpeg:ub", - "ffmpeg:ul", - "ffmpeg:uw", - "ffmpeg:vag", - "ffmpeg:vc1", - "ffmpeg:vc2", - "ffmpeg:voc", - "ffmpeg:vtt", - "ffmpeg:vvc", - "ffmpeg:w64", - "ffmpeg:wav", - "ffmpeg:webm", - "ffmpeg:wv", "ffmpeg:xface", - "ffmpeg:xml", - "ffmpeg:y4m", "graphicsmagick:8bim", "graphicsmagick:8bimtext", "graphicsmagick:8bimwtext",