{"id":17654260,"url":"https://github.com/pgaskin/spicy-kvm","last_synced_at":"2025-03-30T09:20:54.732Z","repository":{"id":251303487,"uuid":"818799663","full_name":"pgaskin/spicy-kvm","owner":"pgaskin","description":"Almost like a KVM switch, but using SPICE, a virtual machine, and a dedicated GPU with a regular monitor connected to both machines.","archived":false,"fork":false,"pushed_at":"2025-03-23T19:24:22.000Z","size":57,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-03-23T20:29:54.858Z","etag":null,"topics":["ddc","ddc-ci","evdev","kvm","pipewire","qemu-kvm","udev"],"latest_commit_sha":null,"homepage":"","language":"C","has_issues":false,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"gpl-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/pgaskin.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2024-06-22T22:49:44.000Z","updated_at":"2025-03-23T19:24:25.000Z","dependencies_parsed_at":"2025-03-23T20:24:02.721Z","dependency_job_id":"a68a61e2-1a2c-4216-bb49-6f3e37496d42","html_url":"https://github.com/pgaskin/spicy-kvm","commit_stats":null,"previous_names":["pgaskin/spicy-kvm"],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pgaskin%2Fspicy-kvm","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pgaskin%2Fspicy-kvm/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pgaskin%2Fspicy-kvm/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pgaskin%2Fspicy-kvm/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/pgaskin","download_url":"https://codeload.github.com/pgaskin/spicy-kvm/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":246297523,"owners_count":20754805,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["ddc","ddc-ci","evdev","kvm","pipewire","qemu-kvm","udev"],"created_at":"2024-10-23T12:09:14.908Z","updated_at":"2025-03-30T09:20:54.711Z","avatar_url":"https://github.com/pgaskin.png","language":"C","funding_links":[],"categories":[],"sub_categories":[],"readme":"# spicy-kvm\n\n\u003e [!NOTE]\n\u003e This tool is still a work-in-progress, and I mostly made this for my own specific use case. The configuration is currently hard-coded, logging is racy, error messages may be obscure, and the code is somewhat messy. Some nice-to-have features are also missing. Everything more or less works (I've been using this since early 2024), but for now, you'll need to modify the code. I am not accepting pull requests.\n\nAlmost like a KVM switch, but using SPICE, a virtual machine, and a dedicated GPU with a regular monitor connected to both machines.\n\nA tool to connect to GPU-passthrough virtual machines on the local network with a hotkey, forwarding input/audio over SPICE, and switching monitor outputs using DDC-CI.\n\nIt is designed for a very specific use case:\n\n- You require low-latency audio/video/input for a virtual machine\n  - Other remote desktop solutions like RealVNC or xfreerdp are simpler if you don't.\n- The virtual machine is on the same host or the local network.\n  - SPICE is TCP-based, and all input and audio is sent through it, so a bad network connection will result in severe performance issues.\n  - Audio is low-latency if the network is, but it is not directly synchronized with the video output, so if both the video and audio aren't low-latency, they may end up out of sync.\n- You are using GPU passthrough, and the machine is connected to a monitor (possibly the same one you're using for another machine -- you can use DDC-CI to automatically switch outputs).\n- You want to pass raw input from a physical evdev input device to the virtual machine without physically disconnecting it and/or want to be able to switch using a hotkey.\n- You want to use audio input/output from your client machine in the virtual machine simultaneously.\n- You want to be able to still use your client machine remotely or on other screens with other input devices while accessing the virtual machine.\n\nYou can think about it like:\n\n- Looking-glass, but for a VM on the local network.\n- A poor-man's KVM switch and audio mixer.\n- Moonlight/GameStream/virt-viewer, but with a real screen and lower latency.\n\nIf any of the above isn't true, you're better off:\n\n- Using SPICE directly with virt-viewer for local or local network VMs.\n- Using LookingGlass for local VMs with a dedicated GPU.\n- Using Moonlight/GameStream for gaming on a remote computer (the input and audio latency will be higher, but it's still generally usable).\n- Using RDP or VNC for general-purpose remote desktop access (RealVNC is very nice for remote desktop on Linux).\n\nThe audio buffering and device code is based on looking-glass.\n\n```\ndnf install cmake gcc g++ kernel-headers 'pkgconfig('{spice-protocol,samplerate,libpipewire-0.3,nettle,hogweed}')'\ncmake -B build -DCMAKE_EXPORT_COMPILE_COMMANDS=1 -GNinja\nninja -C build\n```\n\nEnsure SPICE is enable and exposed over TCP. VirtIO input devices are also required.\n\n\u003c!--\n```\nusage: spicy-kvm [options]\n\n --spice-host                   spice host\n --spice-port                   spice port\n --spice-password PASSWORD      spice password\n --spice-password-env           read PASSWORD as en environment variable name\n --spice-password-file          read PASSWORD as a file\n\n --activate                     automatically activate upon startup\n --oneshot                      exit after the first deactivation\n\n --on KEYCODE                   activate when the specified key is released (requires an input device to be specified)\n --off KEYCODE                  deactivate when the specified key is pressed (requires an input device to be specified)\n\n --record DEVICE                enable audio input from the specified pipewire device (empty for the default)\n --record-persistent            keep audio recording connected even when not active\n\n --playback DEVICE              enable audio output to the specified pipewire device (empty for the default)\n --playback-persistent          keep audio playback connected even when not active\n\n --input DEVICE                 enable keyboard/mouse input from the specified evdev device name, path, or number (can be specified multiple times)\n --input-auto                   watch all accessible evdev devices and enable keyboard/mouse input from the evdev device which pressed the activation key and the next pointing device to send an EV_REL event\n\n --ddc DEVICE                   use the i2c bus associated with the specified drm card name (including the \"card\" prefix) or i2c bus number for ddc-ci\n --ddc-vcp VCP,INACTIVE,ACTIVE  set the specified ddc-ci vcp when activating/deactivating (all values are hex) (can be repeated multiple times) (use `ddcutil capabilities` to figure out what can go here) (you can use this for automatically switching monitor inputs)\n```\n--\u003e\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpgaskin%2Fspicy-kvm","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fpgaskin%2Fspicy-kvm","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpgaskin%2Fspicy-kvm/lists"}