简体   繁体   中英

How to pass a result from a Shell Script to the next step inside Automator

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:

  1. I select a bunch of videos
  2. I right click and run the service.

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:

  1. how do I do that?
  2. are the changes I did correct?

thanks

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:

  1. 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 
  2. 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.

  3. 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 

Example Automator Workflow:

The completed canvas area of your Automator Service/Workflow should now appear something like this:

在此处输入图片说明

Note:

  1. 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" 
  2. 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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM