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
for i in $mypath/*
in stead of for i in $mypath/{*.mp4,*.mkv,*.avi}
– sourav c.
Mar 23 '15 at 18:36
for i in $mypath/*
it lists other files with 0 duration. So, the application is different from SylvainPineau's answer but nonetheless useful :)
– PleaseHelp
Mar 24 '15 at 06:08
ffprobe
(package ffmpeg
) instead of avprobe
. Just switching the name in the script suffice (but attenction to the problem of spaces in the directory names.. can this be sorted?)
– Antonello
Nov 29 '18 at 11:08
E: File read error
while executing in a directory (have other files apart from video files). IMHOmediainfo
is comparatively slow thanavprobe
. It is taking time more than twice than that ofavprobe
. – sourav c. Mar 23 '15 at 19:45avprobe
as it's indeed much faster than mediainfo (I've also fixed the first version read error msg) – Sylvain Pineau Mar 23 '15 at 20:26