On 8 November I put the deck camera at Tsumagoi Work&Camp, our mountain workplace 1,444 m up in Tsumagoi, Gunma, on YouTube, live around the clock. It looks out at Mt Asama, the valley and the field. The first evening, it buffered.
Watch it → youtube.com/@tsumagoicamp/live

The setup
A Tapo C530WS outdoor camera on the deck, and one Intel NUC that reads it and sends it to YouTube. The NUC is on Wi-Fi only. One ffmpeg process does the video. A small Python supervisor around it restarts it, measures its speed and writes a health file that the Ranch Monitor reads, so a stalled stream shows up on the screen I already watch.
What broke, in the order it broke
The broadcast kept ending
I started with YouTube's "Stream now". Each time the encoder restarted, YouTube ended the broadcast, and its link and watch time went with it: four times in the first hour. A scheduled broadcast on its own key, with auto-stop off, fixed it. A reconnect now stays inside the same video.
The PC fell behind
My first version downloaded every 1080p frame from the graphics chip to draw the text on it, then uploaded it back. With nothing else running, that managed 1.25x real time. When the machine got busy, it fell behind, frames piled up into swap, and YouTube dropped the stream twice in four minutes.
Next, the frame stayed on the GPU the whole way: decode, crop, scale, colour and encode. Only the strips that carry text came down to the CPU to be drawn on, and went back on top. That held 25 frames a second, but on the morning of 9 November, with three strips coming down, ffmpeg still used about 70% of one CPU core.
Now nothing comes down. Each text plate is drawn on its own small transparent canvas and blended onto the video on the GPU (overlay_vaapi keeps the transparency). ffmpeg uses about 31% of one core and holds 25 frames a second in real time.

Night ran slow
After dark the camera switches to infrared and sends about 12 to 16 frames a second, still stamped as if there were 25. On the camera's own clock the stream played at about 0.7x, the bitrate sagged, and viewers watched a spinner.
Now every frame is stamped with the wall-clock time it arrives, and a steady 25 frames a second is the very last step before the encoder. The evening line was also losing about 5% of packets beyond our router, so the NUC got BBR congestion control and the bitrate came down to 4,500 kbit/s. YouTube Studio read "Excellent" through that evening.

Silence stalled it
YouTube wants an audio track, and the camera's microphone was never going on air: at best wind noise, at worst a guest's voice. Silence turned out to be the hard part. Silence as a separate input drifted away from the video: the audio stood still while the video ran on, then burst, and Studio said it was not receiving enough video. Silence made inside the filter died every 94 seconds or so. Forcing strict interleaving locked the muxer at 0 kbps.
What worked was borrowing the camera's own audio track only for its clock. Its samples are zeroed, then replaced by a generated soft wind (brown noise, slow gusts, 40 to 900 Hz) from an expression that never reads the input. No microphone sound can leave.
Every restart is every viewer's problem
A restart is a few seconds of nothing, and everyone watching buffers. So I stopped tweaking it live. Changes go out in batches, and the one automatic restart (a memory guard, about every two and a half hours) stays inside the same broadcast.
Worth leaving open
A mountain on a loop starts to feel fake within the hour. So the picture carries things that are true right now.
- Temperature, wind, humidity and pressure from our own weather station, every minute. A reading older than 30 minutes is left blank.
- A gold bar that fills with daylight from sunrise to sunset.
- The camera drifts a small step every minute, and the screen shows its heading and the seconds to its next move.
- Sennin, the pixel hermit from our website, types one line a minute: a local fact, a riddle with the answer three minutes later, a fortune, or a call to focus for 25 minutes and break for 5. More than 200 written lines and 80 riddles and quizzes, plus lines built from the live data. Nothing repeats within 24 hours.
- He says each line in Japanese first, then, where it has an English twin, the same line in English, in sky blue.
- When something happens in the sky, a gold banner says so: the season's first frost at our station, a notice for Mt Asama in the Japan Meteorological Agency's own words, a severe geomagnetic storm, the peak of a meteor shower.
Some of his lines are about the mountains in view, from sourced data, and about the cows that graze there sometimes.


His typing used to jump: the line could be swapped while he was still typing it. Now each line starts at the next minute mark on the stream's own clock, types out over about four seconds, and stays put until the next.
Type !omikuji in the live chat and, within a minute, Sennin reads your fortune out on the stream, by name. One fortune a person a day. Names are cleaned to 16 safe characters, the YouTube ID is kept only as a hash, and the rows are deleted after a week.
Since 9 November the chat has a few more games. !guess (!予想) is a guess at tonight's low; at 7:00 Sennin names the closest, from our station's own overnight minimum. !view (!見る) 1, 2 or 3 votes for one of three views, and the camera glides there and holds for three minutes. !gm (!おはよう) marks the first viewer after sunrise. !answer (!答え) answers his riddle, and the first right answer is named when the answer comes up.

Privacy
The frame is cropped, not painted over. The microphone never streams. We don't record the stream and rewind is off. On request, for a shoot, an event or a guest who asks, the stream switches to a pause slate. There are pixel masks for the tents in view, but they are switched off now. I turn them on by hand when guests are in view; switching them from the bookings is not built yet.
The stream is free to watch.