How I semi-automated our podcast workflow
Photo by david laws on Unsplash
Dom Sinacola and I do our podcast, Pretty Little Grown Men, in a pretty DIY way. We record it ourselves and do some minor editing/mixing in Reaper, upload it for free on Archive.org, and create the RSS feed that sends it to Apple Podcasts and Stitcher by posting on this very WordPress site. There are a number of steps involved in getting this thing from our microphones into your ears, so recently I’ve come up with a workflow that automates some of the set-up.
After finishing up recording and mixing, I export an audio file from Reader as, for example, plgm_episode_83.wav. This file then needs to be tagged, converted to MP3, and sent up to the cloud.
I’ll show you how I’m doing this—first with the terminal commands, and then by building it into a script. I’m doing all of this on a Mac.
Running the commands
Tagging with Taffy
Technically, we can live without tagging, as Apple and other podcast platforms will pull that information from the RSS data, but I like to do it anyway in case the files end up on a hard drive somewhere and someone needs to know what they’re looking at. I do this manually in kid3, which is a great little tool, but filling out title, artist, genre, etc. one field at a time is a time suck. I found the command-line utility
taffy, which works on top of
taglib, as a simple way to automate this piece.
I set this up by installing Taglib, a prerequisite for Taffy, with Homebrew:
brew install taglib
And installing Taffy with Gem.
sudo gem install taffy
Taffy can now be run with the
taffy command, and can easily set fields like title, artist, track number, year, and genre. I’m going to use all of these, and point them toward the path of the file to target at the end of the command.
taffy \ -t "Pretty Little Liars: The Perfectionists, S01E05" \ -r "Pretty Little Grown Men" \ -n 83 -y 2019 -g podcast \ ~/Desktop/plgm_episode_83.wav
\ escape characters are just in here to make this a little more readable for you, you don’t need them.
Encoding with XLD
I use XLD for encoding audio files. Upon installation, it comes with a
CLI folder with the
xld binary. You can put this wherever it can be accessible on your path so you can run
I personally have a custom
cli-tools folder in my home directory for CLI tools and apps I download so I can remember where they are, vs. things that came with my Mac or I use with Homebrew.
One nice thing you can do with XLD is get your settings right in the GUI app for the kind of conversation you want to do, and save that as a profile. You can call this up with the CLI tool so it will do the right thing and you never have to worry about how you left your XLD configuration. I convert our
.wav files to a V5.5 MP3 file, which still sounds good to me but manages to get the file size down dramatically. Presumably a 96 or 128kpbs file would be fine, too, but I’m used to using variable bit rates. I’ve saved this conversation as the profile “podcast.”
We can use the
-f flag to set our format, which is
So, we give
xld the source file, the format for the destination file, and set the profile for the encoding.
xld plgm_episode_83.wav -f mp3 --profile podcast
You can list an output directory but doing it without one will just save the new file to your current, local directory (the same place as the
Uploading to Archive.org
Finally, we need to use the Internet Archive’s CLI tool to upload this. I used
pip to install it:
pip3 install internetarchive
You could also download the binary directly and make it executable.
I set my login credentials for archive.org with:
It will ask for an email and password and save that in a file for future use.
Now we can go straight to work: in my case, I’ll use the
upload command, tell Archive.org what existing directory to use, and the name/path of the file to send it—the new MP3.
ia upload PrettyLittleGrownMen plgm_episode_83.mp3
I use Archive.org vs. Libsyn or self-hosting on a web server because it’s free, we’re giving away the podcast anyway, and I don’t need to track any metrics from people downloading it from Archive.org (vs. through our RSS feed and Apple) because we don’t run ads. The more the merrier. This has been a great, reliable solution for us which is now comically easier now that I can upload my files without clicking six different buttons.
Building the script
Let’s put this into a script and simplify the whole thing.
I’ll start with a new text file,
podcast.sh, which needs to be executable:
touch podcast.sh && chmod +x podcast.sh
In my text editor, we’ll add the opening bash comment:
and do this all on my desktop, but any directory is fine:
And run our three commands there:
taffy \ -t "Pretty Little Liars: The Perfectionists, S01E05" \ -r "Pretty Little Grown Men" \ -n 83 -y 2019 -g podcast \ ~/Desktop/plgm_episode_83.wav xld plgm_episode_83.wav -f mp3 --profile podcast ia upload PrettyLittleGrownMen plgm_episode_83.mp3
So our script looks like:
#!/bin/bash cd ~/Desktop taffy \ -t "Pretty Little Liars: The Perfectionists, S01E05" \ -r "Pretty Little Grown Men" \ -n 83 -y 2019 -g podcast \ ~/Desktop/plgm_episode_83.wav xld plgm_episode_83.wav -f mp3 --profile podcast ia upload PrettyLittleGrownMen plgm_episode_83.mp3
This is a good script for a single file but not for use on a weekly basis as file names and episode numbers change. Let’s add some variables to fix that.
When you call a script, like
sh podcast.sh, you can follow this command with some variable arguments and they’ll pass into the script as
$2, and so on. We can use that here, treating
$1 as the number for our podcast episode number and
$2 for the actual show episode number.
#!/bin/bash # $1 = podcast episode number # $2 = show episode number cd ~/Desktop taffy \ -t "Pretty Little Liars: The Perfectionists, S01E$2" \ -r "Pretty Little Grown Men" \ -n $1 -y 2019 -g podcast \ ~/Desktop/plgm_episode_$1.wav xld plgm_episode_$1.wav -f mp3 --profile podcast ia upload PrettyLittleGrownMen plgm_episode_$1.mp3
And we can run this with:
sh podcast.sh 83 05
I name the
.wav file with an episode number when I export it from Reaper, so it’s important to make sure that number matches or it breaks everything. But the show episode number is just for tagging, so messing that up won’t stop us.
Now I can do a single command to tag, convert, and upload the file, instead of spending 10 or 15 minutes doing this on a bunch of screens. That’s awesome.
What I don’t like about this is having to remember to put in two numbers and in what order for the script command, so I made this even easier with
aText, a $5 text expander app I’ve used for years.
aText expansions can prompt you for content by adding fields, so what I’ve done is set the abbreviation
to an expansion with
sh podcast.sh and two fields after that I have to fill in. So I can open my terminal and type
make pod, and aText will ask me for a “podcast episode number (ex: 84)”, and then a “show episode number (04).” Now all I have to do is know what podcast and show episode I’m working with and my program takes care of where everything needs to go. Something I use
aText for constantly is setting long file paths to abbreviations so I don’t have to remember where anything is, so I may end up setting
make pod to
sh ~/scripts/podcast/podcast.sh or wherever this file ends up. I tend to go back and forth between what I put in
aText and what becomes a Bash alias.
You could also set up the variable reminders with an interactive script in Bash, but I already have
aText running anyway so it’s a little quicker.
When this is all done, I still have to open WordPress and type of the blog post, which is another few minutes. To speed this bit up, I’ve added the Duplicate Post plugin, so I start by copying last week’s podcast post and just editing the text and numbers I need to before hitting publish. I should’ve done this several years ago, but better late than never.
One thing this workflow doesn’t do yet is add cover art to the
.mp3 file (
taffy can’t do it), which is something I can live without for now as Apple will take care of it in the podcast app, but it would be a nice touch to automate. For now, I may do it in
kid3 before running the script.
As always, would love to hear any feedback and ways to do this better or differently.