find -type f -name "*.mp4" -print0
Recursively search the current directory for normal files whose names end with .mp4 and print their relative path names, separated by null bytes. -print0 is safer than -print here, because newlines are valid characters in a filename. find(1)
| xargs -0
Use the input as arguments to the next command. Input is null-separated. xargs(1)
mplayer -vo dummy -ao dummy -identify 2>/dev/null
This is the command that xargs is running. Using dummy video and audio drivers, show file parameters in an easily parseable format. Discard any output from STDERR. mplayer(1)
| perl -nle
Pipe the output to Perl. Perl will read lines of input into the $_ variable, stripping newlines from the end. perlrun(1)
/ID_LENGTH=([0-9\.]+)/
If the line matches this regular expression, capture the number following "ID_LENGTH=",
&& ($t +=$1)
then increase the variable $t by the number captured in the first match,
&& printf "%02d:%02d:%02d\n",$t/3600,$t/60%60,$t%60'
and calculate hours, minutes, and seconds from $t, which is a count of seconds. Because of the -l in the perl invocation, a newline is added automatically to print statements, but not printf, so the format string contains one ("\n").
| tail -n 1
Only print the last line of output. tail(1)
To make this pipeline into a single command, you can create a shell function in your .bashrc or whatever rc-file your shell uses. Here's an example:
vid_lengths() {
find -type f -name "*.mp4" -print0 \
| xargs -0 mplayer -vo dummy -ao dummy -identify 2>/dev/null \
| perl -nle '/ID_LENGTH=([0-9\.]+)/ && ($t +=$1) && printf "%02d:%02d:%02d\n",$t/3600,$t/60%60,$t%60' \
| tail -n 1
}
mp4file or any audio/video file withexiftool -p '$Duration#' file.mp4– Stephane Chazelas Jan 25 at 21:56