English · 简体中文 · 日本語 · 繁體中文 · 한국어
Kando is a desktop app for learning a language from videos in that language. Paste a YouTube or Bilibili link, or drop a video file on the window: Kando downloads the video with yt-dlp, transcribes the speech on your own computer with whisper.cpp, translates each line through an OpenAI-compatible model, and plays the original video with the original line and its translation on screen together. It is written in Go and draws its native interface with MyGo and Breeze UI; there is no web view.
The interface is in English, Simplified Chinese, Traditional Chinese, Japanese and Korean. Kando starts in Simplified Chinese; choose another language in Settings › General › Interface language, and the window changes at once. The labels quoted below are those of the English interface.
- Add a video by pasting a link from YouTube, Bilibili or any other site yt-dlp supports (Help › Supported Websites… lists them, with their logos), or pick a local file (mp4, mov, mkv, webm and other video files) or drag it onto the window. Local files are transcribed where they are, not copied.
- Jobs run one after another through download, transcription, translation and export. A failed job says why, links to the setting that fixes it, and can be retried or removed.
- Speech is recognized on your computer with whisper.cpp, which detects the spoken language. Settings › Speech Recognition lists seven whisper models, from Tiny (77.7 MB) to Large v3 (3.1 GB), and downloads the one you choose from Hugging Face.
- Lines are translated by EveryAPI by default, or by any OpenAI-compatible chat API: Settings › AI Service has presets for OpenAI, OpenRouter, Groq, DeepSeek, xAI, Mistral, Qwen (DashScope), Kimi, Zhipu GLM, SiliconFlow, Ollama and LM Studio, plus a custom endpoint. The target language, a context-aware mode that lets the model read the preceding lines, and the prompt can be changed in Settings › Translation.
- Each finished video gets two SubRip files next to it:
<video>.srtwith the original lines and<video>.bilingual.srtwith each translation above its original line (video.srtandvideo.bilingual.srtfor a downloaded video). - The player shows the subtitles as bilingual, original only, translation only or off, with a delay you can adjust in 0.1-second steps and a style you can change. Its side panel lists every line with search (click a line to jump to it), splits the video into 4 to 12 clips of about 30 seconds, and shows the film's files and source. Each film resumes where you stopped watching.
- Libraries are
.kandofolders of ordinary files you can manage in Finder or a file manager. You can keep several and switch between them from the sidebar, which also filters a library by source: YouTube, Bilibili, other sites and local files. - Optional upload of a film's video and bilingual subtitles to your own object storage (Cloudflare R2, Amazon S3, Alibaba Cloud OSS, Tencent Cloud COS or any S3-compatible store), from the player, after signing in with Google. See Configuration.
- Keyboard shortcuts for playback, subtitles and windows, listed in a cheat sheet (⌘/) and in Settings › Keyboard Shortcuts.
Builds for macOS (Apple silicon and Intel) and Linux (x86-64 and ARM64) are on GitHub Releases; there is no Windows build yet, so on Windows build from source as described below. They are not signed with a Developer ID or code-signing certificate, so the system warns the first time you open Kando:
- macOS: on macOS 15 and later, open Kando once, then choose System Settings › Privacy & Security › Open Anyway. On macOS 14 and earlier, Control-click Kando in Applications and choose Open. Or remove the quarantine flag in Terminal:
xattr -dr com.apple.quarantine /Applications/Kando.app. - Windows: in the SmartScreen dialog, choose More info › Run anyway.
With Go 1.27.3 or later:
git clone https://github.com/yldm-tech/Kando.git
cd Kando
make buildmake build runs go tool mygo build apps/kando for the platform you are on and writes the result under apps/kando/build/<os>-<arch>/: on macOS an ad-hoc signed Kando.app and a .dmg, on other platforms an executable (Linux also gets a .deb, a .tar.gz with an install script and a PKGBUILD; Windows an installer made with NSIS, which mygo downloads when it is not installed). Without make, as on a stock Windows, run go tool mygo build apps/kando from the repository root.
Kando runs yt-dlp, ffmpeg and whisper-cli (whisper.cpp). On macOS and Linux there is nothing to install: when Kando opens and one of them is missing, it downloads it, and the Getting Started guide shows the progress. Programs you already installed, such as with Homebrew, are used as they are.
| Program | Used for | What Kando downloads |
|---|---|---|
yt-dlp |
Downloading online videos. Kando asks for it for every job, local files included. | The standalone build from the yt-dlp release. |
ffmpeg |
Extracting the audio, grabbing covers and decoding the picture in the player. On macOS the sound plays through ffplay beside it, or afplay. |
FFmpeg 9.0.2, with ffplay on macOS, from this repository's tools release. |
whisper-cli (whisper.cpp) |
Speech recognition. | whisper.cpp 1.9.5, with Metal on macOS, from the same release. |
| A whisper.cpp ggml model | Download one in the Getting Started guide or Settings › Speech Recognition, or point KANDO_WHISPER_MODEL at a model file. |
The tools release is built by the Tools workflow (.github/workflows/tools.yml) from the sources pinned in .github/tools.env, and Kando checks each download against a SHA-256 pinned in the app before using it. Downloads go to the tools folder beside settings.json (~/Library/Application Support/Kando/tools on macOS, ~/.config/Kando/tools on Linux). Kando looks there first, then on PATH and in /opt/homebrew/bin, /usr/local/bin and /home/linuxbrew/.linuxbrew/bin, because apps opened from Finder or a desktop launcher get a minimal PATH. Settings › General shows which program is used, offers Download or Retry for one that is missing, and Detect Again looks again. If a download fails because yt-dlp is out of date, Kando offers Update and Retry, which updates it the way it was installed and retries.
On Windows Kando does not download them yet: install the same programs with your package manager and make sure they are on PATH.
On Windows and Linux the player currently shows the picture without sound; audio playback is implemented on macOS only.
- Open Kando. With no library yet, it offers New Library… (named Film Library in
~/Movieson macOS or~/Videoselsewhere unless you change it) and Open Existing Library…. - The Getting Started guide downloads
ffmpeg,yt-dlpandwhisper-cliif they are missing. Open Settings (⌘,): General shows them with their versions, and has the interface language. - In Speech Recognition, click Download next to a whisper model; Kando selects it when the download finishes. The one marked Recommended is Large v3 Turbo (Compressed), 574 MB. Models that Vimpo or hyperframes already downloaded can be selected without copying.
- In AI Service, set up translation:
- EveryAPI (the default): sign in once with the EveryAPI CLI,
everyapi auth login. Kando asks the CLI for the key (everyapi auth credential), so it uses the same login, gateway region and key refresh as the CLI, and you do not paste a token. The default model isclaude-haiku-5-5;everyapi models listshows the others. You can also paste an EveryAPI key into API Key instead. - Another provider: choose it under Service, or choose OpenAI Compatible and enter its Base URL, then fill in Model and API Key (local servers such as Ollama and LM Studio need no key). Test Connection sends a short request to check the settings.
- EveryAPI (the default): sign in once with the EveryAPI CLI,
- In Translation, pick the default target language: Simplified Chinese (the default), Traditional Chinese, English, Japanese, Korean, Spanish, French or German.
- Back in the window, paste a link into the top bar and click Start Processing, or click Local Video or drag a video onto the window. The status line at the bottom of the sidebar says Ready to process when everything a job needs is in place, and otherwise names what is missing.
When the translation provider answers with a rate limit or a server error, Kando sends the request again, up to three attempts in all.
Everything below except the Google client id and secret can also be set in the app (the library from the sidebar, the rest in Settings). An environment variable, when set, takes the place of the value saved in the app.
| Variable | Default | Meaning |
|---|---|---|
KANDO_WHISPER_MODEL |
the model chosen in Settings › Speech Recognition | Path of a whisper.cpp ggml model file, such as ggml-small.bin. |
KANDO_LLM_BASE_URL |
EveryAPI, https://api.everyapi.ai/v1 |
Base URL of an OpenAI-compatible provider, such as https://api.openai.com/v1, or http://localhost:11434/v1 for Ollama. When it is set, the signed-in EveryAPI account is not used. |
KANDO_LLM_MODEL |
claude-haiku-5-5 on EveryAPI |
Translation model. With a custom provider there is no default: set it here or in Settings › AI Service. |
KANDO_LLM_API_KEY |
none | Bearer token for the translation provider. It overrides the signed-in EveryAPI account. |
EVERYAPI_API_KEY |
none | EveryAPI key, used when KANDO_LLM_BASE_URL is unset and KANDO_LLM_API_KEY is empty, instead of the CLI login. |
KANDO_OUTPUT_DIR |
the library opened last | Library folder to open at launch, where new videos and subtitles go. |
KANDO_GOOGLE_CLIENT_ID |
none | Google OAuth client id for signing in on Settings › Account & Upload. Without it the sign-in button is disabled. It is never saved to the settings file. |
KANDO_GOOGLE_CLIENT_SECRET |
none | Optional client secret for the same OAuth client. |
KANDO_STORAGE |
r2 |
Where uploads go: r2, s3 (or aws), oss (or aliyun), cos (or tencent), compat (or s3compat). Any other value means R2. |
KANDO_R2_ENDPOINT |
none | Cloudflare R2: an account id or a full https:// endpoint. |
KANDO_R2_BUCKET, KANDO_R2_ACCESS_KEY, KANDO_R2_SECRET |
none | Cloudflare R2 bucket and keys. |
KANDO_S3_REGION |
none | Amazon S3 region name, such as ap-northeast-1. |
KANDO_S3_BUCKET, KANDO_S3_ACCESS_KEY, KANDO_S3_SECRET |
none | Amazon S3 bucket and keys. |
KANDO_OSS_REGION |
none | Alibaba Cloud OSS region name, such as cn-hangzhou (cn-hangzhou-internal for the internal network). |
KANDO_OSS_BUCKET, KANDO_OSS_ACCESS_KEY, KANDO_OSS_SECRET |
none | Alibaba Cloud OSS bucket and keys. |
KANDO_COS_REGION |
none | Tencent Cloud COS region name, such as ap-guangzhou. |
KANDO_COS_BUCKET, KANDO_COS_ACCESS_KEY, KANDO_COS_SECRET |
none | Tencent Cloud COS bucket (its name includes the APPID, such as video-1250000000), SecretId and SecretKey. |
KANDO_S3COMPAT_ENDPOINT |
none | Full https:// endpoint of another S3-compatible store. |
KANDO_S3COMPAT_REGION |
none | Signing region of that store; MinIO usually uses us-east-1. |
KANDO_S3COMPAT_BUCKET, KANDO_S3COMPAT_ACCESS_KEY, KANDO_S3COMPAT_SECRET |
none | Bucket and keys of that store. |
KANDO_S3COMPAT_PATH_STYLE |
off | 1, true, yes or on turns on path-style addressing, which MinIO needs; 0, false, no or off turns it off. |
Uploading is manual: open a film and click Upload to R2 (or the store you chose) in the player. Kando uploads the video and its bilingual subtitles under <Google account email>/<library>/<film folder>/<file>; the sign-in only says who uploaded. Videos are never uploaded automatically.
A library is a folder whose name ends in .kando. Each downloaded film gets its own folder inside it, <title> [<video id>]/, holding video.mp4, cover.jpg, video.srt and video.bilingual.srt. They are ordinary files: Kando watches the library folder, so videos added or removed in Finder or a file manager show up in the library. On macOS a .kando folder gets a folder icon with the Kando mark in Finder.
Removing a film from the library moves the film's folder to the Trash, or only its video and subtitles when that folder holds other videos or folders too; a local video outside the library folder stays where it is and only leaves the list. Removing a library from the list leaves its folder on disk.
Kando keeps its own files in the user config directory, ~/Library/Application Support/Kando on macOS, %AppData%\Kando on Windows and ~/.config/Kando on Linux:
library.json: the jobs, finished and in progress, and where each video stopped playing.settings.json: the settings, including the API key, the object storage keys and the Google refresh token, in plain text. The file is readable only by your user.window-state.json: window sizes and positions.models/: whisper models downloaded in Settings › Speech Recognition.
Cover images of videos that are not named video.* are cached in ~/Library/Caches/Kando/posters on macOS, %LocalAppData%\Kando\posters on Windows and ~/.cache/Kando/posters on Linux.
Kando was called LingoCut, and nothing reads the old names. To keep your libraries and settings:
- Quit the app.
- Rename the config folder from
LingoCuttoKando:~/Library/Application Support/LingoCuton macOS,%AppData%\LingoCuton Windows,~/.config/LingoCuton Linux. It holdslibrary.json,settings.json,window-state.jsonand the downloaded models. - Rename each library from
X.lingocuttoX.kando, after renaming the config folder and before launching. On macOS and Linux the saved inodes let the app follow every renamed library. On Windows the app can only match one missing library to one new.kandofolder in the same parent folder, so rename one library per folder at a time and launch the app once after each rename. - Rename each environment variable from
LINGOCUT_*toKANDO_*. - Launch Kando and choose the speech model again in Settings › Speech Recognition: the model file moved with the folder and shows as downloaded, but the saved choice still points at the old path.
- Delete what is left of the old name:
lingocut.appandlingocut Dev.app; the poster cache~/Library/Caches/LingoCut(%LocalAppData%\LingoCuton Windows,~/.cache/LingoCuton Linux); on Linux the lowercase~/.config/lingocut; and, if you ranmake dev,~/Library/Application Support/lingocut Dev.
Requires Go 1.27.3 or later.
make test # go test for packages/core, packages/media and apps/kando
make dev # run the app with live reload
make build # build the app for this platform into apps/kando/buildmake dev runs MyGo's mygo dev patched by tools/mygo-dev: on macOS, a reload keeps the running window until the new build shows its own, instead of quitting it first, so saving a change does not look like the app quitting. If the patch stops applying after a MyGo upgrade, it warns and falls back to the stock go tool mygo dev; update tools/mygo-dev/dev.go.patch against the new cmd/mygo/dev.go then. The script behind it, tools/mygo-dev/dev.sh, is a POSIX shell script.
The screenshot tests render the main scenes to PNG files from a fixed demo library, in an empty fake home folder with fake ffmpeg, yt-dlp and whisper-cli, so they do not read your settings, libraries or tools:
KANDO_SCREENSHOTS=/tmp/kando-shots go test ./apps/kando/... -run TestScreenshotsKANDO_SCREENSHOTS_LANG (en, zh-Hans, zh-Hant, ja or ko) renders them in that interface language, with a demo library for its reader; -run TestScreenshotsReadme renders the four pictures of the READMEs, kept in docs/assets/<language>/.
Repository layout:
apps/kando: the app. Each screen has its own directory (sidebar/,films/,film/,settings/,account/,cheatsheet/);view.goconnects the window to them.shelf/is the job record,cloud/is Google sign-in and object storage upload, andbrand/is the Finder icon of a library.packages/core: platform-independent jobs, stages and link parsing.packages/media: the media pipeline: download, transcription, translation, subtitle export, covers and libraries.tools/mygo-dev: the patchedmygo devbehindmake dev.
AGENTS.md describes how the interface is split into components and the rules each area follows; read it before changing the UI.
The CI workflow builds and tests pull requests and main. The Release workflow runs after CI passes on main, or by hand: it picks the next version from the Conventional Commits since the last tag, commits it to main as chore(release), tags it, builds packages for macOS, Windows and Linux without a Developer ID or code-signing certificate, and publishes a GitHub release with their checksums.



