ffmpeg One-Liners

Written by Josh on August 29, 2015

One of the beauties of a *nix (Linux/Unix/OS X) shell is the power of wildcards. Combined with powerful tools such as ffmpeg, one can convert entire folders of audio files to the same format or select video files of a certain size. Below are some one-liners that I have used.

I was recently given a folder of audio files of various formats that I needed to put online. I could have publicized it as a mix of MP3s, WAVs, WMAs, and M4As, but I converted them all to MP3s with one giant command.

for f in ./{*,*/*}/*.{wav,wma,m4a}; do JONew=${f%.wav}; JOTemp=${JONew%.wma}; JONew=${JOTemp%.m4a}.mp3; echo $f to $JONew; ffmpeg -i "$f" "$JONew"; rm "$f"; done

for f in ./{*,*/*}/*.{wav,wma,m4a} iterates over every WAV, WMA, and M4A either two or three levels below my working directory. JONew=${f%.wav}; JOTemp=${JONew%.wma}; JONew=${JOTemp%.m4a}.mp3; removes the old extensions and adds the MP3 extension. I then echo the original and new file name and convert the former to the latter using ffmpeg, removing the original.

Another useful conglomeration command is below, finding all MP4s and filtering them by their dimensions. Both commands iterate over a folder and use ffprobe, a command in the ffmpeg family that gives information about a file, to output a JSON representation of the video information. The output runs through jq (available on GitHub) to prettify the JSON, then grep to find the dimension for which I was looking. It then runs through jq a second time to select the information I wanted, displaying either just the filename or the filename and the height. jq is a command-line JSON parser. I likely could have used only one jq command and not use grep, but it was easier without reading the entire documentation of the tool. The -r flag on the first command outputs the filenames without quotes on separate lines, allowing me to pipe it to a file for later use.

for f in folder/*.MP4; do (ffprobe -of json -show_streams -show_format "$f" 2>/dev/null | jq -c '.'); done | grep '720,' | jq -r '.format.filename'
for f in folder/*.MP4; do (ffprobe -of json -show_streams -show_format "$f" 2>/dev/null | jq -c '.'); done | grep '720,' | jq -c '{filename: .format.filename, height: .streams[0].height}'
Copyright © 2014-2016 Joshua Oldenburg