Function to get the duration of all videos in a folder(s)
did this function to generate the duration of all the video files in a folder or multiple folders, it works fine for my use (I am no Guru as you may have noticed) but when I give it a lot of folders the calculation get a bit borked.
If any good soul had the energy to look at it and give pointers I will be grateful, but you really don't have to
Code:
vidlength ()
{
back=$(pwd)
folder_length=
total_folder_length=
array=()
# Look at the root of the folder
# https://stackoverflow.com/a/23357277 How can I store find command result as arrays in Bash
# $REPLY is the default variable when 'read' is not given one
while IFS= read -r -d $'\0'; do
array+=("$REPLY")
done < <(find . -maxdepth 1 \( -iname '*.mkv' -o -iname '*.mp4' -o -iname '*.avi' \) -print0)
# exiftool -n -q -p '$Duration#' "${array[@]}" 2> /dev/null | awk '{sum += $0}; END{print sum}' GIVES TIME AS 78682.8
# exiftool -n -q -p '${Duration;our $sum;$_=ConvertDuration($sum+=$_)}' "${array[@]}" 2> /dev/null| tail -n1 GIVES TIME AS 0:21:51:22
# This command gives a result of '159' if the array is empty (2 minutes 39 seconds)
total_folder_length=$(exiftool -n -q -p '$Duration#' "${array[@]}" 2> /dev/null | awk '{sum += $0}; END{print sum}')
# I have to add this because for wathever reason the last command fills len with the number 159 when it finds no video in the folder or when the array is empty
if [[ "${total_folder_length%.*}" -eq 159 ]]; then
total_folder_length=0
fi
counter=$(echo ${#array[@]})
for folder in ./*; do
#find . -maxdepth 1 \( -iname '*.mkv' -o -iname '*.mp4' -o -iname '*.avi' \)
if [ -d "$folder" ]; then
array=() # Empty the array between loops
while IFS= read -r -d $'\0'; do
array+=("$REPLY")
done < <(find "$folder" \( -iname '*.mkv' -o -iname '*.mp4' -o -iname '*.avi' \) -print0)
# https://unix.stackexchange.com/a/170973 Way faster with exiftool
# I have to add this because for wathever reason the last command fills len with the number 159 when it finds no video in the folder or when the array is empty
folder_length=$(exiftool -n -q -p '$Duration#' "${array[@]}" 2> /dev/null | awk '{sum += $0}; END{print sum}')
if [[ "${folder_length%.*}" -eq 159 ]]; then
#len=$(echo "$len-159+$(exiftool -n -q -p '$Duration#' "${array[@]}" 2> /dev/null | awk '{sum += $0}; END{print sum}')" | bc)
continue
else
total_folder_length=$(echo "$total_folder_length+$(exiftool -n -q -p '$Duration#' "${array[@]}" 2> /dev/null | awk '{sum += $0}; END{print sum}')" | bc)
fi
counter=$(echo $(echo ${#array[@]})+$counter | bc)
fi
done
# Change it from 78682.8 to 0:21:51:22 https://unix.stackexchange.com/a/34033
total=$(echo $total_folder_length | awk '{printf("%d:%02d:%02d:%02d\n",($1/60/60/24),($1/60/60%24),($1/60%60),($1%60))}')
days=$(echo ${total} | awk -F ":" '{print $1}')
hours=$(echo ${total} | awk -F ":" '{print $2}')
minutes=$(echo ${total} | awk -F ":" '{print $3}')
seconds=$(echo ${total} | awk -F ":" '{print $4}')
if [[ "${days#0}" -gt 0 ]]; then
#printf "The total duration found is:\n"
printf "%d day(s) %02d hour(s) %02d minute(s) and %02d second(s) in %d videos\n" "${days#0}" "${hours#0}" "${minutes#0}" "${seconds#0}" "$counter"
else
if [[ "${hours#0}" -gt 0 ]]; then
#printf "The total duration found is:\n"
printf "%02d hour(s) %02d minute(s) and %02d second(s) in %d videos\n" "${hours#0}" "${minutes#0}" "${seconds#0}" "$counter"
else
#printf "The total duration found is:\n"
printf "%02d minute(s) and %02d second(s) in %d videos\n" "${minutes#0}" "${seconds#0}" "$counter"
fi
fi
cd "$back"
}
That is quite confusing a script. And, what does "get a bit borked" mean? Incorrect? Slow? Crashes?
A few comments:
- you don't need an echo "command substitution" for a variable assignment in general.
- the repeated varn=$(echo ... | awk ... ) could be replaced by a read var1 ... varn <<< ... in what seems to be your bash version (which you, alas, don't mention)
- don't run exiftool with an empty array if the result is crooked, test the array upfront.
- your presumed bash version offers extended pattern matching of pattern-lists when the extglob option is set, mayhap eliminating the need for the find command.
- your presumed bash version offers the %()T format specifier:
Much cleaner but as you said it is very slow when I run it on folders with more than 100 video files.
Thanks
---------- Post updated at 05:07 ---------- Previous update was at 04:47 ----------
Quote:
Originally Posted by RudiC
That is quite confusing a script. And, what does "get a bit borked" mean? Incorrect? Slow? Crashes?
A few comments:
- you don't need an echo "command substitution" for a variable assignment in general.
- the repeated varn=$(echo ... | awk ... ) could be replaced by a read var1 ... varn <<< ... in what seems to be your bash version (which you, alas, don't mention)
- don't run exiftool with an empty array if the result is crooked, test the array upfront.
- your presumed bash version offers extended pattern matching of pattern-lists when the extglob option is set, mayhap eliminating the need for the find command.
- your presumed bash version offers the %()T format specifier:
Code:
printf "%(%T)T\n" 78682
22:51:22
Yup confusing is an euphemism, welcome to my brain, I have to deal with it on a daily basis.
Thanks for the pointers, I still need to learn more about the "best way" to do things.
That is a variation of bash's "here documents": "here strings". This contruct evaluates the expression after the <<< and presents the result on stdin of the (here: read) command.
I don't know about exiftool nor do I have access to it, so simulated it with a cat of several files with integer numbers, trying to condense most of your script into the following three lines:
Here you have
- a here string to read the time elements from the result of printf
- a printf converting seconds to Day, Hour, Minute, and Second (using the "epoch" seconds; day and hour will start at 1 so have to be decremented for later use)
- an "extended pattern matching" for the video files in the working directory (use exiftool in lieu of cat for your purposes)
- shell "Arithmetic Expansion" $(( ... ))
The use of the extended pattern matching may be limited by sheer file count resp. file names' lengths, should they exceed the ARG_MAX or LINE_MAX system parameters...
Hi , How can I check that for a single process, for example pagent for how much duration this process was up or down and also I need multiple entries if this process was down or up multiple times. Please help. (3 Replies)
I have used the arecord command like this
arecord -d 1 test.wav
It is keep on waiting. I need to manually interrupt it by ctrl-c. Why it is not interrupting after one second?
The arecord version which I am using is :
arecord: version 1.0.23 by Jaroslav Kysela (3 Replies)
Hi,
I am looking to write a script to kill the process which are running for more than 7 days.
So i have a command like
"ps -eo pid,etime,args | grep -i xxxx" ( process which has xxx in it and running for more than 7 days needs to be killed ).
When i exeucte the above command , i am... (2 Replies)
Hello forum, i would like to ask if there's a way to view the remaining time of copying files (talking about copying gigabytes) while the cp commnad is running.
I'm using OpenBSD 4.9 -stable.
Thanx in advance. :) (2 Replies)
Hi everybody,
Please some help over here, I`m pretty new in PHP.
I have a cronrefresh php file within a website, I need this script get infornation from a URL of the site.
Part of the script where $URL variable appears is:
$fdURL = mysql_query("SELECT * FROM affiliSt_config WHERE name... (2 Replies)
hi, i'm trying to figure out how to tell the amount of time a ufsdump of a directory takes. i use the below command:
echo "Starting Backup of u4" >> /backup/backup.log 2>&1
/usr/sbin/ufsdump 0uf /dev/rmt/0n /u4 >> /backup/backup.log 2>&1
echo "Finished Backup of u4" >> /backup/backup.log... (0 Replies)
I have a file which has 3 coloumns emp_name, Joining_date, Designation.
abc 12/1/2001 SSE
def 2/25/2007 SE
ghi 3/18/2009 SA
abc 8/1/2008 SSE
def 2/13/2007 SE
ghi 3/24/2005 SA
I need to find out the emp who has been in the company for longest period(Till date).
Can I have any... (3 Replies)