My three-year-old daughter has a favorite show. Baby Shark. She could watch it every day, and often does.
Last week, I showed her something new. Fifteen short videos of herself as a baby — the first year of her life, played one after another.
She sat still for one hour. Smiling, then laughing out loud, then quiet and focused. She didn’t ask for Baby Shark once.
My wife was watching from across the room. She didn’t say much. She didn’t need to.
The Problem: The Videos Existed. We Couldn’t Really Watch Them.
Like most families, we have a lot of phone footage. Hundreds of videos of our daughter — her first sounds, first steps, bath time, silly moments. They’re all backed up to our Synology NAS, sitting in a folder organized by year and month.
But “backed up” isn’t the same as “watched.” To pull up a specific video, you had to dig through a file manager on a phone or PC, find the right folder, find the right file — and the filenames were all machine-generated. 20250314_083217_001.mp4. You couldn’t tell what was what without opening each one.
So most of those videos just sat there.
I wanted to fix that. I’d already built a Kids Player that runs on our NAS. It made sense to add a personal tab — a place where I could curate family videos and photos, organized by year, playable straight from the app.
What I Built: My Tab
The new tab only shows up on devices where someone has entered the family group code in settings. On other devices, it doesn’t exist.
Inside are five categories: growth records, nursery songs, classical, Korean pop, hymns. Each category is a folder accordion — tap a folder, see the files, tap a file to play or view.
For the growth records, I needed to choose which videos to include. Not everything from three years of phone backup belongs in a curated playlist. So I also built a separate browser tool — pick_yeju.py — that runs locally on my PC.
It opens a browser gallery showing our NAS backup folder. I can filter by year, month, and type (photo or video). Each card shows a thumbnail. I tick the ones I want, click copy, and they go into the right year folder on the NAS where the app will find them.
I picked fifteen videos from 2025 — her first year — and that’s what she watched for an hour.
Getting There: Three Problems in a Row
It took me several rounds of fixing to get from “files in a folder” to “plays smoothly on a tablet.”
Problem 1: Filenames Tell You Nothing
The first version of My Tab just listed filenames. 20250314_083217_001.mp4. There’s no way to know what’s in a file without opening it.
The fix was thumbnails. I added an endpoint that uses ffmpeg to grab the frame at 0.5 seconds of any video and scale it to 360 pixels wide. Photos go through the same path with Pillow, which also corrects for EXIF rotation (phones store orientation in metadata, not in pixels). Thumbnails are cached to disk using the file’s modification time as a cache key — so the second request is instant, and if I replace a file, the old thumbnail auto-expires.
This turned a list of cryptic names into a grid I could actually browse.
Problem 2: The Videos Wouldn’t Play
I copied fifteen videos from our Galaxy S24 backup. Clicked the first one. Sound played. No picture.
The reason: Samsung records in HEVC (H.265) at around 14 Mbps. Chrome on tablets doesn’t decode H.265. The file was fine; the browser just couldn’t handle it.
My first fix was real-time transcoding. When a video is requested, the server pipes it through ffmpeg on the fly — converting to H.264, 720p, fast preset — and streams the result to the browser. It works. Start-up takes two or three seconds, and you can’t seek to the middle, but it plays.
One thing that surprised me: during development, ffmpeg kept throwing Illegal byte sequence errors when I passed it the file path directly. The folder name in Korean was the culprit — on Windows, the subprocess was getting a cp949-encoded string it couldn’t handle. The fix was to give ffmpeg a localhost URL instead of a file path, which kept everything in ASCII.
Problem 3: Pre-Transcoding (the Real Fix for Buffering)
Real-time conversion is fine for one video. For an auto-playing playlist of fifteen, it was still choppy — the Cloudflare Tunnel adds a round-trip to every request, and 14 Mbps is a lot to push through that.
I wrote a second script — transcode_yeju.py — that converts the files ahead of time rather than on the fly. The settings: H.264, longest side 1280 pixels (preserving aspect ratio), CRF 23, AAC audio at 128k, with -movflags +faststart so the browser can start playing before the whole file loads.
The result: average file size went from about 14 Mbps down to 2–3 Mbps. About 85% smaller. Playback became smooth.
I run this on my PC rather than on the NAS, by the way. The NAS has a Celeron J4125, and converting video would take a while. My PC is much faster at it, and since the NAS only sends the pre-made file — no decoding, just file transfer — moving the work to the PC is the right call.
The Bug I Almost Missed: Vertical Videos
After converting, I noticed something wrong. Videos my daughter shot in portrait mode — phone held upright — looked squished on screen. Wide faces, compressed proportions.
The issue: phone cameras store portrait video as a 1920×1080 file with a rotation flag in the metadata. Ffmpeg reads the raw dimensions (1920×1080) and, if you tell it scale=1280:720, it squishes a 9:16 image into a 16:9 box.
The fix: don’t specify the output dimensions directly. Use scale=1280:1280:force_original_aspect_ratio=decrease:force_divisible_by=2 instead. This tells ffmpeg to fit the video inside a 1280×1280 box while keeping its original proportions. Landscape comes out 1280×720. Portrait comes out 720×1280. The codec handles it correctly either way.
The already-converted files were unusable — once you squish pixels, you can’t unsquish them. But I’d kept the originals in the backup folder, so I re-ran the converter from scratch.
What It Cost
Nothing extra. The NAS was already running. Ffmpeg is free and was already installed in the app’s Docker container. The only “expense” was a few hours of AI-assisted coding and the electricity to transcode fifteen videos on my PC.
What Happened After
My daughter watched the fifteen videos in a row, then started over. An hour passed. She was laughing at things she no longer remembers doing.
My wife said she felt a little guilty — we’d been meaning to organize all that footage for over a year and kept putting it off. Now that the tool exists, she said she wants to be more deliberate about it: recording more, choosing more carefully, adding to the library instead of just letting the files pile up in a backup folder.
That’s what I was hoping for. The backup folder was full of memories we weren’t actually using. Now they have somewhere to go.
What’s Next
Right now My Tab has fifteen videos. That’s enough to keep a three-year-old busy for an hour, apparently. But the real catalog — three years of footage, hundreds of clips — is still sitting in that backup folder waiting to be sorted.
The tools are there. Now it’s just a matter of sitting down with my wife and doing it together.
That might be the better project anyway.