Transcribing my first podcast episode by hand took four hours. My fingers hurt. The draft was full of "[awkward laugh]" and sentences that went nowhere. I almost quit before I built a pipeline that does the hard work for me.
Now I go from WAV file to published Markdown without typing every "um" and "you know." Here's the exact workflow I use.
Step 1: Extract Clean Mono Audio
Transcription models are picky. Stereo files confuse them. Low sample rates make them hallucinate words. I learned this after Whisper turned a quiet guest channel into nonsense punctuation.
Before you send anything to the transcriber, strip silence and convert to 16 kHz mono. If you recorded a video, pull the audio track first.
ffmpeg -i raw_recording.mp3 -ar 16000 -ac 1 -af "silenceremove=start_periods=1:start_duration=0.5:start_threshold=-50dB" episode_clean.wav
That command forces 16 kHz, collapses to one channel, and strips dead air longer than half a second. It saves you from reading "[long pause]" every thirty seconds. I wish I'd known this sooner.
Step 2: Transcribe with Whisper and Export JSON
I run Whisper locally because I batch episodes and I don't trust cloud services with unreleased content. JSON output is the only format I use. Plain text dumps lose timestamps, and timestamps are your lifeline when you need to verify a technical term at 00:47:12.
whisper episode_clean.wav \
--model medium \
--language English \
--output_format json \
--output_dir ./transcripts/
No GPU? The tiny model still works fine for clean speech. You'll get segments, start times, and confidence scores in a file named episode_clean.json.
Step 3: Build a Searchable Draft Script
Raw JSON is unreadable. I wrote a five-minute script to flatten it into a draft I can actually scan.
import json
with open("transcripts/episode_clean.json") as f:
data = json.load(f)
with open("draft.md", "w") as out:
for seg in data["segments"]:
minutes = int(seg["start"]) // 60
seconds = int(seg["start"]) % 60
out.write(f"[{minutes:02d}:{seconds:02d}] {seg['text'].strip()}\n")
Run it once and you get timestamps next to every line. Suddenly you can spot the exact moment your co-host said the thing about database locks.
[00:03:42] The real issue wasn't the database. It was the N+1 query we introduced in the last deploy.
[00:04:15] We didn't catch it in staging because the dataset there is tiny...
Now you can scan, delete fluff, and annotate without touching the original audio.
Step 4: Outline Before You Write
A blog post is not a transcript. I used to paste chunks of dialogue and wonder why readers bounced. Turns out people skim. They want a problem, a fix, and proof. Before I write a single paragraph, I tag the draft with structural markers.
## Outline
- Hook: The production outage on Tuesday
- Context: Why standard ORM patterns failed us
- Technical breakdown: Query analysis and indexing
- The fix: Cursor pagination and batching
- Takeaways: Three rules for ORM performance
Once the skeleton is solid, the rewrite is fast. You're connecting dots instead of inventing structure at midnight.
Step 5: Rewrite Speech into Scannable Prose
Spoken language is loose. You'll find filler words, fragments, and hedges like "kind of" and "sort of." Your job is to tighten them without making the speaker sound like a press release.
Before:
So, yeah, basically what happened was we, uh, we pushed this change and then, like, the latency just totally exploded and we were like, okay, this is bad.
After:
We pushed the change. Latency exploded immediately. We knew we had a problem.
I used to over-edit and kill the voice. Don't do that. Keep the honesty. Drop the noise. Break long thoughts into short paragraphs. Use bold for the terms a reader is scanning for. If two speakers debated a point, turn it into a comparison list. It reads faster than dialogue formatting.
Step 6: Add Dev.to-Ready Frontmatter and Metadata
Before I paste into the CMS, I lock down metadata. Good frontmatter makes the post discoverable and keeps my formatting consistent across platforms.
---
title: "How an N+1 Query Took Down Our API"
published: false
tags: database, performance, backend, podcast
canonical_url: https://yourpodcast.com/episodes/42
---
Use your primary keyword in the first 100 words and in at least one H2. Keep the slug readable. If you reference a repo or tool, drop an inline link. Internal links to related episodes keep people around.
Dev.to renders your title as the H1, so start the body with H2. Nest H3 under it. Don't skip levels. Search engines notice, and screen readers break.
One trick I stole from smarter writers: embed a short audio player or a timestamped link back to the original episode. Some people want the full tone. Let them jump to the minute they need.
Step 7: Final Polish and Publish
I store drafts in Git, so I run everything through a formatter before publishing. Insane line lengths make diffs unreadable.
npx prettier --prose-wrap always --write post.md
Preview on Dev.to before you hit publish. Check that code blocks scroll and headings nest. Audio content is rich. Written content is searchable. Combine the two, and one recording keeps working while you sleep.
Top comments (0)