Process NotebookLM audio files: convert, transcribe, add chapters, and prepare for publishing.
Skill name: podcast-audio-processing
Process podcast audio from NotebookLM: convert to mp3, transcribe with Whisper, create chapters, and embed metadata.
Use after receiving audio from NotebookLM (Phase 9 in workflow):
Use the Task tool with subagent_type="general-purpose" and prompt:
"Process the podcast audio file for this episode using the podcast-audio-processing skill.
Episode path: podcast/episodes/YYYY-MM-DD-topic-slug
Audio filename: [filename user provided, e.g., 'Original_Audio.m4a']
Episode slug: YYYY-MM-DD-topic-slug
Follow the podcast-audio-processing skill to:
1. Convert to mp3 if needed (m4a → mp3)
2. Get file metadata (size in bytes, duration)
3. Transcribe with local Whisper (base model)
4. Analyze transcript and create 10-15 chapter markers
5. Embed chapters into mp3
CRITICAL: Report back the file metadata when complete:
- Duration: MM:SS format
- File size: bytes"
Check if the audio file is .m4a or .wav format. If so, convert to mp3:
cd ~/src/research/podcast/episodes/EPISODE_PATH
# Convert to mp3 (128kbps for optimal size/quality)
ffmpeg -i "AUDIO_FILENAME.m4a" -codec:a libmp3lame -b:a 128k "EPISODE_SLUG.mp3" -y
Note the metadata from ffmpeg output:
Get the file size in bytes:
ls -l EPISODE_SLUG.mp3 | awk '{print $5}'
Record:
Run Whisper transcription locally (no API key needed):
cd ~/src/research/podcast/tools
# Basic transcription (uv run auto-manages dependencies)
uv run python transcribe_only.py ../episodes/EPISODE_PATH/EPISODE_SLUG.mp3 --model base
# OR with organized logging (recommended for production)
mkdir -p ../episodes/EPISODE_PATH/logs
uv run python transcribe_only.py ../episodes/EPISODE_PATH/EPISODE_SLUG.mp3 \
--model base \
--log-dir ../episodes/EPISODE_PATH/logs \
--quiet
Whisper model options:
tiny: Fastest (~1-2 min for 30 min audio), basic accuracybase: [recommended] Fast (~5-10 min), good accuracysmall: Slower (~15-20 min), better accuracymedium: Slowest (~30-40 min), best accuracyDefault to base model unless user specifies otherwise.
Output:
EPISODE_SLUG_transcript.json in the episode directory--log-dir: Also creates timestamped log file in logs/ directory--quiet: Suppresses progress messages (useful in automated workflows)Read the transcript file and analyze it to identify natural topic transitions.
Chapter creation guidelines:
Create two chapter files:
EPISODE_SLUG_chapters.txt):;FFMETADATA1
[CHAPTER]
TIMEBASE=1/1000
START=0
END=120000
title=Introduction: The Topic Overview
[CHAPTER]
TIMEBASE=1/1000
START=120000
END=300000
title=Historical Context: Early Development
EPISODE_SLUG_chapters.json):{
"version": "1.2.0",
"chapters": [
{
"startTime": 0,
"title": "Introduction: The Topic Overview"
},
{
"startTime": 120,
"title": "Historical Context: Early Development"
}
]
}
Important format notes:
Embed the chapter metadata into the mp3 file:
cd ~/src/research/podcast/episodes/EPISODE_PATH
# Embed chapters using FFmpeg metadata file
ffmpeg -i EPISODE_SLUG.mp3 -i EPISODE_SLUG_chapters.txt -map_metadata 1 -codec copy temp.mp3 -y
# Replace original with chaptered version
mv temp.mp3 EPISODE_SLUG.mp3
Result:
# Fix SSL certificates (macOS Python - one-time)
/Applications/Python\ 3.12/Install\ Certificates.command
# Dependencies auto-managed by uv - no manual install needed
# Just use: uv run python transcribe_only.py ...
After completion, these files should exist in the episode directory:
| File | Size | Description |
|---|---|---|
EPISODE_SLUG.mp3 |
~30MB | Final audio with embedded chapters |
EPISODE_SLUG_transcript.json |
~400KB | Full transcript with timestamps |
EPISODE_SLUG_chapters.txt |
~2KB | FFmpeg chapter format |
EPISODE_SLUG_chapters.json |
~1KB | Podcasting 2.0 format |
If conversion fails:
ffmpeg -versionIf transcription fails:
uv run python (not bare python) - this ensures correct venvIf chapter embedding fails:
When complete, report back to main agent:
EPISODE_SLUG.mp3