Podcast player: calmer line-following scroll, and a voice you can pick

"The scrolling works kinda weirdly" + "maybe a less robotic voice, preferably
male".

Scroll: the transcript now follows by LINE, not by word - words on the same
line never move the page (that was the jitter), a line only scrolls once it
leaves a comfortable band, small corrections are instant rather than animated,
and a wheel/touch/drag on the transcript pauses the following for four seconds
instead of fighting the reader. Chapter jumps and word taps re-centre at once.

Voice: lib/podcast-voices ranks what the platform installed (natural / neural
/ online names up, espeak / SAM / compact down, a male name preferred) and the
player picks the best one automatically; a new picker in the chrome lists
everything in the episode's language, applies it live and remembers the choice
per language. A note points at the system settings when only robotic voices
exist. The engine takes the chosen voice instead of guessing.

podcast-test: 34 checks now (voice ranking, filtered picker, persisted pick,
same-line silence, line following, manual-scroll suspension). Version 0.7.4,
SW v96.
This commit is contained in:
Martin Dvořák 2026-10-16 13:05:57 +00:00
commit 4ec986da12
8 changed files with 684 additions and 46 deletions

View file

@ -302,6 +302,11 @@ const en: Record<string, string> = {
"podcast.pause": "Pause the episode",
"podcast.restart": "Start from the beginning",
"podcast.speedAria": "Playback speed",
"podcast.voiceAria": "Voice",
"podcast.voiceAuto": "Automatic (best available)",
"podcast.voiceLocal": "installed",
"podcast.voiceNote": "Voices come from your browser and system — pick the one that sounds best to you.",
"podcast.voiceRobotic": "Only the basic system voices are installed. For a natural host voice, add one in your system settings (Windows: Speech; macOS: Spoken Content; Chrome ships the Google voices).",
"podcast.tapToJump": "Tap any word to jump there.",
"podcast.noVoice": "This browser has no speech voice installed, so the transcript cannot be read aloud here. You can still read along.",
"podcast.loadingEpisode": "Loading the episode",
@ -1369,6 +1374,11 @@ const cs: Record<string, string> = {
"podcast.pause": "Pozastavit epizodu",
"podcast.restart": "Začít od začátku",
"podcast.speedAria": "Rychlost přehrávání",
"podcast.voiceAria": "Hlas",
"podcast.voiceAuto": "Automaticky (nejlepší dostupný)",
"podcast.voiceLocal": "nainstalovaný",
"podcast.voiceNote": "Hlasy dodává prohlížeč a systém — vyber si ten, co zní nejlíp.",
"podcast.voiceRobotic": "Jsou nainstalované jen základní systémové hlasy. Pro přirozený hlas moderátora si nějaký přidej v nastavení systému (Windows: Řeč; macOS: Mluvený obsah; Chrome má hlasy Google).",
"podcast.tapToJump": "Klikni na kterékoli slovo a přeskočíš tam.",
"podcast.noVoice": "Tento prohlížeč nemá nainstalovaný hlas, takže se přepis nedá přečíst nahlas. Číst ho ale můžeš dál.",
"podcast.loadingEpisode": "Načítání epizody",