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?

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
| improve this answer | |
  • 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 '19 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.

| improve this answer | |

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.