| Download | Help Us Translate! | Join Discord Server |
|---|---|---|
Kainote is a powerful subtitle editor designed for a wide range of tasks. It utilizes FFMS2 for high-precision work like typesetting, timing, and advanced editing, and DirectShow for general video playback and minor subtitle adjustments.
- Comprehensive Format Support: Natively handles ASS, SRT, MPL2, MDVD, and TMP formats. SSA files are automatically converted to ASS upon loading.
- Versatile Format Conversion: Easily convert subtitles between any of the supported formats.
- Translation Mode: A dedicated mode that displays the original text alongside the translation field, streamlining the localization process.
- Efficient Navigation: Quickly seek to lines that have not yet been translated or committed to final.
- Bulk Tagging: Apply ASS tags to multiple selected lines simultaneously.
- Visual Tools: Visually adjust tags like
\pos,\move,\org,\clip,\iclip, and vector drawings (\p) directly on the video frame. - Precision Zoom: Zoom in on the video, even in fullscreen mode, to create highly accurate vector clips and drawings.
- Integrated Time Shifting: Adjust subtitle timing directly within the main grid and sync changes with the current audio/video position.
- Advanced Audio Tools: Visualize audio as a spectrum or waveform display. Includes an auto-splitting tool perfect for timing karaoke lyrics.
- Automation 4 Support: Supported Automation 4 scripts with DependencyControl.
- Subtitle Comparison: Compare two different subtitle files side-by-side in separate tabs.
- Advanced Subtitle Filtering: Filter the subtitle view to hide unnecessary lines and focus on your work.
You can download the latest beta version of Kainote from the link below.
Please Note: Beta builds are unstable and intended for testing purposes. Features may be incomplete or contain bugs. If you encounter issues or have feedback, please join our Discord server.
Want to see Kainote in your native language? You can help us by contributing translations on Weblate, a user-friendly platform for localization.
Help Translate Kainote on Weblate
For questions, help, or to join the community, find us on Discord!
Join the Kainote Discord Server
Kainote currently has two supported source-build paths:
- Windows: the upstream Visual Studio solution (
Kainote.sln). This is the full-featured build that uses DirectShow, DirectSound, Direct3D 9/D3DX9, and the Windows COM/Shell APIs. - Linux: This build uses wxGTK and system packages where possible. Some Windows-only runtime backends are still compatibility layers or partial ports, but the project can be configured, compiled, linked, and smoke-tested on Linux.
The commands below assume a fresh clone:
git clone https://github.com/bjakja/Kainote.git
cd KainoteInstall the following tools before opening the solution:
-
Visual Studio 2022
- Install the Desktop development with C++ workload.
- Include the MSVC v143 x64/x86 build tools.
- Include the Windows 10/11 SDK.
- The solution is normally built as Release | x64.
-
DirectX SDK (June 2010)
- Download from Microsoft: https://www.microsoft.com/en-us/download/details.aspx?id=6812
- The project expects the default install location:
C:\Program Files (x86)\Microsoft DirectX SDK (June 2010) - If it is installed somewhere else, update the include/library directories in Visual Studio project properties.
-
NASM
- Download from https://www.nasm.us/.
- Add
nasm.exetoPATHduring installation, or add it manually afterwards. - Verify from a new terminal:
nasm -v
-
Git
- Required for cloning dependency source trees.
- Download from https://git-scm.com/download/win.
-
CMake
- Required for some third-party libraries such as AOM and VVENC.
- Download from https://cmake.org/download/ and add it to
PATH.
-
MSYS2
- Required for building FFmpeg with the MSVC toolchain.
- Download from https://www.msys2.org/ and install to
C:\msys64.
The Visual Studio project expects most third-party source trees under Thirdparty.
After downloading/extracting dependencies, the layout should look like this:
Kainote/
Kainote.sln
Kainote/
Kainote.vcxproj
Thirdparty/
boost/
icu/
wxWidgets/
ffms2/
luajit/
luabins/
libass/
Hunspell/
uchardet/
BaseClasses/
At minimum, download/extract the following libraries if they are not already present in the repository checkout:
- Boost: https://www.boost.org/releases/latest/
- Extract or rename the directory to
Thirdparty/boost.
- Extract or rename the directory to
- ICU4C source: https://github.com/unicode-org/icu/releases/
- Download the
icu4c-*-src.ziparchive. - Extract or rename the directory to
Thirdparty/icu.
- Download the
- FFMS2: https://github.com/FFMS/ffms2
- Kainote uses additional FFMS2 API functions; see the FFMS2 patching step below.
Note: building ICU from source can require a large amount of RAM. On machines with limited memory, configure a large Windows page file before building.
These optional codec libraries are used by the FFmpeg build configuration below.
They are built with Visual Studio, but their .pc files are consumed from MSYS2.
Open x64 Native Tools Command Prompt for VS 2022 and run:
git clone https://aomedia.googlesource.com/aom C:\src\aom
mkdir C:\build\aom
cd /d C:\build\aom
cmake C:\src\aom -G "Visual Studio 17 2022" -A x64 ^
-DCMAKE_BUILD_TYPE=Release ^
-DAOM_TARGET_CPU=generic ^
-DBUILD_SHARED_LIBS=0 ^
-DENABLE_DOCS=0 ^
-DENABLE_TESTS=0 ^
-DENABLE_TOOLS=0 ^
-DENABLE_CCACHE=1 ^
-DCONFIG_AV1_ENCODER=0
cmake --build . --config ReleaseEdit the generated aom.pc so that:
includedirpoints to a directory containing both the AOM sourceaomheaders and the generatedconfigheaders.libdirpoints to the Release library output directory.
Copy the edited file to:
C:\msys64\usr\lib\pkgconfig\aom.pc
Open x64 Native Tools Command Prompt for VS 2022 and run:
git clone https://github.com/fraunhoferhhi/vvenc C:\src\vvenc
mkdir C:\build\vvenc
cd /d C:\build\vvenc
cmake C:\src\vvenc -G "Visual Studio 17 2022" -A x64 ^
-DCMAKE_BUILD_TYPE=Release ^
-DBUILD_SHARED_LIBS=0 ^
-DVVENC_LIBRARY_ONLY=1
cmake --build . --config ReleaseEdit the generated libvvenc.pc so that:
includedirpoints to the directory containing thevvencheaders.libdirpoints to the Release library output directory.
Copy the edited file to:
C:\msys64\usr\lib\pkgconfig\libvvenc.pc
-
Edit:
C:\msys64\msys2_shell.cmd -
Find this line:
rem set MSYS2_PATH_TYPE=inherit -
Uncomment it:
set MSYS2_PATH_TYPE=inherit
-
Open x64 Native Tools Command Prompt for VS 2022.
-
Start the MSYS2 shell from inside that prompt:
C:\msys64\msys2_shell.cmd
-
In the MSYS2 shell, install the build tools:
pacman -Syu pacman -S --needed make diffutils yasm nasm pkg-config git
-
Avoid a linker-name conflict with MSYS2's
link.exe:if [ -f /usr/bin/link.exe ]; then mv /usr/bin/link.exe /usr/bin/link.exe.bak; fi
-
Confirm MSVC tools are visible inside MSYS2:
which cl which link cl
which link should resolve to the Visual Studio linker, not /usr/bin/link.exe.
From the same MSYS2 shell that inherited the Visual Studio environment:
cd /c
curl -L -o ffmpeg-n7.1.1.zip https://github.com/FFmpeg/FFmpeg/archive/refs/tags/n7.1.1.zip
unzip ffmpeg-n7.1.1.zip
mv FFmpeg-n7.1.1 ffmpeg
cd /c/ffmpeg
./configure \
--toolchain=msvc \
--enable-gpl \
--enable-version3 \
--disable-programs \
--disable-doc \
--disable-avdevice \
--disable-postproc \
--disable-avfilter \
--enable-dxva2 \
--enable-d3d11va
make -j$(nproc)
make installThis installs FFmpeg headers, libraries, and pkg-config files into:
C:\msys64\usr\local
Make sure MSYS2 can see the installed packages:
pkg-config --modversion libavformat libavcodec libavutilKainote requires FFMS2 functions that are not part of the stock public API.
If you replace Thirdparty/ffms2 with a fresh upstream checkout, apply the Kainote additions below.
Add the following declarations near the end of Thirdparty/ffms2/include/ffms.h, before the final #endif:
// Kainote functions
FFMS_API(const char*) FFMS_GetTrackName(FFMS_Indexer* Indexer, int Track);
FFMS_API(const char*) FFMS_GetTrackLanguage(FFMS_Indexer* Indexer, int Track);
typedef struct FFMS_Chapter {
const char* Title;
int64_t Start;
int64_t End;
} FFMS_Chapter;
typedef struct FFMS_Chapters {
FFMS_Chapter* Chapters;
int NumOfChapters;
} FFMS_Chapters;
FFMS_API(FFMS_Chapters*) FFMS_GetChapters(FFMS_Indexer* Indexer);
FFMS_API(void) FFMS_FreeChapters(FFMS_Chapters** Chapters);
typedef struct FFMS_Attachment {
const char* Filename;
const char* Mimetype;
const uint8_t* Data;
int DataSize;
} FFMS_Attachment;
FFMS_API(FFMS_Attachment*) FFMS_GetAttachment(FFMS_Indexer* Indexer, int Track);
FFMS_API(void) FFMS_FreeAttachment(FFMS_Attachment** Attachment);
typedef int (FFMS_CC* GetSubtitlesCallback)(int64_t Start, int64_t Duration, int64_t Total, const char* Line, void* ICPrivate);
FFMS_API(void) FFMS_GetSubtitles(FFMS_Indexer* Indexer, int Track, GetSubtitlesCallback IC, void* ICPrivate);
FFMS_API(const char*) FFMS_GetSubtitleExtradata(FFMS_Indexer* Indexer, int Track);
FFMS_API(const char*) FFMS_GetSubtitleFormat(FFMS_Indexer* Indexer, int Track);Add the following members to the end of the FFMS_Indexer class/struct declaration in the FFMS2 indexing header (Indexing/Indexing.h or src/core/indexing.h, depending on the FFMS2 version):
// Kainote functions
const char* GetTrackName(int Track);
const char* GetTrackLanguage(int Track);
FFMS_Chapters* GetChapters();
FFMS_Attachment* GetAttachment(int Track);
void GetSubtitles(int Track, GetSubtitlesCallback IC, void* ICPrivate);
const char* GetSubtitleExtradata(int Track);
const char* GetSubtitleFormat(int Track);Then build FFMS2 according to the FFMS2 build system you are using, making sure it links against the FFmpeg libraries built above. The resulting ffms2.lib must be available in one of the Visual Studio library directories used by Kainote.vcxproj.
- Open
Kainote.slnin Visual Studio 2022. - Select:
- Configuration:
Release - Platform:
x64
- Configuration:
- If Visual Studio cannot find SDKs or third-party headers/libraries, check:
Kainote/Kainote.vcxprojProject Properties > C/C++ > General > Additional Include DirectoriesProject Properties > Linker > General > Additional Library Directories
- Build the solution from Visual Studio, or from x64 Native Tools Command Prompt for VS 2022:
msbuild Kainote.sln /m /p:Configuration=Release /p:Platform=x64The executable is written under the repository's Visual Studio output folders, typically x64\Release or bin\x64\Release, depending on the active project configuration.
The Linux build uses CMake and system packages. It has been verified on an Ubuntu/Debian-style environment with GCC, wxGTK 3.2, Lua 5.1, FFMS2, FFmpeg, libass, Hunspell, uchardet, libcurl, ICU, Boost, GStreamer 1.x, and OpenGL development packages.
sudo apt update
sudo apt install --no-install-recommends -y \
build-essential \
cmake \
git \
pkg-config \
libwxgtk3.2-dev \
libwxgtk-gl3.2-dev \
libass-dev \
libffms2-dev \
liblua5.1-0-dev \
libhunspell-dev \
libuchardet-dev \
libcurl4-openssl-dev \
libicu-dev \
libboost-filesystem-dev \
libboost-locale-dev \
libboost-regex-dev \
libboost-system-dev \
libavformat-dev \
libavcodec-dev \
libavutil-dev \
libgl1-mesa-dev \
libgtk-3-dev \
libgstreamer1.0-dev \
libgstreamer-plugins-base1.0-dev \
gstreamer1.0-plugins-base \
gstreamer1.0-plugins-good \
gstreamer1.0-pulseaudioGStreamer backs both video and audio playback on Linux, so its runtime plugins
must be present, not just the -dev headers. The -base plugins provide
appsrc, audioconvert, audioresample and playbin; the -good plugins
provide autoaudiosink; and an audio sink such as gstreamer1.0-pulseaudio
(or gstreamer1.0-pipewire / gstreamer1.0-alsa) is needed to actually output
sound. Without these plugins the audio/video pipeline cannot be created.
Optional but useful for headless smoke tests:
sudo apt install --no-install-recommends -y xvfbThe exact package names vary by distribution. Install the equivalent development packages for:
- C and C++ compiler toolchain (
gcc,g++,make) - CMake
- pkg-config
- wxWidgets/wxGTK 3.x with core, base, adv, aui, html, xml, gl, and stc components
- libass
- FFMS2
- Lua 5.1 development headers and library
- Hunspell
- uchardet
- libcurl
- ICU (
icu-ucandicu-i18npkg-config modules) - Boost filesystem, locale, regex, and system
- FFmpeg development libraries: libavformat, libavcodec, libavutil
- OpenGL/Mesa development headers
- GTK 3 development headers
- GStreamer 1.x: the core (
gstreamer-1.0) plus the-baselibraries (gstreamer-app-1.0,gstreamer-audio-1.0,gstreamer-video-1.0), and at runtime the base and good plugin sets plus an audio sink (pulse/pipewire/alsa)
For Fedora-like systems, the package set is approximately:
sudo dnf install \
gcc gcc-c++ make cmake git pkgconf-pkg-config \
wxGTK-devel wxGTK-gl wxGTK-media \
libass-devel ffms2-devel lua-devel hunspell-devel uchardet-devel \
libcurl-devel libicu-devel boost-devel ffmpeg-devel mesa-libGL-devel gtk3-devel \
gstreamer1-devel gstreamer1-plugins-base-devel \
gstreamer1-plugins-base gstreamer1-plugins-goodFor Arch-like systems, the package set is approximately:
sudo pacman -S --needed \
base-devel cmake git pkgconf wxwidgets-gtk3 libass ffms2 lua51 \
hunspell uchardet curl icu boost ffmpeg mesa gtk3 \
gstreamer gst-plugins-base gst-plugins-goodIf your distribution only provides Lua 5.4 as lua, install the separate Lua 5.1 development package. The CMake file intentionally checks for lua5.1 because Kainote uses Lua 5.1 APIs such as lua_getfenv, lua_objlen, and luaL_register.
Before configuring Kainote, confirm that pkg-config can find the required libraries:
pkg-config --modversion \
libass \
ffms2 \
lua5.1 \
hunspell \
uchardet \
libcurl \
icu-uc \
icu-i18n \
libavformat \
libavcodec \
libavutil \
gstreamer-1.0 \
gstreamer-video-1.0 \
gstreamer-audio-1.0 \
gstreamer-app-1.0Also verify wxWidgets:
wx-config --version
wx-config --libs core,base,adv,aui,html,xml,gl,stcIf any command fails, install the missing -dev/-devel package or adjust PKG_CONFIG_PATH so that pkg-config can locate the corresponding .pc file.
cmake -S . -B build-linux -DCMAKE_BUILD_TYPE=Release
cmake --build build-linux -j$(nproc)The executable is created at:
build-linux/kainote
On a normal desktop session:
./build-linux/kainoteFor a headless smoke test, use Xvfb and a timeout:
timeout 8s xvfb-run -a ./build-linux/kainoteExit code 124 from the command above is expected when timeout stops an otherwise running GUI application after 8 seconds.
To rebuild incrementally:
cmake --build build-linux -j$(nproc)To force a clean reconfigure:
rm -rf build-linux
cmake -S . -B build-linux -DCMAKE_BUILD_TYPE=Release
cmake --build build-linux -j$(nproc)On Linux the build behaves the same as the Windows build except for the following.
Media backends (Windows uses DirectShow / DirectSound / Direct3D):
- General video playback uses GStreamer in place of DirectShow:
playbindecodes the file and anappsinkhands BGRA frames to the app, which composites the libass subtitles and progress bar and presents them through the shared wxWidgets paint path. The frame-accurate FFMS2 path used for typesetting, timing, and visual editing is unchanged. - Audio plays through GStreamer (
appsrc → audioconvert → audioresample → autoaudiosink); the playback position is tracked on a wall-clock model. There is no DirectSound path. - Because Linux builds may bundle a relocated
libgstreamer, the plugin search path is pinned at build time (pkg-config --variable=pluginsdir gstreamer-1.0) and exported beforegst_init, so the system GStreamer plugins are found at runtime. The base and good plugin sets (and an audio sink) must be installed.
Other Linux differences:
- Move-to-trash uses freedesktop
gio trash, so thegiotool (glib2) must be present at runtime; if it is missing, deleting a loaded video is a no-op instead of an unrecoverable hard delete. - The file-association
("Skojarzenia")options tab is not shown there is noxdg-mimebackend yet.
Under Wayland specifically (these work normally on X11):
- Cursor-anchored dialogs (colour picker, font/style/hotkey dialogs, etc.) open centred instead of at the pointer a Wayland client cannot position its own windows.
- "Fullscreen on a specific monitor" falls back to fullscreen on the current output.
- Auto-pause-on-minimize and the B-key minimize do nothing a Wayland client cannot minimize itself.
- The screen-pixel colour eyedropper is unavailable Wayland forbids reading pixels outside the app's own surface.
