Reputation: 3650
I'm trying to pass a glob pattern to ffmpeg via subprocess.check_output()
. This appears to be having an issue as the output is what I would expect if the pattern was passed within quotes.
Example:
subprocess.check_output([ffmpeg_path, '-pattern_type', 'glob', '-i', '/tmp/*?(jpg|jpeg)'...])
This results in:
/tmp/*?(jpg|jpeg): No such file or directory.
Which is different than the "no matches" error I receive if run this command via the shell. What appears to be happening is that the command is being composed as
ffmpeg -pattern_type 'glob' -i '/tmp/*?(jpg|jpeg)'
and what I'd want is (note lack of quotations)
ffmpeg -pattern_type glob -i /tmp/*?(jpg|jpeg)
Something of note is that I am passing in the directory so directory + '/*?(jpg|jpeg)'
is what is in the list being passed to check_output()
. This may be part of the issue.
How would I prevent this, or how would I pass the raw arguments desired?
ffmpeg version when running on development machine:
ffmpeg version 4.4.1 Copyright (c) 2000-2021 the FFmpeg developers
built with Apple clang version 13.0.0 (clang-1300.0.29.3)
configuration: --prefix=/usr/local/Cellar/ffmpeg/4.4.1_5 --enable-shared --enable-pthreads --enable-version3 --cc=clang --host-cflags= --host-ldflags= --enable-ffplay --enable-gnutls --enable-gpl --enable-libaom --enable-libbluray --enable-libdav1d --enable-libmp3lame --enable-libopus --enable-librav1e --enable-librist --enable-librubberband --enable-libsnappy --enable-libsrt --enable-libtesseract --enable-libtheora --enable-libvidstab --enable-libvmaf --enable-libvorbis --enable-libvpx --enable-libwebp --enable-libx264 --enable-libx265 --enable-libxml2 --enable-libxvid --enable-lzma --enable-libfontconfig --enable-libfreetype --enable-frei0r --enable-libass --enable-libopencore-amrnb --enable-libopencore-amrwb --enable-libopenjpeg --enable-libspeex --enable-libsoxr --enable-libzmq --enable-libzimg --disable-libjack --disable-indev=jack --enable-avresample --enable-videotoolbox
and using the ffmpeg amd64 static build when deployed.
Upvotes: 1
Views: 176
Reputation: 32094
The quotes is not the issue, the FFmpeg glob syntax is a little different than the one you are using.
Here is an example for a correct syntax:
subprocess.check_output([ffmpeg_path, '-vcodec', 'mjpeg', '-f', 'image2', '-pattern_type', 'glob', '-i', '/tmp/*?{jpg,jpeg}', 'test.mp4'])
'-vcodec', 'mjpeg'
.'-f', 'image2'
.'/tmp/*?{jpg,jpeg}'
(instead of /tmp/*?(jpg|jpeg)
).The command line includes the quotes, and it's working with the them.
ffmpeg -vcodec mjpeg -f image2 -pattern_type glob -i "/tmp/*?{jpg,jpeg}" -vcodec libx264 test.mp4
I tested the Python code under Ubuntu 18.04 (using VirtualBox).
Using command line (console):
Changing directory to /tmp
(in Ubuntu it supposed to be existed):
cd /tmp
Checking FFmpeg version:
ffmpeg -version
Output:
ffmpeg version 3.1.3-static http://johnvansickle.com/ffmpeg/ Copyright (c) 2000-2016 the FFmpeg developers
built with gcc 5.4.1 (Debian 5.4.1-1) 20160803
(I think it's the default version of Ubuntu 18.04).
Creating 10 (synthetic pattern) files with jpg extension and 7 files with jpeg extension:
ffmpeg -f lavfi -i testsrc=size=192x108:rate=1:duration=10 %d.jpg
ffmpeg -f lavfi -i testsrc=size=192x108:rate=1:duration=7 %d.jpeg
List jpg and jpeg files:
ls *?{jpg,jpeg}
Output:
10.jpg 1.jpeg 1.jpg 2.jpeg 2.jpg 3.jpeg 3.jpg 4.jpeg 4.jpg 5.jpeg 5.jpg 6.jpeg 6.jpg 7.jpeg 7.jpg 8.jpg 9.jpg
Encoding the files (in command line):
ffmpeg -y -vcodec mjpeg -f image2 -pattern_type glob -i "/tmp/*?{jpg,jpeg}" -vcodec libx264 test.mp4
Verifying there are 17 video frames using FFprobe:
ffprobe -v error -select_streams v:0 -count_frames -show_entries stream=nb_read_frames -print_format csv test.mp4
Output:
stream,17
delete test.mp4:
rm test.mp4
Python test (still in folder /tmp
, and console):
Checking Python version:
python3 --version
Output:
Python 3.7.4
Copy test.py
into /tmp
folder.
Content of test.py
(the file is in the same folder: /tmp
):
import subprocess
ffmpeg_path = 'ffmpeg'
subprocess.check_output([ffmpeg_path, '-vcodec', 'mjpeg', '-f', 'image2', '-pattern_type', 'glob', '-i', '/tmp/*?{jpg,jpeg}', 'test.mp4'])
Executing the Python script form shell:
python3 test.py
Output:
ffmpeg version 3.1.3-static http://johnvansickle.com/ffmpeg/ Copyright (c) 2000-2016 the FFmpeg developers
...
frame= 17
Upvotes: 1
Reputation: 781004
Your wildcard pattern uses a bash
extension, which ffmpeg
probably doesn't support.
Instead, use multiple -i
options, with standard wildcards.
subprocess.check_output([ffmpeg_path, '-pattern_type', 'glob', '-i', '/tmp/*.jpg', '-i', '/tmp/*.jpeg', ...])
There are no actual quotes being added. When you use shell=False
, the list elements are passed as is directly to the program, without going through a shell, so no quoting is needed. The documentation doesn't explain it accurately -- what they mean is that this acts as if you were quoting all the arguments.
Upvotes: 2