Score:-1

Calculate video total video length and output as total with respective folder

pf flag

I'm working with some videos and I want to measure the total length of videos each folder contains and output it with the respective folder. Current structure is like this.

.
└── Parent folder/
    ├── Trip 1/
    │   ├── Video 1
    │   └── Video 2
    ├── Trip 2/
    │   ├── Video 3
    │   └── Video 4
    └── Trip 3/
        ├── Video 5
        └── Video 6

The output I'm trying to get is like this

Parent folder
  Trip 1 3h34m
  Trip 2 5h14m
  Trip 3 8h12m

So far I was able to get total of all 3 sub folders but I couldn't get it right to show it folder basis.

mediainfo '--Output=Video;%Duration%\n' *.mp4 | awk '{ sum += $1 } END { secs=sum/1000; h=int(secs/3600);m=int((secs-h*3600)/60);s=int(secs-h*3600-m*60); printf("%02d:%02d:%02d\n",h,m,s) }'

I'm open to use mediainfo or ffprobe packages or anything you suggest.

ar flag
Which distro and version of Linux are you using?
John Snape avatar
pf flag
@user68186 I'm using Ubuntu 22.0. Thank you!
Artur Meinild avatar
vn flag
@user68186 how is this question related to the Ubuntu version - so why ask?
ar flag
@ArturMeinild I wanted to know that OP is using one of the official flavors of Ubuntu that have not reached the End of Life (EOL) so that the question is on topic. There is [another stack exchange site](https://unix.stackexchange.com/) for generic Linux questions where such questions are welcome even for Debian, Mint or a very old versions of Ubuntu. General Linux questions are fine here as long as you are using a currently supported version of Ubuntu or its official flavors.
Artur Meinild avatar
vn flag
@user68186 what does it matter if the question is version agnostic? It almost seems if you're looking for a reason to close questions..
Score:0
cn flag

Your method is sound, you just need to nest it per folder.

find . -type d |while IFS= read dir; do
  t=$(mediainfo '--Output=Video;%Duration%\n' "$dir"/*.mp4 | awk '
    { sum += $1 }
    END {
      secs = int(sum / 1000 + 0.5);
      h = int(secs / 3600);
      m = int((secs - h * 3600) / 60);
      s = int(secs - h * 3600 - m * 60);
      printf("%02d:%02d:%02d\n", h, m, s)
    }') 2>/dev/null
  if [ "$t" != "00:00:00" ]; then
    echo "$dir: $t"
  fi
done \
  |sed -r 's:[^/]*/:--/:g; s:((--/)*)--/:\1-- :; s:--/:|   :g; s:([| ]*)-:\1|-:'

To adapt this to output hours and minutes as you requested in the question, change the printf statement to say printf "%dh%02.0fm", h, m + s/60 (this also rounds to the nearest minute).

I assume you already understand the mediainfo and awk commands since you supplied them, though I did change the millisecond conversion to be rounded. I've merely wrapped this in a find call that looks at all children directories of the current path (change . for another path) and loops through its output line by line (while IFS= read dir will read each line, even if there is spacing in it, into $dir. This will not work if you have linebreaks in your directory names).

Since the directory might not contain any .mp4 files, I've piped errors from the assignment to $t to /dev/null and then run a test to ensure the time isn't 00:00:00 (change that to 0h00m if you adapted the output). Then I print the directory and the time.

Finally, a sed uses extended regular expressions (-r) to convert this into a tree with four substitutions (s):

  1. Convert each parent directory name to two dashes (keep the trailing slash for now)
  2. Remove the final trailing slash
  3. Any parent remaining should get a pipe and spaces
  4. Add interim pipes
I sit in a Tesla and translated this thread with Ai:

mangohost

Post an answer

Most people don’t grasp that asking a lot of questions unlocks learning and improves interpersonal bonding. In Alison’s studies, for example, though people could accurately recall how many questions had been asked in their conversations, they didn’t intuit the link between questions and liking. Across four studies, in which participants were engaged in conversations themselves or read transcripts of others’ conversations, people tended not to realize that question asking would influence—or had influenced—the level of amity between the conversationalists.