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.0.tar.gz (98.0 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.0-py3-none-any.whl (65.9 kB view details)

Uploaded Python 3

File details

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

File metadata

  • Download URL: kfn2mp4-0.1.0.tar.gz
  • Upload date:
  • Size: 98.0 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.0.tar.gz
Algorithm Hash digest
SHA256 3dfdc554bb508637e346b9591e1f47d7593099f58bef1133b14349faa23af5bd
MD5 6313daa4854f529e2c4dcc5309557c1b
BLAKE2b-256 f15aff96a78c82ea8fe365a9a5f63c864f7f114e062416669f60681133a18abe

See more details on using hashes here.

Provenance

The following attestation bundles were made for kfn2mp4-0.1.0.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.0-py3-none-any.whl.

File metadata

  • Download URL: kfn2mp4-0.1.0-py3-none-any.whl
  • Upload date:
  • Size: 65.9 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.0-py3-none-any.whl
Algorithm Hash digest
SHA256 e4250675beba8b6a3589a35d9d6a39a4dade86f55ca4f891565c374177c3218d
MD5 c6bbe360d2220df215db94d47a693ac5
BLAKE2b-256 e70d0b5ac1e88c6a36893ddb4f8c87f356be5bc29445a6983105f58cff8c82d9

See more details on using hashes here.

Provenance

The following attestation bundles were made for kfn2mp4-0.1.0-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