Is there a script(bash, python etc.) that outputs the total duration time of all video files in a Directory(recursively) ?
For e.g on executing the following :
script mypath
it gives x minutes/hours .
Is there a script(bash, python etc.) that outputs the total duration time of all video files in a Directory(recursively) ?
For e.g on executing the following :
script mypath
it gives x minutes/hours .
First install mediainfo with:
sudo apt-get install mediainfo
You can now use the following oneliner to get the total video time of a directory:
find . -type f -exec mediainfo --Inform="General;%Duration%" "{}" \; 2>/dev/null | awk '{s+=$1/1000} END {h=s/3600; s=s%3600; printf "%.2d:%.2d\n", int(h), int(s/60)}'
The find command will call mediainfo for every files recursively and get the video duration in ms.
Then the awk part will sum those values and return the total time in the HH:MM format.
Update: avprobe is indeed faster than mediainfo (thanks @souravc)
For better results please use the command below instead (you'll need to sudo apt-get install libav-tools first)
find . -type f -exec avprobe -v quiet -show_format_entry duration "{}" \; | awk '{s+=$1} END {h=s/3600; s=s%3600; printf "%.2d:%.2d\n", int(h), int(s/60)}'
You can use the following script to know Total Duration of all video files in a Directory recursively. I have used avprobe in the following script which comes with libav-tools
Install libav-tools as,
sudo apt-get install libav-tools
Save the script as get_video_duration.sh(say). Give it execution permission from a terminal as
chmod u+x get_video_duration.sh
How to run the script
To know total video duration of the directory /full/path/to/videodir, run with argument as
./get_video_duration.sh /full/path/to/videodir
Or to know total video duration of current directory run without any argument as
./get_video_duration.sh .
For Recursion append -R or -r or -recursive or --recursive after the directory path. For example to know total video duration of the directory /full/path/to/videodir recursively (also search all folders inside /full/path/to/videodir)
./get_video_duration.sh /full/path/to/videodir -R
The script is as following:
#!/bin/bash
mysep="======================================================================================"
mysmallsep="--------------------------------------------------------------------------------------"
if [ -n "$1" ];then
mypath="$1"
else
mypath="$(pwd)"
fi
declare -a my_path_array
get_duration(){
/usr/bin/avprobe "$1" 2>&1 | grep Duration | awk -F[:,] '{print int($2*3600+$3*60+$4)}'
}
print_duration(){
awk -v var="$1" 'BEGIN {print int(var/3600)"Hr "int((var%3600)/60)"Min "int(var%60)"Sec "}'
}
execute_it_now(){
echo -e "Video File\t\tVideo Duration"
echo $mysep
echo "$1"
echo $mysmallsep
j=0
for i in "$1"/{*.mp4,*.mkv,*.avi,*.flv} ## Put the existing video file extension you have
do
if [[ "$(get_duration "$i")" -ne "0" ]];then
echo -e "$(basename "$i")\t$(tput setaf 2)$(print_duration $(get_duration "$i"))$(tput sgr0)"
fi
let j=j+$(get_duration "$i") 2>/dev/null
done
echo $mysep
echo "Total Duration $(tput setaf 1)$(print_duration $j)$(tput sgr0)"
}
execute_these_now(){
for i in "$1"/{*.mp4,*.mkv,*.avi,*.flv} ## Put the existing video file extension you have
do
if [[ "$(get_duration "$i")" -ne "0" ]];then
echo -e "$(basename "$i")\t$(tput setaf 2)$(print_duration $(get_duration "$i"))$(tput sgr0)"
fi
done
}
add_these_now(){
j=0;
for i in "$1"/{*.mp4,*.mkv,*.avi,*.flv} ## Put the existing video file extension you have
do
let j=j+$(get_duration "$i") 2>/dev/null
done
echo $j
}
case "$2" in
-R|-r|-recursive|--recursive)
tmp=$(find $mypath -type d | xargs)
my_path_array=( $tmp )
echo -e "Video File\t\tVideo Duration"
echo $mysep
k=0;
for indx in $(seq ${#my_path_array[@]})
do
echo ${my_path_array[$(($indx-1))]}
echo $mysmallsep
execute_these_now ${my_path_array[$(($indx-1))]}
let k=k+$(add_these_now ${my_path_array[$(($indx-1))]})
done
echo $mysep
echo "Total Duration $(tput setaf 1)$(print_duration $k)$(tput sgr0)"
;;
*)
execute_it_now $mypath
;;
esac
Screen shot of execution of the script

Note: As I don't have any .mkv or .avi file in my home directory last two lines in the screen shot appeared with duration 0Hr 0Min 0Sec
Using ffprobe from FFmpeg (sudo apt-get install ffmpeg), the following FFmpeg command will obtain the length of one file (in seconds):
ffprobe -v error -show_entries format=duration -of default=noprint_wrappers=1:nokey=1 myvideofile
find can obtain a list of files (e.g. in the current directory), and apply the above command to each one:
find . -type f -exec ffprobe -v error -show_entries format=duration -of default=noprint_wrappers=1:nokey=1 "{}" \;
AWK can then be utilised to total the times of each file (formatted in hours, minutes and seconds):
find . -type f -exec ffprobe -v error -show_entries format=duration -of default=noprint_wrappers=1:nokey=1 "{}" \; | awk '{s+=$1} END {h=s/3600; m=(s%3600)/60; s=s%60; printf "%.2d:%.2d:%.2d\n", h, m, s}'
Libav is an abandoned free software project, forked from FFmpeg in 2011. It is no longer provided as an Ubuntu package.