1

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

0

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:

#!/bin/bash
# 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
    verbose=1
    shift
fi

while  [[ $# -ne 0 ]]  ; do
    # the base name, without the extension
    bname="${1//.mkv}"
    oname="$bname.mkv"
    if [[ $verbose -ne 0 ]] ; then
       echo "Reading $1, writing $oname" >&2
    fi
    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
    shift
done
exit 0
1
  • 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
0

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)
do 
ffmpeg -i $file -c:v libx264 -c:a copy -vf [your_parameters] -preset [presetname] -crf 24 -b:v 400k ${file%%.mkv}.mp4
done

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

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .