Total video time in a Directory
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