When you use subprocess, your command must either be a string that looks exactly like what you would type on the command line (and you set shell=True), or a list where each command is an item in the list (and you take the default shell=False). In either case, you have to deal with the variable part of the string. For instance, the operating system has no idea what "%03d" is, you have to fill it in.

I can't tell from your question exactly what the parameters are, but lets assume you want to convert frame 3, it would look something like this in a string:

my_frame = 3
subprocess.call(
    'ffmpeg -r 10 -i frame%03d.png -r ntsc movie%03d.mpg' % (my_frame, my_frame),
    shell=True)

Its kinda subtle in this example, but that's risky. Suppose these things were in a directory whose name name had spaces (e.g., ./My Movies/Scary Movie). The shell would be confused by those spaces.

So, you can put it into a list and avoid the problem

my_frame = 3
subprocess.call([
    'ffmpeg',
    '-r', '10',
    '-i', 'frame%03d.png' % my_frame,
    '-r', 'ntsc',
    'movie%03d.mpg' % my_frame,
])

More typing, but safer.

Answer from tdelaney on Stack Overflow
🌐
GitHub
github.com › scivision › asyncio-subprocess-ffmpeg
GitHub - scivision/asyncio-subprocess-ffmpeg: Examples of Python asyncio.subprocess · GitHub
Examples of Python asyncio.subprocess with FFmpeg and also traditional synchronous processes.
Author   scivision
Discussions

python - subprocess call ffmpeg (command line) - Stack Overflow
I have been incorporating subprocess calls in my program. I have had no issues with subprocess calls for other commands, but I am having trouble getting the command line input ffmpeg -r 10 -i fram... More on stackoverflow.com
🌐 stackoverflow.com
Help me understand subprocess (vs OS, application is FFmpeg/FFprobe)
Pretty sure ffmpeg outputs to stderr (for god knows what reason). You'll need something more like this: process = subprocess.Popen( ['ffmpeg', '--help'], stderr=subprocess.PIPE, text=True, ) print(process.stderr.read()) (There may be a more elegant way to do it; I've never familiarized myself with subprocess.run.) More on reddit.com
🌐 r/learnpython
4
0
August 13, 2023
Multiple Ffmpeg stream into a single subprocess pipeline
Hi, Thanks for the packages! I just discovered it while doing research on an ffmpeg issue I have. I need to process both video stream and the metadata within OpenCV Python. I'm passing the video and data to OpenCV with the subprocess mod... More on github.com
🌐 github.com
1
March 14, 2022
python - Getting realtime output from ffmpeg to be used in progress bar (PyQt4, stdout) - Stack Overflow
I've looked at a number of questions but still can't quite figure this out. I'm using PyQt, and am hoping to run ffmpeg -i file.mp4 file.avi and get the output as it streams so I can create a prog... More on stackoverflow.com
🌐 stackoverflow.com
🌐
FFmpeg Python
kkroening.github.io › ffmpeg-python
ffmpeg-python: Python bindings for FFmpeg — ffmpeg-python documentation
Asynchronously invoke ffmpeg for the supplied node graph. ... A subprocess Popen object representing the child process.
🌐
Python-ffmpegio
python-ffmpegio.github.io › python-ffmpegio › adv-ffmpeg.html
ffmpegio.ffmpegprocess: Direct invocation of FFmpeg subprocess — python-ffmpegio 0.11.0 documentation
input (bytes-convertible object, optional) – input data buffer must be given if FFmpeg is configured to receive data stream from Python. It must be bytes convertible to bytes. **other_popen_kwargs (dict, optional) – other keyword arguments of Popen, defaults to {} ... ffmpegio.ffmpegprocess.run_two_pass(ffmpeg_args, pass1_omits=None, pass1_extras=None, overwrite=None, stdin=None, **other_run_kwargs) · run FFmpeg subprocess with standard pipes with a single transaction twice for 2-pass encoding
🌐
Superkogito
superkogito.github.io › blog › 2020 › 03 › 19 › ffmpeg_pipe.html
How to pipe an FFmpeg output and pass it to a Python variable?
March 19, 2020 - This blog post introduced a small example of reading the ffmpeg command pipe output and parsing the resulting wave data into a numpy array. This approach is a simpler and faster alternative to the classical convert, save then read.
🌐
GitHub
github.com › kkroening › ffmpeg-python › blob › master › ffmpeg › _run.py
ffmpeg-python/ffmpeg/_run.py at master · kkroening/ffmpeg-python
used with ``pipe:`` ffmpeg outputs). pipe_stderr: if True, connect pipe to subprocess stderr. quiet: shorthand for setting ``capture_stdout`` and · ``capture_stderr``. **kwargs: keyword-arguments passed to ``get_args()`` (e.g. ``overwrite_output=True``). · Returns: A `subprocess Popen`_ object representing the child process. · Examples: Run and stream input:: ·
Author   kkroening
Find elsewhere
🌐
Medium
artwilton.medium.com › running-ffmpeg-commands-from-a-python-script-676eaf2b2739
Running FFmpeg commands from a Python Script | by Arthur Wilton | Medium
May 4, 2021 - To run a shell command with subprocess ... be separated into their own list element. def buildFFmpegCommand(): final_user_input = grabUserInput() commands_list = [ ffmpeg, "-i", ......
🌐
Reddit
reddit.com › r/learnpython › help me understand subprocess (vs os, application is ffmpeg/ffprobe)
r/learnpython on Reddit: Help me understand subprocess (vs OS, application is FFmpeg/FFprobe)
August 13, 2023 -

I forgot to save some of my Jupyter notebook last night, so code that is psudo or actual runs will be marked

Some notes/context:

  • Development environment is Windows/Jupyter running whatever latest/stable Python (3.7?, no idea).

  • FFmpeg/FFprobe is open source video processing and querying software that runs on the host machine

  • This task is to ping FFMpeg on the host machine, and store the output as a variable for Python

I have this running using OS no problem (no pseudo, actually runs):

# importing os module 
import os

# Command to execute
cmd = 'ffmpeg -r 24 -i test1.mkv -r 24 -i test2.mkv -lavfi libvmaf="n_threads=20:n_subsample=10" -f null -'

#Using os.system() method
os.system(cmd)

Psudo output:

[Parsed_libvmaf_0 @ 00000148cfab6a80] VMAF score: 96.393400

Great!

But I need to store this as a variable in Python, which I believe is not possible with the OS.System method

But I just can't seem to figure out how to get subprocess to either work, or return the output (actual code):

# importing sibprocess module
import subprocess

# Command to execute
cmd = 'ffmpeg -r 24 -i test.mkv -r 24 -i testsrtlaopus111.mkv -lavfi libvmaf="n_threads=20:n_subsample=10" -f null -'

# Using os.system() method
returned_value = subprocess.check_output(cmd, shell=True)  

# Runs the cmd, returns output 
print('returned value:', returned_value)

Which runs, I can see the ffmpeg command running in terminal, but once the command in terminal finishes processing, the python returns:

returned value: b''

Instead of the desired output:

[Parsed_libvmaf_0 @ 00000148cfab6a80] VMAF score: 96.393400

What am I doing wrong here?

🌐
GitHub
github.com › kkroening › ffmpeg-python › issues › 647
Multiple Ffmpeg stream into a single subprocess pipeline · Issue #647 · kkroening/ffmpeg-python
March 14, 2022 - #!/usr/bin/env python3 import sys, json, klvdata; from subprocess import PIPE import subprocess as sp import cv2 import numpy import ffmpeg command = ['ffmpeg', '-i', 'DayFlight.mpg', '-map', '0:0', '-map', '0:d', '-pix_fmt', 'bgr24', '-c:v', 'rawvideo', '-an','-sn', '-f', 'image2pipe', '-', '-c:d', 'copy', '-f','data', ] pipe = sp.Popen(command, stdin=sp.PIPE, stdout=sp.PIPE, stderr=sp.PIPE, bufsize=10**8) while True: raw_image = pipe.stdout.read(1280*720*3) image = numpy.fromstring(raw_image, dtype='uint8') image = image.reshape((720,1280,3)) if image is not None: cv2.imshow('Video', image) if cv2.waitKey(1) & 0xFF == ord('q'): break for packet in klvdata.StreamParser(pipe.stdout): metadata = packet.MetadataList() print(metadata) pipe.stdout.flush() cv2.destroyAllWindows()
Author   seabass1217
🌐
Unixmen
unixmen.com › home › uncategorized › hack ffmpeg with python, part two
Hacking FFmpeg With Python, Part Two
So make sure you write it in the python interactive shell as we are going to make use of it. So far we have written some code in our interactive shell. Making use of the function which deals with parsing the information returned from ffprobe is really easy. Before making use of the above function it is needed to spawn a new process as shown below: cmds = ['/usr/local/bin/ffprobe', '-show_format', 'test.mp4'] format_p = subprocess.Popen(cmds, stdout=subprocess.PIPE, stdin=subprocess.PIPE, stderr=subprocess.PIPE)
🌐
GitHub
github.com › Ch00k › ffmpy
GitHub - Ch00k/ffmpy: Pythonic interface for FFmpeg/FFprobe command line · GitHub
... from ffmpy import FFmpeg ff = FFmpeg( inputs={'input.mp4': None}, outputs={'output.avi': None} ) ff.run() This will take the input.mp4 file in the current directory as the input, change the video container from MP4 to AVI without changing ...
Starred by 522 users
Forked by 59 users
Languages   Python 87.9% | Shell 6.2% | Go 4.6% | Makefile 1.3%
🌐
GitHub
github.com › scivision › PyLivestream
GitHub - scivision/PyLivestream: Pure Python FFmpeg-based live video / audio streaming to YouTube, Facebook, Periscope, Twitch, and more · GitHub
asyncio-subprocess-ffpmeg simple asyncio subprocess example that could also be used as a template for general asyncio subprocess Python use. ... If errors result from FFmpeg not in PATH environment variable, optionally set environment variable ...
Starred by 749 users
Forked by 164 users
Languages   Python 97.9% | Shell 2.1%
🌐
GitHub
github.com › kkroening › ffmpeg-python › blob › master › ffmpeg › tests › test_ffmpeg.py
ffmpeg-python/ffmpeg/tests/test_ffmpeg.py at master · kkroening/ffmpeg-python
data = ffmpeg.probe(TEST_INPUT_FILE1) assert set(data.keys()) == {'format', 'streams'} assert data['format']['duration'] == '7.036000' · · @pytest.mark.skipif(sys.version_info < (3, 3), reason='requires python3.3 or higher') def test__probe_timeout(): with pytest.raises(subprocess.TimeoutExpired) as excinfo: ffmpeg.probe(TEST_INPUT_FILE1, timeout=0) assert 'timed out after 0 seconds' in str(excinfo.value) ·
Author   kkroening
🌐
GitHub
github.com › ensarkovankaya › ffmpeg
GitHub - ensarkovankaya/ffmpeg: Generates ffmpeg commands programmatically with python.
from ffmpeg.generator import Command from ffmpeg.utils.codecs import Codec from ffmpeg.utils.filters import StreamSpecifier, ScaleFilter, FOAR import subprocess # Generating 10 Minute Video from Another Video input = "input.mp4" output = ...
Author   ensarkovankaya
🌐
Gumlet
gumlet.com › learn › ffmpeg-python
How to Use FFmpeg with Python in 2026? - Gumlet
January 22, 2026 - Integrating FFmpeg with Python is a powerful way to manage and manipulate multimedia files, offering both low-level control with subprocess and higher-level convenience with libraries like pydub and moviepy.
Top answer
1 of 9
23

In this specific case for capturing ffmpeg's status output (which goes to STDERR), this SO question solved it for me: FFMPEG and Pythons subprocess

The trick is to add universal_newlines=True to the subprocess.Popen() call, because ffmpeg's output is in fact unbuffered but comes with newline-characters.

cmd = "ffmpeg -i in.mp4 -y out.avi"
process = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.STDOUT,universal_newlines=True)
for line in process.stdout:
    print(line)

Also note that in this code sample the STDERR status output is directly redirected to subprocess.STDOUT

2 of 9
18

The only way I've found to get dynamic feedback/output from a child process is to use something like pexpect:

#! /usr/bin/python

import pexpect

cmd = "foo.sh"
thread = pexpect.spawn(cmd)
print "started %s" % cmd
cpl = thread.compile_pattern_list([pexpect.EOF,
                                   'waited (\d+)'])
while True:
    i = thread.expect_list(cpl, timeout=None)
    if i == 0: # EOF
        print "the sub process exited"
        break
    elif i == 1:
        waited_time = thread.match.group(1)
        print "the sub process waited %d seconds" % int(waited_time)
thread.close()

the called sub process foo.sh just waits a random amount of time between 10 and 20 seconds, here's the code for it:

#! /bin/sh

n=5
while [ $n -gt 0 ]; do
    ns=`date +%N`
    p=`expr $ns % 10 + 10`
    sleep $p
    echo waited $p
    n=`expr $n - 1`
done

You'll want to use some regular expression that matches the output you're getting from ffmpeg and does some kind of calculation on it to show the progress bar, but this will at least get you the unbuffered output from ffmpeg.

🌐
GitHub
gist.github.com › Hellowlol › 5f8545e999259b4371c91ac223409209
tqdm thread subprocess ffmpeg · GitHub
tqdm thread subprocess ffmpeg · Raw · tqdm_multithread.py · This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
🌐
Google Groups
groups.google.com › g › python-tornado › c › 6ExxyBetLoo
Ffmpeg via subprocess api
-------------------------------------------------cmd = ["/usr/bin/ffmpeg", "-threads", "2", "-f", "lavfi", "-i", "anullsrc=r16000:cl=stereo", "-re", "-i", "/dev/video0", "-c:a", "aac", "-strict", "experimental", "-b:a", "128k", "-ar", "44100", "-s", "640x480", "-vcodec", "libx264", "-x264-params", "keyint=120:scenecut=0", "-vb", "200k", "-pix_fmt", "yuv420p", "-f", "flv", "rtmp://a.rtmp.youtube.com/live2/<key>"] self.__streaming_process = Subprocess(cmd, stdout=Subprocess.STREAM) self.__streaming_process.set_exit_callback(self.__ffmpeg_closed) IOLoop.instance().add_timeout(time.time() + 10, self.do_fulfill_stop_streaming) while True: line = await self.__streaming_process.stdout.read_until(b"\n") if not line: self.logger.debug("nothing to show") await asyncio.sleep(.2) else: print(line) pass
Top answer
1 of 2
1

I would like to understand how to read the following ffmpeg instruction

Your ffmpeg command is semi-obfuscated by scripting so the actual command is not known, but here's an explanation of each option:

  • -i indicates the input.
  • -r 1 sets output frame rate to 1. This is not needed if you want to output a single image or if you want to output all images. In this example it is used to output one frame per second which would skip many frames.
  • -s qvga sets output width x height to "qvga" which is an alias for 320x240.
  • -t 1 sets the output duration to 1 second. This is not needed if you want to output a single image or if you want to output all images. It is often added by rookie users trying to output a single image but -frames:v 1 should be used instead.
  • -f image2 An often superfluous option used to set the output format or muxer. It is used if your output name is ambiguous (perhaps due to scripting). Otherwise, ffmpeg will automatically choose the proper muxer for image outputs.

how can l adapt it to get all the frames of a given video ?

The simplest, unscripted command to get all of the frames is:

ffmpeg -i input %04d.png

This will output 0001.png, 0002.png, 0003.png, etc. If you want more than a numerical sequence you can use something like output_%05d.png which would result in output_00001.png.

For more info see FFmpeg Documentation: Image Muxer.

2 of 2
1
import subprocess
L=subprocess.call('ffmpeg -i %s -r 1 -s qvga -t 1 -f image2 %s' % (videoName,frameName), shell=True)

Information:

  1. import subprocess: The subprocess module enables you to start new applications from your Python program.

  2. L=subprocess.call(...): Assign the output of the call() method to variable L.

  3. ffmpeg -i %s -r 1 -s qvga -t 1 -f image2 %s' % (videoName,frameName), shell=True: Command to run here ffmpeg

  4. -i %s: input file name gotten from videoName variable --> input file url

  5. -r 1: frame rate.

  6. -s qvga: frame size.

  7. -f image2: Force input or output file format

  8. -t 1: When used as an output option (before an output url), stop writing the output after its duration reaches duration.

  9. % (videoName,frameName): Python string formatting that will replace %s sequences in the previous string with the items in the tuple.

  10. shell=True: Make use of specific shell features like word splitting or parameter expansion

Usage:

#!/usr/bin/env python

import subprocess 
L=subprocess.call('ffmpeg -r 5 -i out.ogv fmprg_%04d.png', shell=True)
L()
  • Make executable: chmod u+x filename.sh,
  • Run with: ./filename.sh

Information:

fmprg_%04d.png: Creates images with 0000, 0001, 0002, 0004, ... between fmprg_ and .png.

Read:

man ffmpeg

https://pythonspot.com/en/tag/subprocess/