Reputation: 36003
I am using automator to create a Finder service to get the length of all selected videos and display on a dialog.
So, the service will work like this:
I have found this Bash script on the web that works perfectly.
times=()
for f in *.mov; do
_t=$(ffmpeg -i "$f" 2>&1 | grep "Duration" | grep -o " [0-9:.]*, " | head -n1 | tr ',' ' ' | awk -F: '{ print ($1 * 3600) + ($2 * 60) + $3 }')
times+=("$_t")
done
echo "${times[@]}" | sed 's/ /+/g' | bc
I am trying to adapt that for automator. So, my service so far is equal to this:
I have a first step that receives the movie files from Finder and passes to this Run Shell Script
times=()
for f in "$@"; do
_t=$(ffmpeg -i "$f" 2>&1 | grep "Duration" | grep -o " [0-9:.]*, " | head -n1 | tr ',' ' ' | awk -F: '{ print ($1 * 3600) + ($2 * 60) + $3 }')
times+=("$_t")
done
total="${times[@]}" | sed 's/ /+/g' | bc
I was forced to change the for
loop to this
for f in "$@"; do
I understand this is how automator enumerates all files received. Files are received as arguments.
I have changed the last line to
total="${times[@]}" | sed 's/ /+/g' | bc
To create a variable called total
that can hold the total number of seconds of all videos.
Now I need to pass this variable to the next step and display it on a dialog.
Two questions:
thanks
Upvotes: 4
Views: 2527
Reputation: 25032
Yes, changing the for
loop in your shell script from:
for f in *.mov; do
to
for f in "$@"; do
is correct. The $@
is all the parameters passed to the shell script, which in your scenario will be the pathname of each selected movie file(s).
Now I need to pass this variable to the next step and display it on a dialog
To achieve this you need to:
echo
the total
at the end of the shell script. So change the last line in your second example shell script to the following:
times=()
for f in "$@"; do
_t=$(ffmpeg -i "$f" 2>&1 | grep "Duration" | grep -o " [0-9:.]*, " | \
head -n1 | tr ',' ' ' | awk -F: '{ print ($1 * 3600) + ($2 * 60) + $3 }')
times+=("$_t")
done
echo "${times[@]}" | sed 's/ /+/g' | bc # <-- change last line to this
Next in Automator add a Run AppleScript
action after your current Run Shell Script
action. To find the Run AppleScript
action in Automator you can:
Select Library
at the top of the panel/column on the left:
In the search field type: Run AppleScript and drag the Run AppleScript
action into the canvas area below your current Run Shell Script
action.
Enter the following AppleScript into the newly added Run AppleScript
action:
on run {totalDuration}
set dialogText to (totalDuration as text) & " seconds"
tell application "Finder" to display dialog dialogText with title ¬
"Total Duration" buttons {"OK"} default button 1 with icon 1
end run
The completed canvas area of your Automator Service/Workflow should now appear something like this:
Note:
I don't have the ffmpeg
utility available on the mac I'm currently using, therefore the shell script shown in the screenshot above uses the built-in mdls
utility to obtain the duration of each move instead.
Here is that code:
total_duration=0
for f in "$@"; do
duration=$(mdls -name kMDItemDurationSeconds -raw -nullMarker 0 "$f")
total_duration=$(echo "$total_duration" + "$duration" | bc)
done
echo "$total_duration"
The other minor difference in that screenshot is the code shown in the Run AppleScript
action. This just does some rounding which is probably not necessary given your shell script that you want to use. Using the AppleScript shown in the aforementioned point number 3 should be OK.
Upvotes: 3