This is part two. In the first post I turned 19 free English board books into a tab in my daughter’s media player. The tab worked. Then I used it with her for one evening and found three things that bothered me.
The Need: Three Small Annoyances
- Every video started with a roughly 10-second channel intro and ended with a promo card for other videos. In a song tab, that is a jolt every time.
- My wife and I had agreed she shouldn’t watch video yet, but the tab played video by default.
- The lyrics and translation were below the picture. To read them I had to scroll. And my daughter doesn’t like it when “her” picture shrinks or disappears off the top of her phone.
None of these is a big problem. All three would have stopped us using the tab.
The Proof: What It Does Now
- Each of the 19 songs starts at the first note and ends when the song ends, with a short fade.
- Video mode is behind the same password as the YouTube tab. Audio mode is the default and has no lock.
- Open lyrics, and the whole screen fits on the phone: picture on top, controls squeezed into a small strip, and the current lyrics with Korean below, filling the remaining space. No scrolling.
- The line being sung is highlighted at the moment it is sung. It behaves like karaoke subtitles. I find that part genuinely fun to watch.
The Story: Why I Let the AI Do the Cutting
My first plan was to watch all 19 videos and write down the second where each song starts and ends, then give the AI the numbers. That’s nineteen videos, two numbers each, and I’m bad at being precise to the second.
So I asked a different question. This is the prompt, translated:
💬 Prompt that worked “The intro and the ending outside the main content sound awkward in the audio and video. Should I cut the video myself, or can you cut it? After you cut the video, please cut the audio too.”
It said it could do it. I was doubtful, because “find where the song starts” sounds like it needs ears. I let it try and checked the results afterward.
It did a clean job. It found the boundaries by looking for scene cuts in the video and silent stretches in the audio, then checked each song one by one. The intro was about 12 seconds in most videos, and the ending was a 10-second promo card followed by a silent tail. Where one video was built differently (a version from another publisher), it handled that one by hand and I noted it in the project file. I am not sure that version has the same song as the one printed in the book, and I wrote that down too.
I kept the original files, so I can cut again if I ever find a bad boundary.
The How
1. Trimming the videos
The recipe, in plain words, for each video:
- Detect scene changes near the start to find where the title card ends.
- Detect silence near the end to find where the song stops and the promo card begins.
- Cut from the start boundary to the end boundary, and add a half-second fade-out.
- Re-encode as 720p H.264 (the originals were 1080p AV1, which many phones decode badly).
- Extract the MP3 from the already-trimmed video, so audio and video match exactly.
Step 5 matters. If you trim the audio and video separately, they can drift by a fraction of a second. Extracting audio from the trimmed file avoids that.
Total for 19 songs: about 310 MB. The tools are ffmpeg and ffprobe, which are free.
2. The password gate on video
The app already had a password screen for its YouTube tab. I didn’t build a second one. I asked:
“Please set a password on the video viewing in the Mother Goose tab. Use the same one as the video tab.”
(The real prompt named the four-digit code. I left it out here.)
The tab now reuses the existing gate. If you close the viewer, it locks again. Audio mode needs nothing. The default is audio, so she hears songs and sees the cover, not a screen full of moving pictures.
3. Lyrics with timing
The lyrics come from the audio itself, not from the book. The tab uses a speech-to-text service (ElevenLabs Scribe) that returns every word with a start and end time. The server groups words into lines. A line ends when it hits end punctuation, a pause longer than 0.7 seconds, or about 48 characters, whichever comes first. The result is cached in a .lyrics folder next to the audio, so each song is only transcribed once.
Then a second step sends the lines to Gemini to produce a Korean translation and short word explanations. The English tab already had this pipeline, so for this tab the lyrics code was reused as is.
Lyrics are generated on demand, when I press a button, not up front. That way I pay only for songs we actually open.
4. Two bugs from the first day of real use
Bug 1: pressing “Lyrics + translation” generated twice. The button first made the English lyrics, then asked again for the translation. My message the next morning:
“In the Mother Goose tab, when I press lyrics+translation and it hasn’t been generated yet, it says it will translate, and then when I press the button it says it will translate again, so it runs twice.”
Fix: one press now does both steps.
Bug 2: the subtitle was a little late in one song.
“The sound and subtitles of The Wheels on the Bus are slightly off. It’s mostly right, but in some places the subtitle is a little late and I can’t see it.”
The fix had two parts. The highlight used to refresh only when the browser’s timeupdate event fired, which can be a quarter second apart. It now refreshes with requestAnimationFrame. And the highlight now moves 0.45 seconds earlier than the transcript time, because a line is easier to follow if it appears just before it is sung, not just after.
🗂 Claude.md Rule Subtitle highlight: drive it from
requestAnimationFrame, nottimeupdate, and show each line about 0.45 s early. In my tests, a slightly early line was easier to follow than a late one.
5. Making lyrics fit without scrolling
This was the request that mattered most to my daughter:
“To see the lyrics+translation in the Mother Goose tab I have to scroll down, but my daughter dislikes it when the picture at the top shrinks or disappears, so it’s hard to read the lyrics when she’s with me. Please improve it by shrinking things like the mini player height so that the current lyrics+translation can be seen on the phone screen without scrolling. In other words, I’d like not to have to scroll down to see the lyrics of the part being sung.”
The change, in CSS terms: when lyrics are open, the viewer gets a class (mg-lyr). That class shrinks the controls card (smaller padding, buttons scaled to about 78%), caps the picture at 28% of the screen height, and makes the lyrics panel a flex child that takes whatever height is left (flex: 1 1 0). The picture stays. Only the controls shrink.
The English tab has the same kind of lyrics, so I asked for the same change there. On the first try, the English tab didn’t change. My message that night:
“I asked for the Mother Goose tab and the English tab to be changed together, but the English tab wasn’t changed.”
The reason, from my project notes: the Mother Goose viewer is laid out with flexbox, so CSS alone was enough. The English tab scrolls inside a different container, so the lyrics panel height had to be calculated in JavaScript and recalculated on window resize. Same visible goal, different mechanism.
🗂 Claude.md Rule When asked to change two tabs together, verify both. Layout code that looks shared (same panel, same class) may have a different scroll container.
What It Cost
- Trimming and encoding: $0 (ffmpeg on my own PC)
- Lyrics and translation: pay-per-use. I did not check my invoices. A rough estimate: about 19 songs of 1 to 3 minutes each through the speech-to-text service, plus short translation calls, is likely well under $1 in total. I’ll check the actual bill at the end of the month and update this post.
- AI coding: existing subscription, nothing extra
- Hosting: $0