1

I am trying to run an autocrop ffmpeg command in python. The command works in Ruby so I am not sure why it isn't working in Python. I am just trying to run an autocrop on the videos just in case they have black bars on the top/bottom/sides.

I found this bit of code from this thread a while ago and it has worked for me in Ruby, which makes me think this might be a Python syntax issue because I am running the same version of FFMPEG on my computer.

Would appreciate any help on this

Here is the command from that thread in my Python file:

Code

import subprocess

in_file = /path/input.mp4
out_file = /path/output.mp4

cmd = [
    'ffmpeg', 
    '-y',
    '-i', in_file,
    '-vf', 'cropdetect -f null - 2>&1 | awk \'/crop/ { print \$NF }\' | tail -1',
    out_file
]
subprocess.Popen(cmd, stdout = subprocess.PIPE, bufsize=10**8)

Error

ffmpeg version 3.3.4 Copyright (c) 2000-2017 the FFmpeg developers
  built with Apple LLVM version 7.0.2 (clang-700.1.81)
  configuration: --prefix=/usr/local/Cellar/ffmpeg/3.3.4 --enable-shared --enable-pthreads --enable-gpl --enable-version3 --enable-hardcoded-tables --enable-avresample --cc=clang --host-cflags= --host-ldflags= --enable-libass --enable-libfdk-aac --enable-libfreetype --enable-libmp3lame --enable-libvorbis --enable-libvpx --enable-libx264 --enable-libx265 --enable-libxvid --enable-opencl --enable-videotoolbox --disable-lzma --enable-nonfree --enable-vda
  libavutil      55. 58.100 / 55. 58.100
 [...]
Stream mapping:
  Stream #0:0 -> #0:0 (h264 (native) -> h264 (libx264))
  Stream #0:1 -> #0:1 (aac (native) -> aac (native))
Press [q] to stop, [?] for help
[AVFilterGraph @ 0x7f8c23d1dc60] No such filter: 'cropdetect -f null - 2>&1 | awk /crop/ { print $NF } | tail -1'
Error reinitializing filters!
Failed to inject frame into filter network: Invalid argument
Error while processing the decoded data for stream #0:0
[aac @ 0x7f8c2400a400] Qavg: 45917.641
[aac @ 0x7f8c2400a400] 2 frames left in the queue on closing
Conversion failed!

After more searching, I discovered another approach and have been working on running this but still with no luck:

Code

import subprocess

in_file = /path/input.mp4
out_file = /path/output.mp4

cmd = [
    'ffmpeg', 
    '-y',
    '-i', in_file,
    '-vf', 'cropdetect=24:16:0 -y -crf 51 ultrafast -f null /dev/null 2>&1 | grep -o crop=.* | sort -bh | uniq -c | sort -bh | tail -n1 | grep -o crop=.*', 
    out_file
]
subprocess.Popen(cmd, stdout = subprocess.PIPE, bufsize=10**8)

Error

ffmpeg version 3.3.4 Copyright (c) 2000-2017 the FFmpeg developers
  built with Apple LLVM version 7.0.2 (clang-700.1.81)
  configuration: --prefix=/usr/local/Cellar/ffmpeg/3.3.4 --enable-shared --enable-pthreads --enable-gpl --enable-version3 --enable-hardcoded-tables --enable-avresample --cc=clang --host-cflags= --host-ldflags= --enable-libass --enable-libfdk-aac --enable-libfreetype --enable-libmp3lame --enable-libvorbis --enable-libvpx --enable-libx264 --enable-libx265 --enable-libxvid --enable-opencl --enable-videotoolbox --disable-lzma --enable-nonfree --enable-vda
  libavutil      55. 58.100 / 55. 58.100
[ ... ]
Stream mapping:
  Stream #0:0 -> #0:0 (h264 (native) -> h264 (libx264))
  Stream #0:1 -> #0:1 (aac (native) -> aac (native))
Press [q] to stop, [?] for help
[01/Oct/2017 16:44:25] "GET /home/ HTTP/1.1" 200 13844
[cropdetect @ 0x7f85aca02d00] [Eval @ 0x7fff5cfc1820] Undefined constant or missing '(' in 'y-crf51ultrafast-fnull/dev/null2>&1|grep-ocrop=.*|sort-bh|uniq-c|sort-bh|tail-n1|grep-ocrop=.*'
[cropdetect @ 0x7f85aca02d00] Unable to parse option value "0 -y -crf 51 ultrafast -f null /dev/null 2>&1 | grep -o crop=.* | sort -bh | uniq -c | sort -bh | tail -n1 | grep -o crop=.*"
[cropdetect @ 0x7f85aca02d00] [Eval @ 0x7fff5cfc18a0] Undefined constant or missing '(' in 'y-crf51ultrafast-fnull/dev/null2>&1|grep-ocrop=.*|sort-bh|uniq-c|sort-bh|tail-n1|grep-ocrop=.*'
[cropdetect @ 0x7f85aca02d00] Unable to parse option value "0 -y -crf 51 ultrafast -f null /dev/null 2>&1 | grep -o crop=.* | sort -bh | uniq -c | sort -bh | tail -n1 | grep -o crop=.*"
[cropdetect @ 0x7f85aca02d00] Error setting option reset to value 0 -y -crf 51 ultrafast -f null /dev/null 2>&1 | grep -o crop=.* | sort -bh | uniq -c | sort -bh | tail -n1 | grep -o crop=.*.
[Parsed_cropdetect_0 @ 0x7f85aca02c40] Error applying options to the filter.
[AVFilterGraph @ 0x7f85ac904e20] Error initializing filter 'cropdetect' with args '24:16:0 -y -crf 51 ultrafast -f null /dev/null 2>&1 | grep -o crop=.* | sort -bh | uniq -c | sort -bh | tail -n1 | grep -o crop=.*'
Error reinitializing filters!
Failed to inject frame into filter network: Invalid argument
Error while processing the decoded data for stream #0:0
[aac @ 0x7f85ad805000] Qavg: 45917.641
[aac @ 0x7f85ad805000] 2 frames left in the queue on closing
Conversion failed!

2 Answers 2

3

Check the line [AVFilterGraph @ 0x7f85ac904e20] Error initializing filter ..

What you think are piped shell commands is passed as a single argument to ffmpeg, which confuses it.

Add a print(cmd) before you run the command and you will see that the '-vf' flag just gets a very large argument.

Sign up to request clarification or add additional context in comments.

2 Comments

do you have any idea why it would work when i am running '-vf', 'crop=500:500, pad=width=550:height=550:x=25:y=25:color=white', in the -vf line
Because that is a valid argument for -vf. All commandline tools fundamentally accept an array of strings, and each string can contain whitespaces - a frequent stumbling block. So -vf, filter_arg1:filter arg two with spaces is fundamentally different from -vf, filter_arg1:filter, arg, two, with, spaces
0

In case it helps anyone in the future, here is one solution to the problem I was facing. I run the cropdetect in a seperate ffmpeg command and store its output as a variable.

I'm not so familiar with python so this solution might not be the most elegant, if anyone with more python experience has a better way of formatting the subprocess layout, it would be awesome to see a better layout

I tested this and it works:

import subprocess

in_file = '/path/input.mp4'
out_file = '/path/output.mp4'

crop_dimensions = subprocess.Popen(['ffmpeg -i ' + in_file + ' -vf cropdetect -f null - 2>&1 | awk \'/crop/ { print $NF }\' | tail -1'], shell=True, stdout=subprocess.PIPE).stdout.read().strip()

cmd = [
    'ffmpeg', 
    '-y',
    '-i', in_file,
    '-vf', crop_dimensions,
    out_file
]
subprocess.Popen(cmd, stdout = subprocess.PIPE, bufsize=10**8)

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.