English · 中文
It employs a non-destructive localization approach, requiring no modifications to the original official executables or DLL files. By loading external plain-text JSON language packs, it dynamically intercepts and replaces interface text at runtime. It offers seamless support not only for Simplified and Traditional Chinese but also for a wide range of languages—such as Japanese, Russian, Spanish, German, and French—simply by swapping the corresponding JSON dictionary.
It offers deep compatibility with standard Win32 controls, JScript-based panels, and modern WebView2-based front-end UIs.
Chinese display name 动态多语引擎.
Component version: 1.7.1.
This repository hosts release notes and open language-pack JSON. The component source is not published. Get the installer from the repo Releases page.
- On startup, the component checks for updates and anonymously reports the plugin UI language and the current translation target language.
- Fixed a crash when enabling Zero Bus Service if the Zero Bus server is not installed or not running.
- Windows / macOS: View → Dynamic Multilingual Engine adds Download language packs and Contribute a translation.
- The download window lists community packs for the selected language (contributor, upload time, entry count, size, and score) and shows reviews. Download a pack, or download it and switch to it immediately.
- One language can have many packs. Editing a downloaded cloud pack saves a local modified copy and leaves the original file unchanged.
- Review packs you have downloaded. After a reinstall, an email verification code can recover your upload history.
- Column widths in the download, upload, and review windows are remembered. The download window has a Refresh button.
- Cloud service: https://foo-lang.klyrics.cn
- Windows: Preferences tree nodes of other components (such as foo_zero_bus's "Zero Bus") no longer show a whole translated window title (such as "偏好页:Zero Bus") instead of their own name. Translations that use a full-width colon are handled too.
- macOS: The Dynamic Multilingual Engine preferences page now fits its content instead of filling the whole screen.
- Simplified Chinese: Unified the Zero Bus / JSplitter preferences window titles.
- Windows / macOS: Online translation progress dialog now remembers and restores its window position, with compact UI layout and spacing (dialog width reduced to 3/4) and updated prompt text.
- Windows / macOS: Language pack management context menu clarified to "Online translate all sources..." and "Online translate all untranslated sources...".
- Windows / macOS: Preferences advanced rule editing dialog now dynamically measures label lengths to adaptively adjust control bounds, eliminating truncation for localized strings (e.g. Class, Control ID, Menu ID, Translation).
- Windows: Fixed an issue where third-party context submenus (e.g., image-right plugin) failed to appear when dynamic translation was enabled due to Win32 menu handle and state handling.
- Windows: Added ARM64EC CMake configuration and build support for broader architecture coverage.
- Updated and synchronized language pack dictionaries.
- Windows / macOS: Translation service provided via Zero Bus; service name: plugin.localize (requires foo_zero_bus). New Zero Bus preferences page.
- Windows: lyric overlay windows (desktop / floating / taskbar) are no longer translated, so menu text such as Preferences is not drawn into lyrics.
- Fixed a false positive in the word lookup function: "Klyrics" no longer incorrectly matches "Klyrics\nProduct version ..."
- Windows: COM
Enable/Disableonly control hook replacement (optionalhwnd). They no longer change the user's Enable Multi-Lang Engine checkbox. - Windows:
EnableTranslation/DisableTranslationonly controlTranslate()lookup. The dictionary works even when the plugin switch is off. - Windows:
IsPluginEnabled()reads the user checkbox.Skip()no longer blocksTranslate().
- Windows: JSplitter / Spider Monkey Panel can create
FooLocalize.Engine(type information is provided;GetTypeInfono longer fails). - Windows: The JS sample works on both JScript Panel 3 and JSplitter. Call COM members as methods, e.g.
engine.IsEnabled(),engine.Translate("Play"). - Windows: A JS panel’s
SetPanelTypeno longer leaks onto other windows, which caused ghosted radio-button labels on already-localized dialogs such as JSplitter Configuration.
- Language packs now support more precise matching: matching conditions can be attached, allowing the same source text to be linked to different translations depending on the context.
- Windows: Supports translating text within WebView2 pages (exact match; disabled by default), including
placeholder,title,alt, and buttonvalueattributes. - Upon upgrading, new entries from the built-in language packs are merged into existing
foo-langfiles without overwriting user-modified translations.
- Language-pack window: right-click to copy the source or the translation separately
- About 99 new Simplified Chinese entries (column headers, Klyrics, visualizations, Cover Art Archive, and more), synced to Traditional Chinese / Japanese / Russian / Spanish / German / French
- Online translation: in the language-pack window, use an online engine to translate source strings automatically
- Windows / macOS: choose an online translation engine (Google / Baidu) and enter AppID / secret in Preferences
- macOS: language-pack window now matches Windows (preview, merge, edit, online translate)
- Standalone language-pack window: preview a pack, merge into a target language, and edit translations in the list
- Windows: new Translate DUI main menu switch (on by default; also requires Translate menus); paint uses bar titles and the BeginPaint window so Preferences no longer stacks English under Chinese
- Windows: playlist translation applies only to the main window, so plugin dialogs such as YouTube Find in page no longer ghost
- Simplified Chinese pack: Playing / Artist/album / Title / track artist / Track no
- Pack manager, DUI switch, and content-scope rules are Windows-only; macOS matches 1.2.2
- Windows x64: fix 1.2.1 rejecting nearly all UI text pointers, which left runtime strings and the Default UI menu bar untranslated
- Windows: fix a crash when other components open the system file dialog (
SetWindowTextWreceived(LPWSTR)-1)
- Windows: optional static-resource translation (string tables and dialog templates)
- Windows: JScript Panel / Spider Monkey Panel can call
new ActiveXObject("FooLocalize.Engine")for owner-drawn text - Windows: Default UI menu bar is translated on startup, without a window jump
- Static resources and COM are Windows-only; macOS matches 1.1.0
- Separate toggles for menus, dialogs, and playlist / library text
- Playlist and library column headers translate; lookups strip zero-width format characters and accept
%year%/%length%wrappers - Windows: menu items measure translated width; dialogs no longer paint English under Chinese; SysLink captions translate
- macOS: the Language list lives under View → Dynamic Multilingual Engine, matching Windows
- First release: Windows 32 / 64-bit and macOS
- Main menus, context menus, Preferences, dialogs, and window titles follow the language pack
- View → Dynamic Multilingual Engine → Language switches packs live; Developer Mode writes missing strings to
harvest.txt - Built-in Simplified / Traditional Chinese, Japanese, Russian, Spanish, German, French, and an English template; first launch writes them to
foo-lang(existing files are never overwritten)
| Item | Requirement |
|---|---|
| OS | Windows 10 / 11; macOS 11+ |
| Player | foobar2000 2.0+ (32-bit or 64-bit) |
| Not supported | foobar2000 1.x; Windows components cannot be loaded on Mac and vice versa |
32-bit and 64-bit are two different DLLs. Do not mix them.
| Player | Component file | Install folder |
|---|---|---|
| foobar2000 2.x 32-bit | foo_localize.dll |
%APPDATA%\foobar2000-v2\user-components\foo_localize\ |
| foobar2000 2.x 64-bit | foo_localize.dll |
%APPDATA%\foobar2000-v2\user-components-x64\foo_localize\ |
| foobar2000 Mac | foo_localize.component |
~/Library/foobar2000-v2/user-components/ |
Language packs stay in the user profile, not the program folder:
| OS | Language-pack folder |
|---|---|
| Windows | %APPDATA%\foobar2000-v2\foo-lang\ |
| macOS | ~/Library/foobar2000-v2/foo-lang\ |
- Open Releases and download
foo_localize-1.6.1.fb2k-component(official foobar package: one zip with 32-bit, 64-bit, and macOS; Install picks the matching binary). - In foobar: File → Preferences → Components → Install, then pick that file.
- Or copy the matching DLL /
.componentinto the folder above and fully quit, then reopen foobar2000.
On first launch the built-in packs are written to foo-lang only when that file is missing. Existing JSON is never overwritten, so upgrading the component does not discard your edits.
A typical 64-bit Windows path:
C:\Users\<name>\AppData\Roaming\foobar2000-v2\user-components-x64\foo_localize\foo_localize.dll
C:\Users\<name>\AppData\Roaming\foobar2000-v2\foo-lang\
foobar cannot overwrite the DLL while it is running. Quit first.
- Master switch: Off after a fresh install. Enable it under View → Dynamic Multilingual Engine → Enable, or in Preferences.
- Scopes: separately enable menus, Translate DUI main menu, dialogs, and playlist / library text. Windows also has Enable static resource translation (gated by the master switch, off by default).
- Switch language: View → Dynamic Multilingual Engine → Language, or File → Preferences → Display → Dynamic Multilingual Engine and pick Target language. Manage packs edits entries, merges harvest files, and can translate online.
- Developer Mode: same View → Dynamic Multilingual Engine submenu.
- Developer Mode appends unmatched UI English to
foo-lang/harvest.txt. Merge new keys into the JSON, then pick the language again or restart.
en-US-template.json has empty values, so selecting it shows the original English. Use it as a blank for a new pack.
Menus and dialogs refresh immediately after a switch. A few owner-drawn controls may need the window reopened.
The English UI string is the key; the translation is the JSON value. An empty value leaves the original text on screen. Do not use an empty string to mean “hide”.
| Rule | Meaning |
|---|---|
| Exact match | Look up the on-screen source text; ASCII case can fold, and a leading • / surrounding spaces / zero-width format characters are stripped first |
@name |
Language-menu label only; not substituted into the UI |
| Menu accelerators | Text after \t is the shortcut; translate only the visible part before \t |
| Empty value | Do not translate |
| Do not translate | Track titles, file names, playlist names, paths, URLs, foobar2000, foo_*, ReFacets, UPnP, FFmpeg, font names, Title Formatting, config scripts |
| First-run seed | A built-in pack is written only if that file is absent from foo-lang |
| Upgrades | Existing JSON is kept; to restore a shipped pack, back it up, delete that file, and restart |
| Harvest | Developer Mode → harvest.txt → merge into JSON → pick the language again |
[dict/](dict/) in this repo matches the built-in seeds. Writing guide: Language pack guide.
Shipped files:
| File | Display name |
|---|---|
zh-CN.json |
简体中文 |
zh-TW.json |
繁體中文 |
ja-JP.json |
日本語 |
ru-RU.json |
Русский |
es-ES.json |
Español |
de-DE.json |
Deutsch |
fr-FR.json |
Français |
en-US-template.json |
English (template) |
The Windows Columns UI status-bar volume cell currently draws -3.00 dB, not the word volume. That path is deferred.
File → Preferences → Display → Dynamic Multilingual Engine (Chinese UI: 动态多语引擎)
Enable the engine, the translation scopes (including the DUI main menu), Developer Mode, Plugin language, Target language, and the online engine / AppID / secret. Manage packs opens a window to edit entries. The View menu group follows the plugin language: 动态多语引擎 in Chinese, Dynamic Multilingual Engine in English.
C++ components: the header and a buildable sample live in [sdk/](sdk/README.md). Copy [sdk/foo_localize_api.h](sdk/foo_localize_api.h) into your project and call localize_api::tryGet. Implement localize_notify and register it with FB2K_SERVICE_FACTORY to hear language changes. Full sample component: [sdk/sample/](sdk/sample/README.md).
JScript Panel 3 (Windows only): paste [sdk/foo_localize.js](sdk/foo_localize.js) into a panel. Use new ActiveXObject("FooLocalize.Engine") and gr.WriteText (same as Klyrics). If the component is not installed, catch the error and keep English.
With Zero Bus installed, the component also registers plugin.localize (Windows and macOS). See Zero Bus.
See Component API. 中文:docs/api.md.










