This is a submission for the Hacktoberfest Open-Source AI Challenge Week 2: Side Hustle
What I Built
If your videos get views from Brazil or Japan, YouTube already shows those viewers your title in Portuguese or Japanese. A machine wrote it, and you have never read it.
This month I started two faceless channels: rain and night sounds on one, slow daytime scenes on the other. Studio lets me replace YouTube's machine version with my own, but that means two fields per language per video. Fifty videos in twelve languages is 1,200 fields.
Channel Tongues is a Chrome side panel that opens next to YouTube Studio, plus a small helper on my laptop. I press Translate, and Gemma 4, running in Ollama on the same laptop, writes the title and description in the twelve languages with the biggest YouTube audiences. Under every title the panel shows what the translation says in English. I untick anything I don't trust, press Publish, and the helper adds the rest to the video through the official YouTube Data API, after taking a backup.
People already pay for tools that do this. I wanted one that runs on my own machine and never holds my channel's keys.
Demo
Screenshots and install steps: nazboyko.github.io/channel-tongues
Code
nazboyko
/
channel-tongues
Translate your video titles and descriptions with an open model on your own machine, then add them to the video.
Channel Tongues
Your channel's titles and descriptions in every language, translated on your own laptop.
YouTube already shows viewers abroad a machine translation of your titles, and you never get to read it. Channel Tongues opens next to YouTube Studio as a Chrome side panel; you press Translate, and Gemma 4 running on your computer through Ollama writes the title and description in the twelve languages with the biggest YouTube audiences. You read them over, press Publish, and the helper adds them to the video through the official YouTube Data API after taking a backup.
Install
You need a Mac or Linux machine with Chrome, Go 1.26 and Node 26.
- Install Ollama from ollama.com/download and open it.
- Get the code and build it
git clone https://github.com/nazboyko/channel-tongues && cd channel-tongues && make build - Run the setup. It downloads the model, walks you through your own Google…
A Go helper and a React side panel, MIT license. make build, then bin/tongues setup walks you through the rest.
How I Built It
The shape. The side panel (React, Manifest V3) reads the video id from the tab address and talks to a Go helper on 127.0.0.1. It never changes Studio's page, and reads from it only in the no-sign-in mode, after you allow it. The helper runs the model, keeps the sign-in file and writes backups, and Chrome starts it when you open the panel.
Protect, translate, check. Before Gemma sees anything, the helper swaps links, timestamps, hashtags and keep words (my channel names) for placeholders like ⟦1⟧. Then the checks run: every placeholder back in place, lines and blank lines kept, the title within 100 characters, the right script, no link or keyword the original lacks. A failed check retries twice with the exact problem. After that the card says Check this one with the reason, and it goes out only if I tick it myself.
On my first real publish, the Spanish title came back as "cabina nocturna 30s · escenas nocturnas tranquilas y música suave para dormir profundamente", with the description's first sentence glued on. Now the checks reject a title that grows a new part. With the smaller gemma4:e4b, the Korean title added "ASMR" on all three tries, and the panel held it back.
The read-back line. A placeholder check can't tell me what a Thai title means. So the same model translates each translation back into English, and the panel shows it under the title. The panel marks words my original doesn't have, and a marked title makes the card Check this one. On my sample videos it caught Turkish turning the cabin into a "mountain" cabin, and Vietnamese and Thai adding "help sleep".
On my first real panel run, 10 of 15 cards came back to check, and 9 of them blamed "created": my description said "made", and nearly every read-back said "created". Now a description word that at least half the read-backs share counts as the read-back's own wording, and only title words untick a card. The same video went from 10 cards to check to 0, and the Turkish "mountain" still gets caught. The read-back is a second opinion from the same model, and still the first time I can see what my Thai title says.
Merge, never replace. YouTube deletes any language you leave out of an update. So the helper reads the video first, starts from what is there and sends the complete set: it adds languages the video lacks, updates the ones it wrote last time, and keeps everything else. It never sends the title, description or tags. Before every write it saves a backup of the video's translations, re-reads the video and refuses if anything changed. After the write it reads each language back. Undo in the panel, or tongues restore on the command line, puts the backup back.
What a run costs. tongues translate --measure prints the seconds, the tokens Ollama counted and, with macmon installed, what the whole machine drew. Twelve languages with gemma4:26b on an M5 Max with 64 GB, model already loaded:
| Short sample | Real video | Real video | Test video | Long sample | |
|---|---|---|---|---|---|
| Title / description, characters | 57 / 273 | 96 / 691 | 99 / 727 | 93 / 1,042 | 94 / 1,979 |
| Start to finish | 22-25 s | 54 s | 56 s | 59-62 s | 157-162 s |
| Retries | 0 | 6 | 2 | 3 | 4-5 |
| Output tokens, translation and read-back | 2,484-2,518 | 5,819 | 6,566 | 6,788-6,796 | 17,710-18,315 |
| Energy, whole machine (macmon) | 0.59-0.62 Wh | 1.34 Wh | 1.50 Wh | 1.33-1.40 Wh | 4.00-4.03 Wh |
| Ready / to check / failed | 10 / 2 / 0 | 12 / 0 / 0 | 11 / 1 / 0 | 12 / 0 / 0 | 12 / 0 / 0 |
The real descriptions on my channels run 293 to 1,042 characters, so twelve languages take a minute or less and at most 1.5 Wh. On the long sample I wrote for testing, Gemma used to get stuck in Hindi and repeat one word, पढ़ते ("reading"), until the answer limit. A retry with a repeat penalty now comes through, and the long sample dropped from 212-219 seconds to 157-162.
What I cut. Translating three languages at once. With gemma4:e4b, translation only, twelve languages took 11.9 and 12.5 seconds one at a time and 12.4 and 14.0 three at once, so one at a time stayed. A model picker and a settings page: the helper uses the best Gemma 4 you have, and your keep words live in one fold at the bottom of the panel.
Why Does Open Innovation Matter?
The person most afraid of a tool like this is a channel owner. An open tool that runs on your machine answers that fear with things you can check.
Google's consent screen for the YouTube scope says the app can "see, edit and permanently delete" your videos. Google offers no narrower scope that only writes translations, so any tool that publishes them has to ask for that much. Channel Tongues keeps the dangerous part small and visible:
- The Google project is your own, the sign-in file stays on your disk, and Sign out deletes it and tells Google.
- The code calls four API methods: three reads (your channel, your uploads list, your videos) and one write,
videos.update, which sends only the translations. The one exception is a separate command that sets a video's language, and you run it by hand. - Every write starts with a backup and ends with a read-back, and Undo takes one click.
- You can skip the sign-in. "I'll paste it myself" translates on your machine, and you copy the results or save them to a folder. No Google account appears on that path.
Running locally gives you the rest. A back catalog of a few hundred videos costs nothing per video, so you can localize all of it. Your channel and series names stay as written; YouTube's machine translation has no way to know they are names. And a better open model next month is one ollama pull and one setting away.
One cloud extension in this space states in its Chrome Web Store listing that it collects "authentication information", "web history" and "user activity". That may suit many people. For a channel owner who worries about their account, a local model and a local sign-in file decide whether they try a tool at all.
Honest limits. YouTube can't translate tags. The free API quota covers about 190 publishes a day. A Google project in Testing status signs you out every seven days. The read-back shares the model's blind spots and raises some false alarms, such as Japanese "Pleasant" for "Cozy". A translation can also pass every check and still get the meaning wrong: with gemma4:e4b, "Light Waves" at a harbor became "waves of light". Read before you publish; the panel shows the original next to every card.
My First User
I am the first user, on my own two channels, The Slow Night Hours and The Living Postcard.
- The Living Postcard's three public videos had no translations.
bin/tongues channel localize --langs used --applyadded the 11 languages I last picked to each in 1 minute 54 seconds, with a backup before each write and none held back. By hand in Studio, that is 66 fields. - On a private test video on The Slow Night Hours, before the read-back line existed, the panel translated twelve languages in 10.4 seconds, published all twelve in one click, and Undo put the video back as it was.
Prize Categories
Best Use of Gemma: Gemma 4 writes every translation and every read-back through Ollama on the creator's own laptop, as gemma4:26b, or gemma4:e4b on smaller machines.
Credits: Gemma 4 by Google (Gemma Terms of Use) through Ollama (MIT); the Google API client for Go, golang.org/x/oauth2 and golang.org/x/text (BSD-3-Clause); modernc.org/sqlite (BSD-3-Clause); React, Vite and Vitest (MIT); the Inter typeface (SIL Open Font License 1.1); macmon for the power numbers (MIT). Audience figures from DataReportal's Digital 2025. Channel Tongues is MIT-licensed and not affiliated with YouTube or Google.




Top comments (0)