Skip to content
Docs

How We Produce an Episode

The PyPodcats team handbook: every stage from speaker invitation to publishing.

Below is the documentation on how our team produce each PyPodcats episode.

There are various stages involved to produce a PyPodcats episode:

  1. Speaker invitation
  2. Episode recording
  3. Editing
  4. Reviewing
  5. Transcribing
  6. Publishing

Detailed Documentation on How to publish an Episode of PyPodcats

Notes:

  • Links with the lock icon ๐Ÿ” are private and can only be accessed by PyPodcats team members.
  • If you are a PyPodcats team member and having trouble accessing the links, please reach out on Slack.

As a PyPodcats team member, you should have access to the following:

Credentials for the above are found on Notion.

Tools that are needed for the “Publishing” step:

Detailed Steps

1. Speaker Invitation

  • Write an email inviting them to the podcast
    • Send the email using meow at pypodcats dot live email address, hosted through Fastmail
  • Prepare a collaboration doc on Google Docs
  • Ask the speaker to fill in Speaker Information form
  • Schedule a prep call & tech check session: 30 minutes, schedule through Calendly
  • Schedule the episode recording: 1 hour, schedule through Calendly

2. Episode Recording

  • Create the StreamYard recording link
  • Share the StreamYard recording link with speaker
  • Include the StreamYard recording link on the Prep Notes for easy discovery

3. Editing

  • Download raw videos from StreamYard: the composite video, and individual local recordings
  • Create new folder on Google Drive under the PyPodcats > Episodes ๐Ÿ” folder
    • Example folder name: “Ep 6 - Niharika Vadluri”
    • Example folder path: PyPodcats > Episodes > Ep 6 - Niharika Vadluri
  • Upload the raw videos to this folder
  • Let Georgi know that the videos are ready for editing
  • Produce:
    • trailer video
    • social media trailer video: a smaller copy of the trailer, under 10 MB, for posting on social media (see the ffmpeg command under “Other useful ffmpeg commands” below)
    • full episode video
    • artwork (using provided photo and information from the speaker info form)
    • necessary promotional materials
  • Upload all assets to the Speaker folder on PyPodcats > Episodes > Speaker folder
  • Folder structure:
    • PyPodcats
      • Episodes
        • Ep 1 - Speaker Name
          • Ep 1 - trailer
          • Ep 1 - full
          • Ep 1 - raw
        • Ep 2 - Speaker Name
          • Ep 2 - trailer
          • Ep 2 - full
          • Ep 2 - raw

4. Reviewing

  • Let other team members know that the episode is ready for review
  • Share the trailer and full episode with the speaker for review
  • Make any further editing based on feedback from other team members and speaker
  • Reupload any updates to the same folder

5. Transcribing

  • Once episode is approved, proceed to transcribe and subtitle using Veed.io
  • Go to veed.io, providing the pypodcats.live email address
  • The login info will be sent to the email address, click on it to login
  • On veed.io, Create a new project, upload the video/ trailer
  • Choose the “Subtitle” on the left. Options:
    • Language: English
    • Detect speakers: yes
    • Click the “auto-subtitle” button
  • Review the generated subtitle, listen to the video, and make edits.
    • fix any typos, especially speaker names
    • Ensure proper capitalization, eg PyPodcats, Python, PSF, PyLadies, etc (see the canonical spelling list in the “Proofread the write-ups” step under Publishing)
    • If necessary, clarify spellings with the speaker.
  • Ensure the subtitle is readable on the video
    • The subtitle text should have black background
  • Once finished, Download the subtitle as .SRT file
  • Export the video. Options:
    • Click “Done” button on the top right
    • Burn Subtitles: yes
    • Click the “Export Video” button
  • Once exported, download the video as both MP3 and MP4.
    • MP4 is to be uploaded to YouTube
  • Repeat this for both the trailer and the full episode
  • Upload the subtitled videos, and the .SRT files to the Speaker Episode folder on Google Drive.
    • Ensure to include “captioned” in the filename so that we can distinguish between the video with subtitle and without

6. Publishing

Internal team workflow
  • Gather all the videos, transcript (at this point, everything should have been on one folder on Google Drive)
  • Create the webpage for the episode/trailer
    • Create a new branch under the psf/the-invisibles GitHub repository, e.g. add-ep-6-trailer
    • Scaffold the write-up pages with Hugo archetypes, which pre-fill the frontmatter with TODO markers:
      • hugo new episodes/ep{number}.md for the full episode
      • hugo new episodes/ep{number}-trailer.md for the trailer
      • hugo new speakers/{speaker-name}.md for the speaker bio page
    • Create the remaining files (you can copy/look at content from previous episodes):
      • f"assets/images/ep{episode_number}-{speaker_name}.jpg": The cover image for the episode (png works too)
      • f"assets/images/{speakername}.jpg": The speaker photo (download from the Speaker Info Form. png works too)
      • f"content/english/episodes/ep{number}-trailer.md": write up about the trailer episode (more details below)
      • f"content/english/episodes/ep{number}.md": write up about the full episode (more details below)
      • f"content/english/speakers/{speaker_name}.md" : speaker bio page: photos, links, etc
      • f"static/audio/hidden-figures-ep{number}-trailer.mp3:": mp3 of the trailer
      • f"static/audio/hidden-figures-ep{number}.mp3:": mp3 of the full episode
      • f"static/transcript/hidden-figures-of-python-ep{number}-trailer.srt:": transcript of the trailer
      • f"static/transcript/hidden-figures-of-python-ep{number}.srt:": transcript of the full episode
    • The transcript files are displayed on each episode page as a collapsible “Read Transcript” section (between the audio player and the video), with a timestamp next to each caption. This is generated automatically from the transcript field in the episode frontmatter, so double check that the path is correct.
    • Commit, push, and create a pull request
    • Example Pull request: https://github.com/psf/the-invisibles/pull/40
  • Proofread the write-ups before publishing
    • Run the article through a grammar and spelling checker. Use your browser’s spell checker or a grammar checking tool of your choice, or ask a teammate to read it over.
    • Check that community names use their canonical spelling and capitalization. Some examples:
      • Python, always with a capital P
      • PyCon, always with a capital P and capital C
      • PyPodcats, PyLadies, PSF, SciPy, NumPy
      • GitHub, YouTube, TikTok
    • Double check the spelling of the speaker’s name and the projects they mention, matching the Speaker Info Form
  • Preview the episode (check the Netlify Deploy Preview), share the preview with teammates and speaker
  • Validate the RSS feed format
    • Once Netlify preview has been built, go to {netlify preview url}/episodes/index.xml. This is the RSS Feed url.
    • Enter the RSS Feed url to https://www.castfeedvalidator.com/
    • Ensure everything is green
YouTube workflow

Since Season 2, we publish to our own PyPodcats YouTube channel, so there is no need to go through The PSF anymore. Credentials are on Notion.

  • Once videos, transcript, and writeups are done, upload the captioned trailer and full episode videos to the PyPodcats YouTube channel
    • At this point: the artwork and writeups should also be on the Speaker Google Drive folder
    • Use the write-ups as the basis for the YouTube title and description
  • Schedule each video for publishing, matching the dates in the webpage frontmatter
    • Usually we do it on 9 AM US Eastern timezone / 1 PM UTC
  • Once the YouTube videos are uploaded, update the webpage with the YouTube ID in the frontmatter
Scheduling
  • Set the desired schedule dates into the webpage frontmatter
  • Ensure YouTube video ID is updated
  • Commit and merge the pull request
  • There is a scheduled GitHub action that rebuilds the site every hour. The content will eventually be published automatically
  • Promote on social media
    • Draft the announcement on buffer. Credentials in Notion.
    • Attach the social media trailer video (the under 10 MB copy of the trailer). If it is not yet on the Speaker Episode folder on Google Drive, produce it with ffmpeg (see below) and upload it there.

Publishing to Spotify/Apple Podcast etc

This happens automatically, so there is nothing else to do. They are configured to pick up changes from our RSS Feed at https://pypodcats.live/episodes/index.xml.

As long as our rss feed is valid, any new episodes will appear. That is why we need to always validate the RSS feed before merging.

More technical details on the Episode Write up

Episode/Trailer writeup should be created under the content/english/episodes/ directory as a new markdown file, e.g f"content/english/episodes/ep{number}-trailer.md"

Update the episode frontmatter with the correct information.

The information on this frontmatter is used to generate the RSS Feed for our podcast at /episodes/index.xml, which is consumed by podcast apps like Spotify, Apple Podcast, Overcast.fm, etc.

Therefore, it is important to have these info as accurate and correct as possible.

Example frontmatter for a full episode. (You can always copy from any previous episode)

title: "Episode 5: with Mona Obedoza"
meta_title: "Episode 5 with Mona Obedoza"
description: "Learn about Mona Obedoza from the Philippines to hear about her journey in technology. She started learning to code at five years old, and now she is teaching other kids to code."
date: 2024-07-24T05:00:00-07:00
host: [ "Georgi", "Tereza"]
draft: false
tags: ["python", "public speaking", "coding for kids", "youth", "Philippines", "mental health"]
publish_date: 2024-07-24T05:00:00-07:00
podcast_file: "/audio/hidden-figures-ep5.mp3"
podcast_duration: 2372.257959
episode_image: "images/ep5-mona.png"
podcast_bytes: "55887490" # the length of the episode in bytes
images: ["images/ep5-mona.png", "images/mona_obedoza.png"]
explicit: false 
type: 'episode'
episode: '5'
season: 1
transcript: '/transcript/hidden-figures-of-python-ep5.srt'
episode_type: full
layout: episode
youtube_id: SDipvSE21Es

The fields should be self-explanatory (hopefully), but here are some fields that might need special attention:

  • episode_type: It should be either episode or trailer
  • youtube_id: This is the ID from the YouTube video that got uploaded to The PSF’s YouTube channel The HTML template will pick this field up automatically to render the YouTube video in each episode
  • podcast_bytes and podcast_duration: This is generated using the print_metadata.py script.
Printing the metadata using Python

The script requires Python 3.14 or newer and the ffprobe command line tool. It uses only the Python standard library, so there are no dependencies to install and no virtual environment is needed.

From the root of this repository, run the script:

python print_metadata.py {path to the audio/video file}

Copy the values printed to the podcast_byes and podcast_duration in the frontmatter.

Other useful ffmpeg commands
  1. Extracting audio from video

Use this to generate mp3 audio file from a video

ffmpeg -i filename.mp4 filename.mp3
  1. Produce the social media trailer video (under 10 MB)

Social media platforms limit upload sizes, so we post a smaller copy of the trailer. Scale it down to 960x540 and use a two-pass encode to hit a predictable file size. For a trailer around 2 minutes, a 450k video bitrate plus 96k audio lands at about 9 MB:

ffmpeg -i trailer.mp4 -vf "scale=960:540" -c:v libx264 -preset slow -b:v 450k -pass 1 -an -f mp4 /dev/null
ffmpeg -i trailer.mp4 -vf "scale=960:540" -c:v libx264 -preset slow -b:v 450k -pass 2 -c:a aac -b:a 96k -movflags +faststart hidden-figures-ep{number}-trailer-social.mp4

For a longer or shorter trailer, adjust the video bitrate: total size in bytes is roughly (video bitrate + audio bitrate) * duration in seconds / 8. Verify the result is under 10 MB, then upload it to the Speaker Episode folder on Google Drive.

  1. Scale the video/audio down

Sometimes you may need to scale down the video/trailer before sharing on social media. It can be scaled down using ffmpeg.

To scale half size:

ffmpeg -i input.mkv -vf "scale=trunc(iw/4)*2:trunc(ih/4)*2" new_file_half_the_size.mkv

To scale one-quarter size:

ffmpeg -i input.mkv -vf "scale=trunc(iw/8)*2:trunc(ih/8)*2" new_file_quarter_the_size.mkv

Read more on ffmpeg scaling doc.