Be a Better Podcaster Blog: Automating Your Podcast Workflow

A few days ago I set out on a quest to automate my podcasting workflow. Part of the reason why shows don’t get posted in a timely manner is the mundane process that has to take place for each one after I press the Stop button. Previous to the automation that I successfully completed (well, mostly completed, more on that in a little bit), my workflow was this:

  1. Record the show.
  2. Drag the WAV file from the recorder to my desktop.
  3. Edit the file in Adobe Audition (make any content edits, and add a Hard Limiter filter).
  4. Export as MP3.
  5. Launch ID3 Editor and set the ID3 tags.
  6. Launch Cyberduck, connect to the FTP server (GeekCast for the tech shows, Libsyn for the others) and upload the file.
  7. Go to Safari, log into QAQN, and create a new post. Type out the show notes. Set the category, title, Pretty Link, podcast episode and excerpt.
  8. Clean up. Remove the WAV from the desktop, archive the MP3 file to a local folder as well as my Drobo unit. Close down the running programs that I won’t need ’til next time.

That’s quite a list – and while the show notes take the most time, the rest of it really adds up. It can take 30 minutes or more to do the rest, upwards of 45 minutes or an hour to complete the entire process.

I have somewhat of a programming background. I used to write and edit Unix shell scripts when I was working at NASA (nothing noteworthy, but I enjoyed it), and I learned C++ when I went to school for video game design years ago. Every now and then, I get myself into a situation where I’ve got some tasks that get repetitive, and my first instinct is to automate them programatically. So, check that list again… what things do I absolutely have to do manually?

If you said numbers 1-3 and part of number 7 (the show notes), that’s what I came up with, too. Clearly, the show itself has to be manual, getting the file off the recorder has to be, and editing needs to be. Everything else?

Podcast Automation to the Rescue – How I Did It

Being on a Mac, I have access to Unix shell scripting, which is great. I know it fairly well, but it’s been 10 years since I used it on a regular basis. I also have access to Automator, which I know a bit, and AppleScript, which I don’t know at all. I know some PHP, so that could potentially be part of this, too.

I made a list of my workflow tasks (seen above) and identified specific items that would be addressed individually. Then I set about deciding how to attack each one. After some trial and error (there was a lot of that over the past five days), I decided to do everything in a Bash script. Later, I ended up incorporating PHP, which I’ll explain shortly. I used TextWrangler to write the script because executing the script is built into that program, which is nice.

Let’s start with the setup.

Setting You Up the Bomb, I mean, script

I created a new, empty text file on my desktop called Podcast Processing (~Desktop/Podcast Processing.txt). I opened the file in TextWrangler and added:

[bash]#!/bin/bash

############################
# Podcast Automation by Daniel M. Clark, http://qaqn.com.
# Free to use by anyone for anything.
# I make liberal use of comments.
# I’m not a professional programmer.
# If you *are* a professsional progammer, you will probably
# see things that I’m doing inefficiently. Please be nice.
# I’m open to suggestions, but not flames. Thanks!
[/bash]

Granted, I only added all that because I’m sharing it with you here ;) But the very first line, the Shebang, is required to declare this a Bash script.

Next, declaring and setting some variables that I used later on. It starts with CocoaDialog, a tool that allows me to pop GUI elements from the shell. If you’re following along, you’ll need to install that tool and configure it according to the instructions on their site.

[bash]############################
# Set up CocoaDialog
#
CD_APP="/Applications/CocoaDialog.app"
CD="$CD_APP/Contents/MacOS/CocoaDialog"
############################

############################
# Get and set the episode variables
#
OLD_IFS="$IFS"
IFS=$’\n’
showcode=($($CD standard-inputbox –title "What is the show’s abbreviation?" –text "Abbreviation" –float –no-newline))
showcode=${showcode[@]:1:1000}
episodenum=($($CD standard-inputbox –title "What is the episode number?" –text "#" –float –no-newline))
episodenum=${episodenum[@]:1:1000}
showtitle=($($CD standard-inputbox –title "What is the episode title?" –text "Title" –float –no-newline))
showtitle=${showtitle[@]:1:1000}
IFS="$OLD_IFS"
[/bash]

These three dialog boxes ask me for the abbreviation (gdw for Geek Dads Weekly, iim for Inside Internet Marketing, etc), then the episode number, and then the episode’s title. All of my shows, you may have noticed, follow the format Show Name #X – Episode Title. If you don’t title your shows exactly like that you will need to modify this script accordingly in later steps!

Next:

[bash]# Set the production code, declare the file name
procode=$showcode$episodenum
file=$procode.mp3

# use the showcode to get the show’s name
if [ "$showcode" == "gdw" ]; then
showname="Geek Dads Weekly"
elif [ "$showcode" == "iim" ]; then
showname="Inside Internet Marketing"
elif [ "$showcode" == "babp" ]; then
showname="Be a Better Podcaster"
elif [ "$showcode" == "yawls" ]; then
showname="Yet Another Weight Loss Show"
elif [ "$showcode" == "rtt" ]; then
showname="Road to Thin"
fi

# Set the full title of the show, to be used as the title of the post
fulltitle="$showname #$episodenum – $showtitle"
[/bash]

The production code is used in the filename, which is handy later on. I use it to put the full name of the shows into variables as well, then the full title is generated. The $fulltitle variable will be passed to the PHP script later on when I automatically set up the WordPress post.

Next, variables for the ID3 Tags:

[bash]# for the ID3 tags
DATE=`date +%Y`
comment=`echo -e "Feedback, comments or questions? Call the listener feedback line!\n\n281-241-QAQN\n\nYou may also record your own audio clip (on your computer or using an app on your phone) and email it as an attachment to feedback@qaqn.com"`
artist="QAQN.com"
url="http://qaqn.com"
copyright=`echo -e "\xA9$DATE Daniel M. Clark. All Rights Reserved."`
composer="Daniel M. Clark"
[/bash]

I only need the year for the Year tag, so that’s what the date function is giving me. The comment is formatted like that (with the echo -e command) because I need a multi-line comment formatted correctly. Likewise with the copyright variable. You’ll notice something odd in there – the \xA9 is the code that generates the © copyright symbol. I paired that with the $DATE variable for the copyright line. Along with the text-based tags, the ID3 Editor will put artwork into the MP3 file. I declared the locations of my artwork next:

[bash]gdwimage="/Users/danielclark/Documents/My Business/Active Items/QAQN/Shows/Geek Dads Weekly/Logo/gdw-600.png"
iimimage="/Users/danielclark/Documents/My Business/Active Items/QAQN/Shows/Inside Internet Marketing/Graphics and Banners/iim-600.jpg"
babpimage="/Users/danielclark/Documents/My Business/Active Items/QAQN/Shows/Be a Better Podcaster/Graphics : Logo/babp-600.png"
yawlsimage="/Users/danielclark/Documents/My Business/Active Items/QAQN/Shows/Yet Another Weight Loss Show/yawls-600.png"
rttimage="/Users/danielclark/Documents/My Business/Active Items/Road to Thin/Road to Thin – 600.png"
[/bash]

Then, the variables for FTP, local and Drobo storage:

[bash]############################
# Locations for FTP, local and Drobo storage
#
gdwftp="s152854811.onlinehome.us"
gdwremotedir="/geekdadsweekly/"
iimftp="s152854811.onlinehome.us"
iimremotedir="/inside-internet-marketing/"
babpftp="s152854811.onlinehome.us"
babpremotedir="/better-podcaster/"
yawlsftp="ftp-server.libsyn.com"
yawlsremotedir="/qaqn/public/"
rttftp="ftp-server.libsyn.com"
rttremotedir="/qaqn/public/"

gdwl="/Users/danielclark/Documents/My Business/Active Items/QAQN/Shows/Geek Dads Weekly/The Show/Episodes"
gdwd="/Volumes/Drobo/Archives/QAQN/Geek Dads Weekly"
babpl="/Users/danielclark/Documents/My Business/Active Items/QAQN/Shows/Be a Better Podcaster/Episodes"
babpd="/Volumes/Drobo/Archives/QAQN/Be a Better Podcaster"
iiml="/Users/danielclark/Documents/My Business/Active Items/QAQN/Shows/Inside Internet Marketing/The Show/Episodes"
iimd="/Volumes/Drobo/Archives/QAQN/Inside Internet Marketing"
yawlsl="/Users/danielclark/Documents/My Business/Active Items/QAQN/Shows/Yet Another Weight Loss Show/The Show/Episodes"
yawlsd="/Volumes/Drobo/Archives/QAQN/Yet Another Weight Loss Show"
rttl="/Users/danielclark/Documents/My Business/Active Items/Road to Thin/Episodes"
rttd="/Volumes/Drobo/Archives/Road to Thin"

process="/Users/danielclark/Documents/My Business/Active Items/QAQN/Shows/Common/Auto Upload and Process/Process"
############################
[/bash]

Each show is being uploaded to a different directory (on one of two servers) and is being backed up to a local folder on my Mac and a folder on my Drobo for archiving. The last line defines a folder called Process that all the episode MP3s get saved to for processing. This is needed for the archiving process later on.

One more bit of code for today:

[bash]# LET’S DO THIS THING!
#
############################
# Verify the episode title. If the title is correct, all variables are correct.
runit=`$CD ok-msgbox –text "Is this right?" \
–informative-text "Continue only if everything is correct -> $fulltitle" –no-newline –float`
if [ "$runit" == "1" ]; then
echo "User said OK"
elif [ "$runit" == "2" ]; then
echo "Canceling"
exit
fi
############################
############################
# Upon file save from Audition/Audacity or whatever, start the rest of the process
#
runit=`$CD ok-msgbox –text "Shall we continue?" \
–informative-text "Continue only if the episode is completely saved out of the editing software." –no-newline –float`
if [ "$runit" == "1" ]; then
echo "User said OK"
elif [ "$runit" == "2" ]; then
echo "Canceling"
exit
fi
############################
[/bash]

Yes, this could have been done with one dialog box. I wanted two because I wanted to be reminded to really check the show title for errors rather than just absentmindedly hitting OK to keep going. If you’re implementing this yourself, feel free to remove the second dialog box.

The final code for the first part of the automation process:

[bash]#!/bin/bash

############################
# Podcast Automation by Daniel M. Clark, http://qaqn.com.
# Free to use by anyone for anything.
# I make liberal use of comments.
# I’m not a professional programmer.
# If you *are* a professsional progammer, you will probably
# see things that I’m doing inefficiently. Please be nice.
# I’m open to suggestions, but not flames. Thanks!

############################
# Set up CocoaDialog
#
CD_APP="/Applications/CocoaDialog.app"
CD="$CD_APP/Contents/MacOS/CocoaDialog"
############################

############################
# Get and set the episode variables
#
OLD_IFS="$IFS"
IFS=$’\n’
showcode=($($CD standard-inputbox –title "What is the show’s abbreviation?" –text "Abbreviation" –float –no-newline))
showcode=${showcode[@]:1:1000}
episodenum=($($CD standard-inputbox –title "What is the episode number?" –text "#" –float –no-newline))
episodenum=${episodenum[@]:1:1000}
showtitle=($($CD standard-inputbox –title "What is the episode title?" –text "Title" –float –no-newline))
showtitle=${showtitle[@]:1:1000}
IFS="$OLD_IFS"

# Set the production code, declare the file name
procode=$showcode$episodenum
file=$procode.mp3

# use the showcode to get the show’s name
if [ "$showcode" == "gdw" ]; then
showname="Geek Dads Weekly"
elif [ "$showcode" == "iim" ]; then
showname="Inside Internet Marketing"
elif [ "$showcode" == "babp" ]; then
showname="Be a Better Podcaster"
elif [ "$showcode" == "yawls" ]; then
showname="Yet Another Weight Loss Show"
elif [ "$showcode" == "rtt" ]; then
showname="Road to Thin"
fi

# Set the full title of the show, to be used as the title of the post
fulltitle="$showname #$episodenum – $showtitle"

# for the ID3 tags
DATE=`date +%Y`
comment=`echo -e "Feedback, comments or questions? Call the listener feedback line!\n\n281-241-QAQN\n\nYou may also record your own audio clip (on your computer or using an app on your phone) and email it as an attachment to feedback@qaqn.com"`
artist="QAQN.com"
url="http://qaqn.com"
copyright=`echo -e "\xA9$DATE Daniel M. Clark. All Rights Reserved."`
composer="Daniel M. Clark"

gdwimage="/Users/danielclark/Documents/My Business/Active Items/QAQN/Shows/Geek Dads Weekly/Logo/gdw-600.png"
iimimage="/Users/danielclark/Documents/My Business/Active Items/QAQN/Shows/Inside Internet Marketing/Graphics and Banners/iim-600.jpg"
babpimage="/Users/danielclark/Documents/My Business/Active Items/QAQN/Shows/Be a Better Podcaster/Graphics : Logo/babp-600.png"
yawlsimage="/Users/danielclark/Documents/My Business/Active Items/QAQN/Shows/Yet Another Weight Loss Show/yawls-600.png"
rttimage="/Users/danielclark/Documents/My Business/Active Items/Road to Thin/Road to Thin – 600.png"

############################
# Locations for FTP, local and Drobo storage
#
gdwftp="s152854811.onlinehome.us"
gdwremotedir="/geekdadsweekly/"
iimftp="s152854811.onlinehome.us"
iimremotedir="/inside-internet-marketing/"
babpftp="s152854811.onlinehome.us"
babpremotedir="/better-podcaster/"
yawlsftp="ftp-server.libsyn.com"
yawlsremotedir="/qaqn/public/"
rttftp="ftp-server.libsyn.com"
rttremotedir="/qaqn/public/"

gdwl="/Users/danielclark/Documents/My Business/Active Items/QAQN/Shows/Geek Dads Weekly/The Show/Episodes"
gdwd="/Volumes/Drobo/Archives/QAQN/Geek Dads Weekly"
babpl="/Users/danielclark/Documents/My Business/Active Items/QAQN/Shows/Be a Better Podcaster/Episodes"
babpd="/Volumes/Drobo/Archives/QAQN/Be a Better Podcaster"
iiml="/Users/danielclark/Documents/My Business/Active Items/QAQN/Shows/Inside Internet Marketing/The Show/Episodes"
iimd="/Volumes/Drobo/Archives/QAQN/Inside Internet Marketing"
yawlsl="/Users/danielclark/Documents/My Business/Active Items/QAQN/Shows/Yet Another Weight Loss Show/The Show/Episodes"
yawlsd="/Volumes/Drobo/Archives/QAQN/Yet Another Weight Loss Show"
rttl="/Users/danielclark/Documents/My Business/Active Items/Road to Thin/Episodes"
rttd="/Volumes/Drobo/Archives/Road to Thin"

process="/Users/danielclark/Documents/My Business/Active Items/QAQN/Shows/Common/Auto Upload and Process/Process"
############################

# LET’S DO THIS THING!
#
############################
# Verify the episode title. If the title is correct, all variables are correct.
runit=`$CD ok-msgbox –text "Is this right?" \
–informative-text "Continue only if everything is correct -> $fulltitle" –no-newline –float`
if [ "$runit" == "1" ]; then
echo "User said OK"
elif [ "$runit" == "2" ]; then
echo "Canceling"
exit
fi
############################
############################
# Upon file save from Audition/Audacity or whatever, start the rest of the process
#
runit=`$CD ok-msgbox –text "Shall we continue?" \
–informative-text "Continue only if the episode is completely saved out of the editing software." –no-newline –float`
if [ "$runit" == "1" ]; then
echo "User said OK"
elif [ "$runit" == "2" ]; then
echo "Canceling"
exit
fi
############################

[/bash]

Tomorrow: The Main Monkey Business

The setup is complete, tomorrow’s follow-up will show you what I did with it!

Update: here’s Part 2!

About Daniel M. Clark

Daniel M. Clark is a podcaster and proprietor of QAQN, a writer at danielmclark.com, and an all-around cool dude everywhere else.

God, I hate talking about myself in the third-person.

Justin Burdine September 4, 2013 at 10:58 pm

Hey Daniel, great read! I too ran into this same issue and took it one step further by creating a web service that does this and more. You can upload your media (audio/video) to your podcast auto update the feed as well as convert the media and even send it to youtube, vimeo and dailymotion all by dragging and dropping a file into dropbox. I'd love it if you wanted to swing by, sign up and try it out. check out http://firepype.com.

Comments on this entry are closed.

2 Comments…

Previous post:

Next post: