# PiKaraoke turns a Raspberry Pi into a KTV box with a QR code for the queue

> PiKaraoke is a Flask and Socket.IO karaoke server that plays YouTube videos and local files, gives guests a mobile remote through a scanned QR code, shifts pitch live, and scores singers at random. It installs with one curl command, runs on Raspberry Pi, macOS, Windows and Linux, and is MIT licensed.

**vicwomg/pikaraoke** — Youtube-based Karaoke KTV system for Raspberry Pi, OSX, Windows, and Linux

- Repository: https://github.com/vicwomg/pikaraoke
- Stars: 929 · Forks: 261
- Language: Python
- License: not declared
- Published: 2026-10-20 · Updated: 2026-10-20 · Language: en
- Canonical page: https://hysenlabs.com/projects/vicwomg-pikaraoke

## A karaoke server with a browser player and a phone as the remote

PiKaraoke is a cross-platform karaoke server that brings the professional KTV experience to your home. It transforms your computer or Raspberry Pi into a dedicated karaoke station with a full-screen player and an instant web interface.

The guest experience is the interesting part of the design. Guests join by scanning a QR code, with no app downloads required, and from there they can browse the local library, manage the queue, and access countless karaoke hits from YouTube.

That splits the system into two halves that can be different devices. The player is a dedicated full-screen view meant for the screen everyone watches, and it can be opened on any web browser for a karaoke room feel. The remote is a phone. The README lists an Instant Mobile Remote, where you search and queue songs from any smartphone, just scan and sing.

Two more pieces round out the feature list. There is Live Pitch Shifting, to adjust the key of any song to match your vocal range, and an Admin Control that manages the queue and settings through a password-protected admin mode.

Session Management records every night automatically, so you can browse the play history and see which songs and performers topped the charts.

And then there is the scoring system, which the README describes as hyper-accurate vocal performance scoring, followed in the same parenthesis by the correction that it is not really, it is random, but kind of fun. That is a good sign about the rest of the documentation, and it is also a real limitation you need to plan for.

## The install script pulls uv, ffmpeg and deno for you

There are several routes in, and the quick one is a single shell pipeline.

```bash
curl -fsSL https://raw.githubusercontent.com/vicwomg/pikaraoke/master/build_scripts/install/install.sh | bash
```

That command is described as a one-step installation that handles all dependencies, uv, ffmpeg and deno, and installs PiKaraoke. On Windows there is an installer executable, PiKaraoke-<version>-setup.exe, downloaded from the latest release, which adds Start Menu and desktop shortcuts. The README warns that Windows shows a blue Windows protected your PC screen because the installer is unsigned, and tells you to click More info then Run anyway. There is also a PowerShell form.

```bash
irm https://raw.githubusercontent.com/vicwomg/pikaraoke/master/build_scripts/install/install.ps1 | iex
```

To uninstall on Windows, the README says to swap install.ps1 for uninstall.ps1, and the normal route is Settings then Apps.

The manual route is for advanced users, and it lists the prerequisites: a modern web browser with Chrome, Chromium or Edge recommended, Python 3.10 or greater, FFmpeg preferably a build with lib-rubberband for transposing, and a JavaScript runtime installed on your PATH, with Node.js most common and Deno described as probably easiest for non-developers.

The package install itself is one command.

```bash
uv tool install pikaraoke
```

The README says you may alternately use the standard python pip install pikaraoke installer if you are familiar with virtual environments or not concerned with global package isolation.

## Running it: headed by default, headless for an external screen

The command line entry point is the package script pikaraoke, mapped to pikaraoke.app:main in the project metadata.

```bash
pikaraoke
```

Running it launches the player in headed mode via your default browser. You then scan the QR code to connect the mobile remotes. For an external browser or a dedicated display, the README documents a headless flag.

```bash
pikaraoke --headless
```

That runs it as a background server for external browsers. The help command, pikaraoke --help, lists the available options.

Upgrading is a separate uv command.

```bash
uv tool upgrade pikaraoke
```

The README also says re-running the quick install command will update a previous pikaraoke installation to the latest version, so you have two update paths depending on how you installed.

The supported platforms are listed plainly: OSX, Windows, Linux, and Raspberry Pi 4 or higher, with a note that a Pi3 works ok with overclocking. The project description in the package metadata says the same set, and the classifiers cover video, sound and audio, and games and entertainment.

Two details from the metadata are worth noticing because they explain the design. The dependency list includes flask-socketio with a comment in the file explaining that version 5.6.1 stops assigning to Flask 3.1.3's read-only session. That is the kind of comment that saves an afternoon. And gevent appears alongside flask-socketio, which is how the server handles many concurrent sockets.

The scoring being random is a small but real constraint on how you can use it in a party with people who care about winning.

## Docker needs a port, a LAN address and two volumes

The container route is documented with an explicit command rather than a compose file, and the README lists what you have to get right.

```bash
docker run -p 5555:5555 \
  -e TZ=Europe/London \
  -v ~/pikaraoke-songs:/app/pikaraoke-songs \
  -v ~/.pikaraoke:/home/pikaraoke/.pikaraoke \
  vicwomg/pikaraoke:latest \
  -u http://<YOUR_LAN_IP>:5555
```

Three things in there matter. The port mapping is 5555 on both sides, and the -u argument tells the app the public origin it should build links against, which has to be the LAN IP of the host, not localhost, because the phones on the wifi need to reach it. The TZ environment variable sets the timezone, taken from the TZ identifier column of the tz database list.

The two volumes are the songs directory and the settings directory under ~/.pikaraoke. Without them the container is stateless and you lose your library and configuration on every restart.

Running under a path prefix is documented too. You add --base-path /your-path and set -u to the public origin, for example --base-path /karaoke -u https://example.com, and PiKaraoke generates links under /karaoke automatically. The README then notes the catch for reverse proxy setups: the proxy must forward both HTTP and WebSocket traffic for that path to PiKaraoke. That detail is the whole difference between a working path-prefix deployment and a broken one, and path-based nginx-proxy setups typically also need VIRTUAL_PATH=/karaoke with VIRTUAL_DEST=/.

For more information and a configurable docker-compose example, the README points at the official Dockerhub repo at hub.docker.com/r/vicwomg/pikaraoke.

## The Flask stack, yt-dlp, and a JS runtime in the path

The dependency list in pyproject.toml is the honest description of how the system works.

Flask and Flask-Smorest provide the web layer, with flask-paginate for the song browsing pages and Babel plus Flask-Babel for translation. qrcode with the png extra generates the QR code the phones scan. psutil reads process and system information, requests handles outbound HTTP, ffmpeg-python drives FFmpeg for the audio and video processing, and yt-dlp with the default extra is what pulls from YouTube.

Then there are the two dependencies that explain the rest of the setup. flask-socketio provides the live connection between the player and the remotes, so a song queued on a phone appears on the screen without a page reload, and gevent is the concurrency layer underneath it.

The JavaScript runtime in the prerequisites list is there for the frontend, which is why the install script handles deno and the manual instructions ask for Node.js or Deno on the PATH.

The build backend is hatchling, the package is a wheel built from the pikaraoke directory, and the project requires Python 3.10 or greater, matching the prerequisite list in the README. The repository carries a uv.lock, so a uv based install resolves to pinned versions.

There is also a dependency group for translations with deep-translator and polib, which tells you the UI is localised and that translation files are maintained as a separate workflow rather than by hand-editing strings.

## What PiKaraoke is not, and where it stops working

Two limits are stated and one is implied.

The stated limit is scoring. The vocal performance score is random. Any party format built around a leaderboard, a prize for the best singer, or a competitive round is not going to work with it, and the README is honest about that rather than implying the scoring is meaningful. The play history and charts are real, though, since those come from the recorded sessions rather than from the score.

The second stated limit is hardware. Raspberry Pi 4 or higher is the supported board, with a Pi3 described as working ok with overclocking. Pitch shifting also depends on the FFmpeg build, and the README asks for one preferably built with lib-rubberband. An FFmpeg without that feature means the key change either does not work or is done in a way that costs quality.

The implied limit is the YouTube dependency. Songs come from YouTube through yt-dlp, so the machine running the server needs network access to it, and a party venue with poor internet has a smaller library than the README's feature list implies. Local files are the fallback, which is why the songs volume is a first-class mount in the Docker command.

There is also the practical limit of an unsigned Windows installer. Windows shows the blue protection screen and you have to click through it, which is fine on your own machine and a problem on a shared or managed one.

Finally, the pitch shifting, the QR pairing and the local library are separate features from the scoring, and it is worth being clear that PiKaraoke is a party application rather than a general media server. If you want a video player with a remote control, this is more than you need.

## MIT licensed, actively released, and asking for coffee money

The licence field on the repository is not one the platform could classify, but the project states its terms directly in the README, which says the project is independently maintained and free for everyone to enjoy.

Looking at the repository root, there is a LICENSE file, so the terms are readable there. The project description calls it free, and the funding route is a buy me a coffee link for the maintainer, who asks for help to keep the project alive and growing.

Maintenance is straightforward. The repository is not archived, and the last push was on 2026-10-19. The release list shows 1.23.0 on 2026-08-28, 1.22.0 on 2026-08-20 and 1.21.0 on 2026-07-21, and the project metadata version field reads 1.23.0, so the tagged releases and the package version agree.

Two things in the repository indicate a conventional release process rather than ad hoc tagging. There is a .release-please-manifest.json and a release-please-config.json at the root, which is the configuration for automated releases driven by conventional commits, and the README carries a Conventional Commits 1.0.0 badge. So the commit messages drive the version numbers.

Development practice is documented rather than implied. The README says contributions are welcome and points at development.md for setup, tests and the PR conventions, and the pyproject.toml carries dev dependency groups with pytest, pytest-cov, pylint and pre-commit, plus a translations group and a pyright configuration.

The plugin and tooling structure is visible in the top level listing, with build_scripts/ holding the installers, code_quality/ for the linting setup, docs/, scripts/, tests/ and the pikaraoke package itself.

## Conclusion

Adopt PiKaraoke if you want a karaoke station that plays YouTube and your own files, with guests controlling the queue from their phones and no app to install, and if you have a spare machine or a Raspberry Pi 4 to run it on. Do not adopt it if the scoring has to mean something, because the README says the vocal performance score is not really accurate and is random, or if you need a vendor-supported product, since it is an independently maintained free project. Before you set it up, install an FFmpeg build with lib-rubberband if you want pitch shifting to work properly, and check that you can reach YouTube from the machine that will run it.

## FAQ

### How do I install PiKaraoke on Linux or macOS?

Run the quick install pipeline, curl -fsSL on the install.sh script piped to bash, which handles the dependencies uv, ffmpeg and deno and installs PiKaraoke. For a manual install the README recommends uv tool install pikaraoke.

### Which devices does PiKaraoke support?

The README lists OSX, Windows, Linux, and Raspberry Pi 4 or higher, noting that a Pi3 works ok with overclocking. Python 3.10 or greater is required.

### How do guests join a PiKaraoke session?

They scan the QR code that appears in the player, which opens an instant mobile remote in any browser with no app download. From there they browse the library and manage the queue.

### Does PiKaraoke really score singers accurately?

No. The README describes the vocal performance scoring as not really accurate, that it is random, but kind of fun. The play history and the charts of top songs and performers come from the recorded sessions instead.

### What does the PiKaraoke Docker command need besides the port mapping?

It needs a -u argument with the public origin, such as http://<YOUR_LAN_IP>:5555, a TZ environment variable for the timezone, and two volume mounts, one for the songs directory and one for the settings under ~/.pikaraoke.

### How do I run PiKaraoke behind a reverse proxy under a path prefix?

Add the base path option, for example --base-path /karaoke, and set -u to the public origin. PiKaraoke generates links under that path automatically, but the proxy must forward both HTTP and WebSocket traffic for it, and path-based nginx-proxy setups also need VIRTUAL_PATH and VIRTUAL_DEST.

## Sources

- [Issues](https://github.com/vicwomg/pikaraoke/issues)
- [README](https://github.com/vicwomg/pikaraoke/blob/master/README.md)
- [Releases](https://github.com/vicwomg/pikaraoke/releases)
- [vicwomg/pikaraoke on GitHub](https://github.com/vicwomg/pikaraoke)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/vicwomg-pikaraoke
