Skip to content

leriart/Mirai

Repository files navigation

Mirai

Miracast daemon and CLI for Linux — like Windows Win + K, but for your Wayland desktop.

License: GPL v2 or later

Mirai is a lightweight, headless Miracast controller for Linux. It exposes a plain JSON-over-Unix-socket API that any shell, widget, or status bar (such as Quickshell or Hyprland panels) can talk to.

  • Source mode — cast your Linux desktop to a Miracast sink (TV, dongle, another PC…) just like Windows does with Win + K.
  • Sink mode — make your Linux machine appear as a Miracast receiver, so you can mirror an Android / iOS / Windows device to it.
  • Display selection — pick the monitor or window to share.
  • Window / fullscreen — render the received stream the way you want.
  • Wayland & PipeWire native — works on Hyprland, Sway, KDE Plasma and any XDG Desktop Portal compatible compositor.

Mirai does not ship a full GUI. It is meant to be embedded: bind a key in Hyprland, build a Quickshell widget, or drive it from scripts.


Table of Contents


Overview

Feature Status Notes
Discover Miracast sinks MICE over mDNS/Avahi + NetworkManager P2P
Connect and cast screen Uses gnome-network-displays-stream (XDG Portal / PipeWire)
Receive Miracast stream Uses MiracleCast (miracle-wifid + miracle-sinkctl)
Render in window GStreamer / mpv
Render fullscreen mirai sink-mode fullscreen
Select monitor to share Through the XDG Desktop Portal dialog
Hyprland / Wayland / PipeWire Detects compositor and picks the right sink
Quickshell widget example See quickshell/Mirai.qml

How it works

┌─────────────┐      JSON / Unix socket      ┌──────────────┐
│  Hyprland   │◄────────────────────────────►│              │
│ Quickshell  │                              │  mirai       │
│    CLI      │                              │  daemon      │
└─────────────┘                              └──────┬───────┘
       │                                            │
       │           sink.py                          │      source.py
       │    ┌──────────────────────┐               │   ┌─────────────────────┐
       └───►│   miracle-wifid      │               └──►│  NetworkManager     │
            │   miracle-sinkctl    │                   │  Avahi discovery    │
            │   + GStreamer player │                   │  gnome-network-     │
            └──────────────────────┘                   │  displays-stream    │
                                                       └─────────────────────┘

The daemon is a single Python process. Clients send one-line JSON messages over a Unix socket and receive JSON replies. Events (sink found, connected, disconnected, etc.) are pushed to all connected clients.


Install

One-line installer

curl -fsSL https://raw.githubusercontent.com/Leriart/Mirai/main/install.sh | sh

The installer detects your distribution and installs dependencies when a known package manager is available. Supported: Arch / Manjaro, Debian / Ubuntu, Fedora, openSUSE, Alpine, Void, NixOS (via nix run), and generic fallback.

If you prefer a different prefix:

curl -fsSL https://raw.githubusercontent.com/Leriart/Mirai/main/install.sh | PREFIX=/usr/local sh

Manual install

git clone https://github.com/Leriart/Mirai.git
cd Mirai
sudo make install
# or
sudo ./install.sh

Dependencies

  • Python >= 3.10
  • dbus-python (usually python-dbus in distro packages)
  • wpa_supplicant with P2P support
  • miraclecast (miracle-wifid, miracle-sinkctl)
  • gstreamer (gst-launch-1.0, gst-inspect-1.0)
  • gnome-network-displays (for source / casting mode only)
  • NetworkManager and avahi (recommended for discovery)
  • mpv (optional alternative player)

NixOS

Add the flake input:

{
  inputs.mirai.url = "github:Leriart/Mirai";

  outputs = { self, nixpkgs, mirai, ... }: {
    nixosConfigurations.myhost = nixpkgs.lib.nixosSystem {
      modules = [
        mirai.nixosModules.default
        {
          services.mirai.enable = true;
          services.mirai.user = "myuser";
        }
      ];
    };
  };
}

Or run it imperatively:

nix run github:Leriart/Mirai

Usage

Start the daemon

Sink mode needs root privileges to manage Wi-Fi P2P.

# Foreground (useful for debugging)
sudo mirai daemon --foreground

# Background
sudo systemctl enable --now mirai

CLI quick reference

mirai status                 # show daemon state, displays and sinks
mirai displays               # list connected monitors
mirai logs                   # tail the daemon log

# Sink: receive a Miracast stream on this machine
mirai sink-start
mirai sink-mode window       # or fullscreen
mirai sink-stop

# Source: cast this machine to a Miracast sink
mirai source-scan            # discover sinks
mirai source-list            # show discovered sinks
mirai source-connect <id> --display HDMI-A-1
mirai source-disconnect

# Stop everything and quit
mirai stop
mirai quit

JSON socket API

Connect to /tmp/mirai.sock (or $MIRAI_SOCK) and send newline-delimited JSON. Example with socat:

printf '{"cmd":"status"}\n' | socat - UNIX-CONNECT:/tmp/mirai.sock

Supported commands:

Command Arguments Description
status Full state
displays List monitors
sink_start {link?: int} Start Miracast sink
sink_stop Stop sink
sink_mode {mode: "window" | "fullscreen"} Set render mode
source_scan {timeout?: int} Scan for sinks
source_connect {sink_id, display?} Connect to sink
source_connect_uri {uri, display?} Connect by URI
source_disconnect Disconnect source
stop_all Stop all sessions
quit Stop daemon

Events pushed by the daemon:

{"type": "source", "event": "sink_found", "data": {...}}
{"type": "sink",   "event": "connected",  "data": {...}}

Quickshell / Hyprland integration

A ready-to-use widget is in quickshell/Mirai.qml. To install it:

mkdir -p ~/.config/quickshell/mirai
ln -s /usr/share/mirai/quickshell/Mirai.qml ~/.config/quickshell/mirai/shell.qml
quickshell -c mirai

Example Hyprland key bindings:

bind = SUPER, K, exec, mirai source-scan
bind = SUPER SHIFT, K, exec, ~/.config/hypr/scripts/mirai-toggle.sh

A small helper script is included in scripts/mirai-toggle.sh.


Configuration

Configuration is mostly done through environment variables:

Variable Default Description
MIRAI_SOCK /tmp/mirai.sock Unix socket path
MIRAI_LOG /tmp/mirai.log Daemon log path
MIRAI_SINK_NAME Mirai Display Name shown to Miracast sources
MIRAI_SOURCE_NAME Mirai Name advertised when casting
MIRAI_SINK_PLAYER auto Player backend: gst, mpv, auto
GNOME_NETWORK_DISPLAYS_STREAM /usr/lib/gnome-network-displays-stream Path to GNOME source helper

Troubleshooting

sink-start fails with "must run as root"

MiracleCast needs root to create a P2P group owner. Run the daemon with sudo, pkexec, or the provided systemd service.

Source scan finds nothing

  • Make sure the TV/dongle is in Miracast / screen-mirroring mode.
  • Verify Avahi is running: systemctl status avahi-daemon.
  • On some hardware, MICE is supported but P2P discovery is not; Mirai lists both separately.

Video renders in a tiny window on Wayland

Use mirai sink-mode fullscreen, or set a geometry manually:

mirai sink-mode window  # default; drag/resize the window with your compositor

No audio in sink mode

Ensure your GStreamer setup includes AAC decoders:

gst-inspect-1.0 avdec_aac

PipeWire / portal issues

For source mode, Mirai relies on gnome-network-displays-stream, which uses xdg-desktop-portal. Make sure you have the portal implementation for your compositor installed, e.g.:

  • Hyprland: xdg-desktop-portal-hyprland
  • Sway: xdg-desktop-portal-wlr
  • KDE: xdg-desktop-portal-kde
  • GNOME: xdg-desktop-portal-gnome

Inspirations & references

Mirai stands on the shoulders of several open-source projects and public specifications:

  • MiracleCast — the original Linux implementation of Wi-Fi Display (Miracast) by David Herrmann, now maintained by Alberto Fanjul. Mirai wraps miracle-wifid and miracle-sinkctl for its sink mode.
  • GNOME Network Displays — provides the source streaming backend (gnome-network-displays-stream) used by Mirai to cast the desktop through PipeWire and the XDG Desktop Portal.
  • Wi-Fi Display Technical Specification v1.1 / v2.1 — the Miracast / Wi-Fi Display standard from the Wi-Fi Alliance.
  • Quickshell — the Qt/QML shell framework that inspired Mirai's socket-based, UI-agnostic design.
  • The Windows Win + K wireless display flow is the user-experience goal: discover, connect, and stream from a single shortcut.

License

Copyright (C) 2026 Leriart

Mirai is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. See LICENSE.

About

Miracast daemon and CLI for Linux — like Windows Win + K, but for your Wayland desktop

Topics

Resources

License

Contributing

Stars

0 stars

Watchers

0 watching

Forks

Releases

No releases published

Contributors