Python Forum

Full Version: Get an FFMpeg pass to subprocess.PIPE to treat list as text file?
You're currently viewing a stripped down version of our content. View the full version with proper formatting.
The following FFMpeg command will import a text file to concatenate/join said file together:
ffmpeg -f concat -safe 0 -i "list_Of_Videos.txt" -c copy "output.mp4"

Alternatively, the following bash terminal will pipe traversed files in a directory:
ffmpeg -f concat -i <( for f in *.wav; do echo "file '$(pwd)/$f'"; done ) output.wav

My question regards the first statement. Can I substitute list_Of_Videos.txt with a python array list variable, instead?

FFMpegs requies that 2 streams be specified, one for stdout, the other for stderr:
process = subprocess.Popen(shlex.split(cmd),
                    stdout=subprocess.PIPE,
                    stderr=subprocess.STDOUT)
I don't want to utilize the Python built-in FFMpeg wrapper, but instead looking to work with the separate/stand-alone FFMpeg program.
Try this,work when i test.
import subprocess

list_of_files = ['v1.mp4', 'v2.mp4', 'v3.mp4']
# Prepare the concat list
concat_list = '\n'.join([f"file '{file}'" for file in list_of_files])

# FFmpeg command with protocol whitelist
cmd = [
    'ffmpeg',
    '-f', 'concat',
    '-safe', '0',
    '-protocol_whitelist', 'file,pipe',
    '-i', '-',
    '-c', 'copy',
    'output.mp4'
]
process = subprocess.Popen(
    cmd,
    stdin=subprocess.PIPE,
    stdout=subprocess.PIPE,
    stderr=subprocess.STDOUT,
    universal_newlines=True  # Ensure text mode for stdin
)

# Send the concat list to FFmpeg and get the output
output, _ = process.communicate(input=concat_list)
print(output)
By adding -protocol_whitelist file,pipe to FFmpeg command,
allow FFmpeg to use the necessary protocols to read your concat list from stdin and access the video files for concatenation.
(Nov-21-2024, 08:12 AM)snippsat Wrote: [ -> ]Try this,work when i test.
...
...
process = subprocess.Popen(
    cmd,
    stdin=subprocess.PIPE,
    stdout=subprocess.PIPE,
    stderr=subprocess.STDOUT,
    universal_newlines=True  # Ensure text mode for stdin
)
# Send the concat list to FFmpeg and get the output
output, _ = process.communicate(input=concat_list)
print(output)
...
...
Thank you very much. It worked. Just had to make minor changes.
Newer versions of ffmpeg require that the list of files, if one wishes to use pipe, be preceded with:
file file:'input_1.mp4' instead of file 'input_1.mp4'

Also for the statement:
output, _ = process.communicate(input='\n'.join(concat_list))
I had to prepend the list variable with '\n'.join method, as input= demanded an str variable, Expected type 'str', got 'List[str]' instead

Thank you again.