Case Study · Product Design · Desktop Tool · Personal Project · 2026

Yimu 譯幕

Live translated subtitles for Windows, with a floating window that stays visible across applications and supports Traditional Chinese with Taiwanese wording.

Gemini Live API · OpenAI Realtime · Python · tkinter · OpenCC

Yimu brand lockup — the 譯 logo and wordmark above an enlarged view of the subtitle window, showing an English sentence and its three-line Traditional Chinese translation, captioned: English in, Traditional Chinese out, live.

Problem
Following English lectures and meetings often meant pausing or replaying audio. I wanted subtitles that worked across desktop applications without relying on an existing caption track.
Process
A written build plan divided development into four stages, with checks for audio capture, streaming translation, window behavior, and the connected application.
Result
A working Windows tool that I use regularly, with optional transcripts and summaries added as the project developed.
2Translation engines, selectable in Settings
<3sSpeech-to-subtitle latency target
37Offline regression tests
1 dayTo the first working version

Live translation demo

This recording shows English narration appearing as source text above live Traditional Chinese subtitles.

Turn on sound to follow the English narration alongside the translation. The subtitles were generated during the recording.


Following English audio across applications

Long lectures and meetings take more effort to follow in English. When I miss a phrase, replaying it interrupts the rest of the session.

The tools I tried did not give me the combination I needed: desktop audio capture, streaming translation, and Traditional Chinese with wording familiar in Taiwan. That last detail mattered in everyday reading, including terms such as 人工智慧.

Yimu began as a tool for my own listening habits. Capturing system audio meant it could work with videos, calls, and other audio playing through the computer's default output device.


Building and checking the app in stages

The first working version took one day. A written plan divided the work into four stages so I could check each part before connecting the full application.

  1. 01

    Audio capture

    Capture Windows playback through WASAPI loopback and prepare it for the translation API. I checked recorded audio by ear for changes in pitch or speed.

  2. 02

    Translation session

    Stream audio to Gemini and display the translated text as it arrives. Checks covered live speech and reconnection after a dropped session.

  3. 03

    Subtitle window

    Build a draggable, semi-transparent window that stays above other applications. Automated UI checks and screen review covered its appearance and behavior.

  4. 04

    Integration and iteration

    Connect capture, translation, and display. Subsequent work added the second engine, settings, transcript saving, and summaries.

Acceptance checks used recorded audio, live API sessions, and the running interface. Offline regression tests covered behavior that could be checked without sending API requests.


From desktop audio to translated text

Yimu sends captured audio to the selected translation engine and displays its text output as subtitles.

The pipeline

Input

Desktop audio

Capture sound from the default Windows output device through WASAPI loopback. An existing caption track is not required.

Capture

Prepare the audio

16 kHz for Gemini or 24 kHz for OpenAI

Convert stereo audio to mono PCM and resample it for the selected engine.

Translate

Stream to the selected engine

Gemini Live or OpenAI Realtime

The selected engine receives the audio and returns translated text. Changing engines reconnects the translation session without restarting the app.

Localize and filter

Prepare Traditional Chinese

OpenCC's Taiwan conversion

For Traditional Chinese, OpenAI output passes through OpenCC's Taiwan conversion. A local filter also suppresses repeated Chinese source text.

Output

Display the subtitles

Show source text and translation in a floating window, with separate controls for their line counts. Transcript saving is optional.

Where processing happens
The app connects directly to the selected provider using locally configured API keys. Live translation requires sending audio to that provider. Transcript files are saved locally; sending a saved transcript for summarization requires a separate confirmation.

Connection status
Audio-device failures, invalid keys, and rate limits appear in the subtitle window's status line.

After the session

With transcript saving enabled, Finish closes the session and offers a summary in the selected target language. The confirmation shows the provider, transcript character count, and estimated number of requests.

The summary uses source-language text when available and falls back to translated text. Long transcripts are processed in sections. Each summary is saved as a separate Markdown file beside the transcript, preserving earlier summaries.

In use

The subtitle window in 3-line mode: English source transcription in gray above three lines of Traditional Chinese translation on a black bar. The current Yimu subtitle bar while listening: connected status, Waiting for audio message, and the two session controls, Finish and Pause. The current Yimu settings panel: Gemini and OpenAI engines, automatic source-language detection, a selectable Traditional Chinese target, source-text controls, transcript and microphone options, window controls, and interface language.

Decisions behind the interface

Streaming translation

I chose APIs that accept audio directly to support subtitles that update during playback. Keeping up with a speaker was the priority; the under-three-second figure was a development target.

Taiwanese Traditional Chinese

Character conversion alone did not address the wording I wanted to read. OpenCC's Taiwan conversion adds regional vocabulary handling to the OpenAI output.

Direct API connections

For this single-user desktop tool, a separate application backend was unnecessary. The app connects to the translation providers with locally stored keys.

Subtitle window

The window uses a dark background and keeps text visually dominant. Finish and Pause remain visible, while appearance and recording options sit in Settings.

Transcript saving

Completed transcript segments are written throughout the session. This reduces how much could be lost if the app closes unexpectedly, though an unfinished segment may still be lost.

Speaker labels

Local voice clustering provides approximate speaker labels. Settings explains the limitation so those labels are not mistaken for verified identities.

Summary confirmation

A saved transcript may contain a private meeting. Ending a session therefore requires a separate decision about sending its text for a summary. When transcript saving is off, Finish simply stops the session.

Pricing information appears beside the engine selector. Summary requests are separate from live translation, and their estimated request count appears before confirmation.


Problems found through use and review

Daily use and code review revealed several failures that needed changes beyond the initial working flow.

  • Repeated Chinese text
    Chinese speech could reappear in the transcript output even when no translated audio was produced. A local filter now compares output with recent source text, accounting for Simplified and Traditional Chinese.
  • An unfinished final sentence
    When I paused a video, OpenAI sometimes left the last sentence incomplete. Windows loopback stopped sending audio, so the session received no trailing silence. A short, capped burst of synthetic silence lets the final text complete.
  • A microphone failure that kept reconnecting
    Python's TaskGroup wrapped an exception that the error handler did not recognize. The app repeatedly reconnected instead of reporting the microphone failure. Error handling was corrected, with a regression test for the wrapped exception.
  • Missing source subtitles
    OpenAI source text was absent because input transcription had not been enabled in the session configuration. The same omission also affected echo filtering. Enabling that setting restored both.
  • A rejected summary request
    The Gemini SDK serialized a schema flag that the API did not accept. The fix separated the schema sent to the provider from the stricter validation applied to the returned summary before saving.

These fixes covered playback pauses, missing configuration, device failures, and rejected requests alongside the normal translation flow.


How I used AI in this project

This project was built in collaboration with AI; the design decisions, content, and direction are mine.

AI tools wrote the implementation code. Claude Code helped build the initial application, and later work with Codex added the summary workflow.

My work covered the product definition, written build plan, name, and logo direction. I decided how the subtitle window should behave, which controls belonged in Settings, and when a saved transcript could be sent for summarization.

Reviewing the running app and reporting problems from daily use remained part of my role throughout development.


Using Yimu for lectures and meetings

Yimu now runs on my desktop for lectures and meetings. Depending on the session, I adjust the subtitle size and line count, save a transcript, or request a summary afterward.

Continued use shaped the work beyond the first version. Pausing a video exposed the unfinished-sentence problem; reading both languages exposed the missing source-text setting. Those observations led to specific fixes in the tool I use.

Explore Yimu

Watch the recorded session or browse the implementation.