How can I get duration of all video files in a folder containing multiple subfolders?

5,362

Solution 1

You could use this instead which finds you all your mp4's in a specific folder and all subfolders and sums their duration to a total. This takes also care if they have special characters like a space etc.

find ~/Videos/tutorials/ -name "*.mp4" -printf "\"%p\" " | xargs exiftool -n -q -p '${Duration;our $sum;$_=ConvertDuration($sum+=$_)}' | tail -n 1

To see the totals of every subfolder aswell

#!/bin/bash

SEARCHPATH=~/Videos/tutorials

echo "## TOTAL OF EVERY MP4"
find  $SEARCHPATH -name "*.mp4" -printf "\"%p\" " | xargs exiftool -n -q -p '${Duration;our $sum;$_=ConvertDuration($sum+=$_)}' | tail -n 1

find $SEARCHPATH -type d  > /tmp/allFolders.txt

while read -r; do
echo "## TOTAL OF $REPLY"
find "$REPLY" -maxdepth 1 -name "*.mp4" -printf "\"%p\" " | xargs exiftool -n -q -p '${Duration;our $sum;$_=ConvertDuration($sum+=$_)}' | tail -n 1
done < /tmp/allFolders.txt

#cleanup
rm /tmp/allFolders.txt

Solution 2

You should replace ./*.mp4 with "$d"/*.mp4:

 for d in ~/Videos/tutorials/*; do
   if [ -d "$d" ]; then
     exiftool -n -q -p '${Duration;our $sum;$_=ConvertDuration($sum+=$_)}' "$d"/*.mp4| tail -n1
   fi
 done

Your for loop is finding any directories in ~/Videos/tutorials/ and assigning its path to the value of the d variable. That's the directory you want to check for mp4 files with exiftool, whereas you're telling exiftool to use the current directory with ./.

Another approach would be to cd to the directory each time, so your code would become:

 for d in ~/Videos/tutorials/*; do
   if [ -d "$d" ]; then
     cd "$d"
     exiftool -n -q -p '${Duration;our $sum;$_=ConvertDuration($sum+=$_)}' ./*.mp4| tail -n1
   fi
 done

The following approach can be used if you have troublesome filenames for some of the mp4 files, such as containing spaces. It saves the filenames into an array, and expands them quoted in the exiftool command.

 for d in ~/Videos/tutorials/*; do
       if [ -d "$d" ]; then
         cd "$d"
         files=(./*.mp4)         
         exiftool -n -q -p '${Duration;our $sum;$_=ConvertDuration($sum+=$_)}' "${files[@]}"| tail -n1
       fi
     done
Share:
5,362

Related videos on Youtube

Backspace
Author by

Backspace

Updated on September 18, 2022

Comments

  • Backspace
    Backspace over 1 year

    I have a folder named tutorials. Inside it, there are about 15 folders each containing about 15-20 .mp4 video files. I want to get the total duration of all the files present in the folder tutorials. This is the code I have written so far:

     for d in ~/Videos/tutorials/*; do
       if [ -d "$d" ]; then
         exiftool -n -q -p '${Duration;our $sum;$_=ConvertDuration($sum+=$_)}' ./*.mp4| tail -n1
       fi
     done
    

    The above code, when executed, gives an error File not found: ./*.mp4 for each of the subfolders present inside tutorials. However, when the line

    exiftool -n -q -p '${Duration;our $sum;$_=ConvertDuration($sum+=$_)}' ./*.mp4| tail -n1
    

    is executed individually inside each sub-folders, I am able to get the correct output.

    What changes should I make in the above code to get it working?

  • Backspace
    Backspace over 6 years
    Can we modify it to calculate the sum of all individual durations obtained above , and append it at the end of the output ?
  • Ziazis
    Ziazis over 6 years
    You will have issues if the names ever get a space or the mp4 has a strange name. Those won't work then.
  • Arronical
    Arronical over 6 years
    Good point @Ziazis. It's a drawback of using a glob there I guess, I can protect the directory name by quoting, but not filenames. It'd be possible to loop through the files and use 'exiftool' on each, doing the addition outside of the exiftool command, but I suppose find is the better approach.
  • Ziazis
    Ziazis over 6 years
    Ah ok, couldn't read it out from your question. Just use the script that I edited. You could also create functions and call them via a parameter you call while running the script. So you could switch around what you actually want to see. Or you just leave them like that to always see everything.
  • Mike
    Mike almost 4 years
    Also you need to have exiftool installed: sudo apt install libimage-exiftool-perl, otherwise it will nag: xargs: exiftool: No such file or directory.