fluent-ffmpeg / node-fluent-ffmpeg

A fluent API to FFMPEG (http://www.ffmpeg.org)
MIT License
7.64k stars 874 forks source link

Input options parsing not working when using custom HTTP headers #1151

Open mulekick opened 2 years ago

mulekick commented 2 years ago

Version information

Code to reproduce

Case 1 Fluent-ffmpeg : works everytime, but impossible to fine tune HTTP headers spawned command + FFmpeg : works if you add quotes to input options and source

'use strict';

const
    // ------------------------------------
    ffmpeg = require(`fluent-ffmpeg`),
    // example
    url = `https://video.hosting.com/video.m3u8`,
    target = `/my/downloads/video.mp4`,
    // ------------------------------------
    USER_AGENT = `Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/92.0.4515.159 Safari/537.36`,
    REFERER_RGX = /^(?<referer>http|https:\/\/(?:[a-zA-Z0-9-]+\.)+[a-zA-Z0-9-]+)(?::\d+)?\/[^ "]+$/u,
    match = url.match(REFERER_RGX),
    [ referer ] = match === null ? [ `unknown` ] : match.slice(1),
    // ------------------------------------
    ffcmd = ffmpeg();

ffcmd
    .on(`start`, cmd => process.stdout.write(`${ cmd }\n`))
    .on(`stderr`, log => process.stdout.write(`${ log }\n`))
    .on(`end`, () => process.stdout.write(`Transcoding succeeded !\n`))
    .on(`error`, err => process.stdout.write(`Error: ${  err.message }\n`));

ffcmd
    .input(url)
    .inputOptions([
        // works everytime, but impossible to fine tune HTTP headers
        `-user_agent`, `${ USER_AGENT }`,
        `-referer`, `${ referer }/`
    ])
    .output(target)
    .run();

Case 2 Fluent-ffmpeg : works with a small fix in /lib/options/custom.js spawned command + FFmpeg : works if you add quotes to input options and source

'use strict';

const
    // ------------------------------------
    ffmpeg = require(`fluent-ffmpeg`),
    // example
    url = `https://video.hosting.com/video.m3u8`,
    target = `/my/downloads/video.mp4`,
    // ------------------------------------
    USER_AGENT = `Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/92.0.4515.159 Safari/537.36`,
    REFERER_RGX = /^(?<referer>http|https:\/\/(?:[a-zA-Z0-9-]+\.)+[a-zA-Z0-9-]+)(?::\d+)?\/[^ "]+$/u,
    match = url.match(REFERER_RGX),
    [ referer ] = match === null ? [ `unknown` ] : match.slice(1),
    // ------------------------------------
    ffcmd = ffmpeg();

ffcmd
    .on(`start`, cmd => process.stdout.write(`${ cmd }\n`))
    .on(`stderr`, log => process.stdout.write(`${ log }\n`))
    .on(`end`, () => process.stdout.write(`Transcoding succeeded !\n`))
    .on(`error`, err => process.stdout.write(`Error: ${  err.message }\n`));

ffcmd
    .input(url)
    .inputOptions([
        // works with a small fix in /lib/options/custom.js
        `-headers`, `User-Agent: ${ USER_AGENT }`,
        `-headers`, `Referer: ${ referer }/`
    ])
    .output(target)
    .run();

Case 3 Fluent-ffmpeg : never works spawned command + FFmpeg : works if you add quotes to input options and source

'use strict';

const
    // ------------------------------------
    ffmpeg = require(`fluent-ffmpeg`),
    // example
    url = `https://video.hosting.com/video.m3u8`,
    target = `/my/downloads/video.mp4`,
    // ------------------------------------
    USER_AGENT = `Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/92.0.4515.159 Safari/537.36`,
    REFERER_RGX = /^(?<referer>http|https:\/\/(?:[a-zA-Z0-9-]+\.)+[a-zA-Z0-9-]+)(?::\d+)?\/[^ "]+$/u,
    match = url.match(REFERER_RGX),
    [ referer ] = match === null ? [ `unknown` ] : match.slice(1),
    // ------------------------------------
    ffcmd = ffmpeg();

ffcmd
    .on(`start`, cmd => process.stdout.write(`${ cmd }\n`))
    .on(`stderr`, log => process.stdout.write(`${ log }\n`))
    .on(`end`, () => process.stdout.write(`Transcoding succeeded !\n`))
    .on(`error`, err => process.stdout.write(`Error: ${  err.message }\n`));

ffcmd
    .input(url)
    .inputOptions([
        // never works
        `-headers User-Agent: ${ USER_AGENT }`,
        `-headers Referer: ${ referer }/`
    ])
    .output(target)
    .run();

Expected results

The mp4 output file should be produced in each case.

Observed results

case 1 : the mp4 output file is produced.

case 2 (as I mentioned, implementing a small fix in /lib/options/custom.js produces the output file):

[NULL @ 0x559f0021c040] Unable to find a suitable output format for 'https://video.hosting.com/'
https://video.hosting.com/: Invalid argument
Error: ffmpeg exited with code 1: https://video.hosting.com/: Invalid argument

case 3 :

Unrecognized option 'headers User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/92.0.4515.159 Safari/537.36'.
Error splitting the argument list: Option not found
Error: ffmpeg exited with code 1: Unrecognized option 'headers User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/92.0.4515.159 Safari/537.36'.
Error splitting the argument list: Option not found

I know that I use FFmpeg 4.1 (can't update for now unfortunately), but I suspect this issue can be reproduced with FFmpeg 4.4 as well.

Checklist