Podcast first episode real test - run: 2026-10-25 11:08 UTC host: Linux 6.8.0-139-generic x86_64 ffmpeg: ffmpeg version 6.1.1-3ubuntu5 Copyright (c) 2000-2023 the FFmpeg developers === 1. the narration we recorded for the episode === $ ffprobe -v error -show_entries format=duration,size -show_entries stream=codec_name,sample_rate,channels -of default=noprint_wrappers=1 '/home/ubuntu/rt/pod/episode.wav' codec_name=pcm_s16le sample_rate=24000 channels=1 duration=22.869333 size=1097772 exit=0 === 2. encode the episode the way Apple recommends for RSS (MP3 stereo, 44.1 kHz, 128 kbps) === $ ffmpeg -v error -i '/home/ubuntu/rt/pod/episode.wav' -c:a libmp3lame -b:a 128k -ar 44100 -ac 2 episode.mp3 -y exit=0 $ ffprobe -v error -show_entries format=duration,size,bit_rate -show_entries stream=codec_name,sample_rate,channels,bit_rate -of default=noprint_wrappers=1 episode.mp3 codec_name=mp3 sample_rate=44100 channels=2 bit_rate=128000 duration=22.909388 size=367012 bit_rate=128161 exit=0 === 3. how loud is it? (our own measurement) === $ ffmpeg -v error -i episode.mp3 -af ebur128=peak=true -f null - exit=0 --- ebur128 summary --- === 3b. normalise the episode to -16 LUFS (our chosen target) and measure the difference === $ ffmpeg -v error -i episode.mp3 -af loudnorm=I=-16:TP=-1.5:LRA=11 -c:a libmp3lame -b:a 128k -ar 44100 -ac 2 episode-normalised.mp3 -y exit=0 $ ffmpeg -v error -i episode-normalised.mp3 -af ebur128=peak=true -f null - exit=0 --- ebur128 summary of the normalised file --- $ ffmpeg -v info -i episode-normalised.mp3 -af ebur128=peak=true -f null - 2>&1 | grep -A10 Summary [Parsed_ebur128_0 @ 0x591e25415e00] Summary: Integrated loudness: I: -16.0 LUFS Threshold: -27.3 LUFS Loudness range: LRA: 3.9 LU Threshold: -37.6 LUFS LRA low: -19.7 LUFS LRA high: -15.8 LUFS exit=0 === 4. the RSS feed we ship === enclosure length set to the real file size: 367012 bytes Plot Nine https://example.com/plotnine A fortnightly show from a city allotment: compost, slugs and what we are not doing this season. en-gb Plot Nine false Plot Nine hello@example.com Episode 1: The heap in January What actually happens to a compost heap in January, why the slugs win every year, and one thing we are not doing this season. Sun, 25 Oct 2026 09:00:00 +0000 plotnine-e001 00:00:23 1 === 5. check the feed against Apple's published requirements === $ python3 /home/ubuntu/rt/pod/check_feed.py feed.xml episode.mp3 PASS the feed is well formed XML PASS the root element is rss version 2.0 PASS the itunes namespace is declared PASS the feed has a channel PASS the channel has a PASS the channel has a <description> PASS the channel has a <link> PASS the channel has a <language> PASS the channel has <itunes:author> PASS the channel has <itunes:explicit> PASS the channel has artwork (<itunes:image>) PASS the channel has <itunes:category> PASS the feed has at least one episode - 1 item(s) PASS the episode has a <title> PASS the episode has a <description> PASS the episode has a <pubDate> PASS the episode has a <guid> PASS the episode has an <enclosure> PASS the enclosure has a url PASS the enclosure has a length PASS the enclosure has a type PASS the enclosure url is ASCII with only a-z, A-Z, 0-9 and / . - _ - https://example.com/plotnine/episode-001.mp3 PASS the pubDate follows RFC 2822 with a time zone offset - Sun, 25 Oct 2026 09:00:00 +0000 PASS every episode GUID is unique PASS every episode enclosure URL is unique PASS the feed avoids HTML entities such as ’ or “ PASS the episode file is MP3 - mp3 PASS the episode file is stereo - 2 PASS the episode sample rate is 44.1 kHz - 44100 PASS the episode bit rate is in Apple's recommended 128-256 kbps range for stereo MP3 - 128 kbps PASS the enclosure length matches the audio file size - feed says 367012, file is 367012 RESULT: 31 checks passed, 0 failed exit=0 === 6. what we ship === -rw-rw-r-- 1 ubuntu ubuntu 367012 Oct 25 11:08 episode.mp3 -rw-rw-r-- 1 ubuntu ubuntu 1269 Oct 25 11:08 feed.xml === done === === 7. transcribe the episode with the live tool and compare it word by word === $ node scenario-transcript2.cjs episode.mp3 script.txt page: https://koldflux.com/tools/podcast/transcript language select: English model select: Accurate (Whisper base, 80 MB download) run: 2026-10-25, headless Chromium via Playwright the run that produced the transcript took 14 s and reported no page errors. three earlier runs of the same scenario on the same day each took about 500 s and did not leave a readable transcript box, so we did not measure where that time went. --- the transcript the tool wrote, as it downloaded it (time codes included) --- [00:00:00] Welcome to Plot 9, a fortnightly show from a city allotment. [00:00:05] Today, what actually happens to a compost heap in January, why the slugs seem to win every [00:00:14] single year, and one thing we are definitely not doing this season. [00:00:22] Bring a mug. --- word by word against the script we recorded --- method: lower case, strip punctuation, drop the time codes, split on spaces, then a plain Levenshtein distance over the word lists reference words: 43 transcript words: 43 edit distance: 1 word error rate: 2.3% errors: 1 sub nine -> 9 The only mistake was the show name: the tool wrote "Plot 9" for "Plot Nine". Everything else came back word for word, including the clause "why the slugs seem to win every single year". The tool page reports 4.8% of words wrong over 48 minutes of read English. Our 2.3% comes from 43 words of synthetic speech, so the two numbers are not comparable: a longer recording has more chances to go wrong. === done, transcript comparison added ===