Wednesday, October 11, 2023

Batch Video Conversion to MKV Using Linux and FFMPEG Without Extra Software

Background.  I'm a dual sport athlete.  I use a trail camera extensively.  It runs about 90 minutes on a charge and in that short time, it generates 15 GB of .MOV video. I can't really justify keeping that much data so I need a way to transcode from one format into .MKV using .h265

Note:  The levels that are set by flags produce a file that "sounds good to me" without overmodulation or lowering in quality.  My hearing is not perfect.  Judge for yourself.  The software I wrote works for me.

Requirements are: 

  • Linux.  Windows people this isn't for you.  Mac, I don't know.
  • ffmpeg.  The workhorse that does the conversion. (line 16)
  • mplayer.  Command line mp3 player for when file is done. (line 17)
  • One mp3 file.  I am sure you have one somewhere.
  • bash.  This is where the magic happens under terminal.
  • video file for conversion.  


Copy this script and save it in your home directory as normalizeit.sh .

#!/bin/bash
# flags in ffmpeg from https://stackoverflow.com/questions/58742765/convert-videos-from-264-to-265-hevc-with-ffmpeg;
# and https://superuser.com/questions/323119/how-can-i-normalize-audio-using-ffmpeg
# tweaks to quality and normalization are in https://ffmpeg.org/ffmpeg-filters.html#dynaudnorm
#
declare VAR1=$1;
declare VAR2=$VAR1.h265.mkv;
declare BEGIN=$( date '+%F_%H:%M:%S' )
# clear;
echo "Input File: >"$VAR1"<";
echo "Output File: >"$VAR2"<";
echo "started at " $BEGIN;
echo ;
echo ;
sleep 1;
ffmpeg -avoid_negative_ts make_zero -i "$VAR1" -filter:a "dynaudnorm=p=0.85:s=0" -c:v libx265 -vf scale=1920:1080 -vtag hvc1 "$VAR2";
mplayer play /home/bill/Bike-ring-bell.mp3;
echo "Converted " $VAR1 " to " $VAR2;
echo ;
echo ;
declare END=$( date '+%F_%H:%M:%S' )
echo "started at " $BEGIN;
echo "  ended at " $END;

Make the script executable by graphical means or "chmod 775 ~/normalizeit.sh"

Open terminal in the directory you wish to do your work.

~/normalizeit.sh "path to the file to be converted"


Run Time Process: 


The script will report back the following info:

  • Input File name that normalizeit.sh is working with.
  • Start time and date.
  • Pause for a second.
  • A lot of info that ffmpeg puts out with what it is doing to your file.
  • DURATION: has the length of time your input file is in Hours:Minutes:Seconds:Fraction
  • A Running Time Count will show until finished.
At the end:
  • The MP3 file you asked to be played in the script when done will sound off.
  • Output file will be created in the directory you ran normalizeit.sh
  • Converted message telling you input and output file names.
  • Start and end time for the conversion.
Further info:
  • normalizeit.sh can be added to another bash script for added flexibility.
  • Since my trail cam puts out 4 large files per workout, I simply added all four commands to a file with line 1 being #! /bin/bash to invoke the interpreter.
  • It plays an MP3 file at the end of each individual conversion. 
  • If you are going to create a batch file to run multiple files, you can add a line to play a different file to let you know that your conversion job has ended.
  • Or not.  A # character in column 1 in each line will comment out the line.
  • Output file name can be tailored in line 7 to not have the .h265.mkv extension if needed.

ffmpeg (line 16):

  • -avoid_negative_ts - will smooth over input file problems
  • make_zero - will correct the errors found to a zero in the time count in the video
  • -i "$VAR1" - use input file as stored in $VAR1
  • -filter a: - tells ffmpeg to process using the following filters
  • dynaudnorm - Normalize sound volume
  • p=0.85 - Maximum volume will be 85% to avoid distortion
  • s=0 - maintain audio quality as input file and do not compress
  • -c:v libx265 - create output file using h265
  • -vf scale=1920:1080 - scale to a maximum video of 1920 x 1080
  • vtag hvc1 "$VAR2" - create the output file named in $VAR2



No comments:

Post a Comment