Skip to main content

Convert KaraFun KFN karaoke files to MP4 with synchronized lyrics

Project description

kfn2mp4

CI Release License: GPL-3.0-or-later Python 3.9+ Coverage ≥85%

Convert KFN karaoke files (the format used by the KaraFun player) into standalone MP4 videos with synchronized, highlighted lyrics.

It parses the KFN container, reads lyric timing and background from Song.ini, and renders with ffmpeg — a word-by-word wipe over the song's background and audio. CD+Graphics karaoke (.cdg + audio) converts too.

Why such tool

.kfn is a widely used file format for creating karaoke versions of songs, but it is only well supported by one application — KaraFun. The desktop player that plays local KFN files, KaraFun Player 2, is officially no longer updated, and the current KaraFun offering is built around its subscription streaming catalogue rather than local files.

There is no open format for karaoke songs — and more and more creators simply publish videos instead.

So rather than relying on the unknown future of KaraFun's local-file support, it seems better to convert KFN files to plain videos — MP4 — that play anywhere. And even better: to convert a whole library at once.

That's why this is here.

Requirements

  • Python 3.9+ (not needed for the standalone Windows .exe)
  • ffmpeg/ffprobe with libass, libx264 and AAC — verified up front (kfn2mp4 --check); found on PATH, via KFN2MP4_FFMPEG (a directory or the ffmpeg binary path), or next to the Windows .exe
  • fluidsynth + a General-MIDI soundfont — optional, only for MIDI-only files (KFN2MP4_SOUNDFONT overrides the auto-detected soundfont)

Install

pip install kfn2mp4            # from PyPI

Windows users can instead grab the standalone kfn2mp4.exe from the releases page (no Python needed; put ffmpeg.exe on PATH or next to the exe). From a checkout: pip install -e .

External tools on Windows

winget install Gyan.FFmpeg     # full build: includes libass, libx264, AAC

or download a build from gyan.dev and drop ffmpeg.exe + ffprobe.exe next to kfn2mp4.exe. For MIDI-only files, install FluidSynth and point KFN2MP4_SOUNDFONT at a General-MIDI .sf2 soundfont. Verify with kfn2mp4 --check.

Usage

kfn2mp4 "song.kfn" -o song.mp4                 # convert to a specific file
kfn2mp4 "song.kfn" -O out/                     # write "<song name>.mp4" into out/
kfn2mp4 *.kfn -O out/                          # convert many; re-runs skip finished files
kfn2mp4 *.kfn -O out/ --overwrite              # force re-render
kfn2mp4 "song.kfn" --extract-only out/         # just unpack audio/images/Song.ini
kfn2mp4 "song.kfn" -O out/ --file-colors       # use the KFN's own lyric colours
kfn2mp4 "song.kfn" -O out/ --duration 40 -v    # quick verbose preview (first 40s)

kfn2mp4 "song.cdg" -o song.mp4                 # CD+Graphics: pairs the sibling song.mp3
kfn2mp4 *.cdg -O out/                           # convert a folder of .cdg+.mp3 pairs
kfn2mp4 "song.cdg" --audio backing.mp3 -o s.mp4 # override the paired audio track

kfn2mp4 "song.kfn"                             # NO output given -> report the file
kfn2mp4 *.kfn                                  # ...report many files (like ffprobe)
kfn2mp4 "song.kfn" --json                      # ...as machine-readable JSON

kfn2mp4 *.kfn -o "{artist} - {title}.mp4"      # name outputs from KFN metadata
kfn2mp4 "song.kfn" -O out/ --sung-color "#00FF00"   # custom lyric colours
kfn2mp4 "song.kfn" -O out/ --logo brand.png    # watermark, bottom-left
kfn2mp4 "song.kfn" -O out/ --slots 3           # 3 on-screen lines (default: auto)
kfn2mp4 --check                                # verify ffmpeg & features (doctor)
kfn2mp4 "broken.kfn" --report                  # paste-ready diagnostic for a bug

Encoding is intentionally opinionated: a fixed 1280×720 canvas (background fitted, black bars as needed), crf 28, 25 fps, medium x264 preset. Lyrics use a brand palette over a translucent box (colour flags and --no-text-box override), in 2–3 slots auto-picked from the song's pace; duets get an accent colour for the second voice. The MP4 is tagged with the song's title/artist/album/year and a converted-by marker (comment tag):

ffprobe -v error -show_entries format_tags -of default=nw=1 song.mp4

Skipping already-converted files makes a re-run resume a batch cheaply. A progress bar shows per-file and batch progress on a terminal. Stopping a run (Ctrl-C or kill) removes the unfinished output and temp files. Globs like *.kfn work even on Windows shells.

How it works

  1. Parse the KFN container — KFNB binary (AES-128-ECB entries), old PK ZIP, or legacy KFN3 (chunked deflate).
  2. Read Song.ini into a syllable-level lyric timeline + style + background references.
  3. Generate an .ass subtitle with karaoke wipe (\kf) highlighting.
  4. Render background + lyrics + audio to MP4 with ffmpeg.

Supported formats

Signature Format Support
KFNB New KaraFun binary container (AES-128-ECB) full
PK Old KaraFun (plain ZIP) full
KFN3 Legacy KaraFun (chunked deflate) files with a readable body; see below
.cdg CD+Graphics stream + sibling audio (.mp3/.wav/…) full (graphics decoded by ffmpeg)
MIDI-only KFN .mid/.kar track, no MP3 synthesized via fluidsynth + GM soundfont

The KFNB container specification is in docs/kfn-format.md.

KFN3 (legacy container)

Read natively; files with an encrypted first chunk cannot be fully decoded (metadata is still reported, --extract-only salvages what validates). Details: docs/kfn3-format.md.

Status

Faithful-ish fidelity: image / video / slideshow background, embedded font, auto 2–3 line slot layout, smooth wipe highlighting, duet second voice, MIDI-only synthesis, CD+Graphics. Not yet: full KaraFun effect layers (trajectories, sprites, Milkdrop transitions) and encrypted-head KFN3 (above) — see the open issues.

Development

pip install -e .[dev]
pytest

The suite is built entirely from synthetic in-memory fixtures — no sample library is required, and no real (copyrighted) .kfn file is ever needed to run or pass the tests.

Legal & disclaimer

This project is an independent, unofficial tool for format interoperability. It is not affiliated with, endorsed by, or connected to KaraFun or Recisio; "KaraFun" is a trademark of its respective owners.

kfn2mp4 only reads a container format so you can convert files you already have for personal use. It ships no copyrighted content. The musical recordings, lyrics, and artwork inside a KFN file remain the property of their rights holders — do not use this tool to redistribute copyrighted material.

License

Released under the GNU General Public License v3.0 or later — see LICENSE.

Acknowledgements

Reverse-engineering of the KFN formats built on prior open work:

  • UlduzSoft blog — the reverse-engineering series (header, directory, Song.ini, encryption): the authoritative narrative.
  • WinslowJosiahunlock_kfn gist (Python): the cleanest read/decrypt reference (AES-128-ECB with the FLID key).
  • gyunaev/spivakSpivak (C++/Qt): a production karaoke player; lyricsparser_kfn.cpp is the reference for the Sync/Text merge + tokenization.
  • MadLord80/KFN_ViewerKFN_Viewer (C#): a GUI viewer/extractor with the richest field table and an extended-LRC export.
  • mazsibazsi/kfn-rskfn-rs (Rust): the best-modeled [Eff#] effects/animation layer.

Croonify convinced the author that MP4 is the proper format for karaoke.

This project was written with the help of AI tools — the code, tests, and documentation were developed with Anthropic's Claude (Claude Code).

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

kfn2mp4-0.1.1.tar.gz (98.6 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

kfn2mp4-0.1.1-py3-none-any.whl (66.2 kB view details)

Uploaded Python 3

File details

Details for the file kfn2mp4-0.1.1.tar.gz.

File metadata

  • Download URL: kfn2mp4-0.1.1.tar.gz
  • Upload date:
  • Size: 98.6 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.14

File hashes

Hashes for kfn2mp4-0.1.1.tar.gz
Algorithm Hash digest
SHA256 cac27102edbaaefd38d2b69453f7439bc974047f65adc680d4db9f7ebd2c2ef3
MD5 5b3a40641c3178acbd8673dcf642ec5f
BLAKE2b-256 3a62b450d3f13185d173057811df5ea7eb52b8e533ebe4c8020a1457fac2a091

See more details on using hashes here.

Provenance

The following attestation bundles were made for kfn2mp4-0.1.1.tar.gz:

Publisher: release.yml on lukenowak/kfn2mp4

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file kfn2mp4-0.1.1-py3-none-any.whl.

File metadata

  • Download URL: kfn2mp4-0.1.1-py3-none-any.whl
  • Upload date:
  • Size: 66.2 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.14

File hashes

Hashes for kfn2mp4-0.1.1-py3-none-any.whl
Algorithm Hash digest
SHA256 230637bcb9ede52cdc546c6a2f98a98cf1da91cde7b55e66956ddccc5683e2ce
MD5 bb1a49a5441af70cd72208fdeae5b792
BLAKE2b-256 c72008ef48905f4d3523e3f51124cdbf388b00560f5218b3d4956946090765e3

See more details on using hashes here.

Provenance

The following attestation bundles were made for kfn2mp4-0.1.1-py3-none-any.whl:

Publisher: release.yml on lukenowak/kfn2mp4

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page