Newbie shell script question

Discussion in 'Mac Programming' started by oedipax, Oct 14, 2010.

  1. macrumors newbie

    Joined:
    Oct 14, 2010
    #1
    Hey there. I'm an editor trying to cobble together a script for generating video thumbnails automatically. I've done a small amount of programming in my past, but not enough to really code something like this. I've been able to cobble together a solution between Automator and a shell script (plus ffmpeg) I found on the web, but there's one final problem.

    Currently the script is as follows:

    First, an Automator action: "Get Selected Finder Items."

    Then, a Run Shell Script action:

    Code:
    for f in "$@"
    do 
    /usr/local/bin/ffmpeg -i "$f" -an -ss 00:00:30 -t 00:00:01 -r 1 -y /Users/me/Desktop/Thumbs/test/video%d.jpg
    done
    It grabs a thumb from 30 seconds into the video and saves it out as a jpg. Beautiful. Simple. Automatic.

    The only problem, as you can probably guess, is that if I drop several files at once on the script, it gives them all the same name. It overwrites them progressively so that at the end, all you have is the last file.

    What I'd like to know is, how can I pass the filenames from the Finder (which I'm using to drag the files over to the script) to the script and maintain them at the end. So if I give it Video1.m4v, Video2.mov, Video3.avi, etc., it will spit out Video1.jpg, Video2.jpg, Video3.jpg.

    I'm so close to getting this thing working right and saving myself a ton of time, as I have to make hundreds of thumbnails sometimes. I tried many of the freeware apps and they all had things that bugged me and made them unusable for one reason or another.

    Any help would be extremely appreciated! Thanks!
     
  2. macrumors 68040

    lee1210

    Joined:
    Jan 10, 2005
    Location:
    Dallas, TX
    #2
    Code:
    for f in "$@"
    do
      thumb_name=`echo $f|sed 's/\..\{3\}$//'`.jpg
      echo $thumb_name
    done
    You can just subsitute $thumb_name into your ffmpeg command for the filename. I got the sed from:
    http://txt.binnyva.com/2007/07/remove-file-extension-using-sed/
    by searching google for "shell remove file extension"

    It looks like this assumes 3 character extensions. That can be tweaked, but if all of your videos are 3 character extensions it will work. .mpeg will bite you.
    Code:
    for f in "$@"
    do
      thumb_name=`echo $f|sed 's/\..\{2,4\}$//'`.jpg
      echo $thumb_name
    done
    
    This will deal with 2 to 4 character extensions.

    -Lee
     
  3. thread starter macrumors newbie

    Joined:
    Oct 14, 2010
    #3
    Thanks very much for the quick and helpful reply!

    Unfortunately I have to show here my own ignorance of what to do next... I'm guessing I need to merge the code somehow, but I'm unsure which part of the old one I need to throw away. Here's how I tried it just now:

    Code:
    for f in "$@"
    do
    thumb_name=`echo $f|sed 's/\..\{3\}$//'`.jpg
    echo $thumb_name
    /usr/local/bin/ffmpeg -i $thumb_name -an -ss 00:00:30 -t 00:00:01 -r 1 -y /Users/me/Desktop/Thumbs/test/$thumb_name.jpg
    done
    Which gives an error (but not a helpful one!) I've also tried putting quotes around $thumb_name in the argument.

    Sorry. I really do need this spelled out :p
     
  4. macrumors regular

    CarlJ

    Joined:
    Feb 23, 2004
    Location:
    San Diego, CA, USA
    #4
    Try this (as as a replacement/new version for the entire script):
    Code:
    #!/bin/bash
    
    DEST=/Users/me/Desktop/Thumbs/test
    
    for VIDEO in "$@"; do
        BASE=${VIDEO##*/}
        NAME=${BASE%.*}
        /usr/local/bin/ffmpeg -i $VIDEO -an -ss 00:00:30 -t 00:00:01 -r 1 -y $DEST/$NAME.jpg
    done
    
    exit 0
    
    It's a little simpler, letting the shell tweak the name directly, rather than farming the work out to external commands like sed. Points of interest:
    • Incoming filenames each get assigned to $VIDEO, in turn, and look something like "/foo/bar/Animal.m4v".
    • $BASE is set to a copy of this, with any initial sequence up to the final "/" removed (thus "Animal.m4v"), giving us the base filename without the initial path.
    • Then $NAME is set to a copy of $BASE, with the trailing ".whatever" removed (thus, "Animal").
    • We set $DEST up at the start of the script to the directory where you want the files to end up (tweak that as necessary), so $DEST/$NAME.jpg gets us an output filename of (in this example) "/Users/me/Desktop/Thumbs/test/Animal.jpg".
    • The "#!/bin/bash" at the start of the script makes sure that the script really does run as a Bash script (even if your shell is set to something else, like tcsh or zsh), and the "exit 0" at the end makes the script tell the program that called it that everything went okay.
     
  5. thread starter macrumors newbie

    Joined:
    Oct 14, 2010
    #5
    Many thanks again to both of you! Such a supportive forum you all have here, I hope I can give back at some point... just not in this subforum :)
     

Share This Page