I want to write a command or script to find all my .mkv videos larger than 3Gb, then run ffmpeg to make them smaller (720p) and change the extension to mp4. I have it working except the file ends up with .mkv.mp4 extension.

I'm also sure there is probably a much better way of doing this, such as with a script. Here is what I have come up with:

find '/home/username/Videos/' -type f -size +3G -exec ffmpeg -i "{}" -c:v libx264 -c:a copy -acodec copy -vf scale="trunc(oh*a/2)*2:720" -preset superfast -crf 24 -b:v 400k "{}.mp4" \;

I would also like to have the output files to a directory like /home/username/Videos/Changed, and then delete the original .mkv.

Can anyone help teach me the best method to do this?

2 Answers 2


IMHO, the "Good" way to do this is to break it into two steps:

  1. Find the big files.
  2. "Fix" them.

And, I'd put step 2 into a bash script, stored in /home/username/bin/fixvideos

My find command would then look like:

find '/home/username/Videos/' -type f -name '*.mkv' -size +3G -print0 |\
    xargs -0 --no-run-if-empty /home/username/fixvideos

and, the script in /home/username/fixvideos is something like:

# handle "-v" or "--verbose" as optional 1st parameter, the rest are "*.mkv" files
# which will be rescaled and converted to ".mp4", using ffmpeg
declare -i verbose=0
if [[ "$1" = "-v" ]] || [[ "$1" = "--verbose" ]] ; then

while  [[ $# -ne 0 ]]  ; do
    # the base name, without the extension
    if [[ $verbose -ne 0 ]] ; then
       echo "Reading $1, writing $oname" >&2
    ffmpeg -i "$1" -c:v libx264 -c:a copy -acodec copy \
       -vf scale="trunc(oh*a/2)*2:720" -preset superfast \
       -crf 24 -b:v 400k "$oname"
    # shift all the filenames down so the next file is actually next
exit 0
  • Thanks @waltinator! It's great. It will take me some time to learn exactly how it works. I changed this line oname="$bname.mkv" to oname="$bname.mp4" and it worked. How can I have it save the new .mp4s to a different folder, like /home/username/Videos/Changed?
    – ticotexas
    Jan 22, 2019 at 19:43

If your filenames do not have spaces, newlines or other strange characters, try this:

for file in $(find '/home/username/Videos/' -type f -size +3G)
ffmpeg -i $file -c:v libx264 -c:a copy -vf [your_parameters] -preset [presetname] -crf 24 -b:v 400k ${file%%.mkv}.mp4

-c:a copy is the same as acodec copy. You don't need it repeated.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.