Skip to content

Latest commit

ย 

History

11 Commits

Folders and files

NameName
Last commit message
Last commit date
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 

Repository files navigation

pg-kvm

Turn an Android phone into an IP-KVM.

(pg stands for poor guys - for those of us who can't justify a few hundred dollars for a hardware IP-KVM but still have machines to babysit.)

English | ไธญๆ–‡

Hardware requirements

That's all the hardware you need - no dedicated KVM switch, no extra server:

  • ๐Ÿ“ท A UVC video capture card (HDMI-to-USB, the cheap kind works fine)
  • ๐Ÿ”ฒ An ESP32-S3 development board
  • ๐Ÿ“ฑ An Android phone

Use case

You have a home server sitting in a corner. Most of the time it just works - until one day it hangs, drops off the network, or needs a BIOS/UEFI tweak. Now you must physically connect a monitor and keyboard to debug it, and hauling a monitor over (finding one, finding the right cable, clearing desk space) is a pain. Again.

pg-kvm is for exactly that: leave a UVC capture card plugged into the server's HDMI port and an ESP32-S3 into a USB port, and the next time it acts up, just grab an android phone and open a browser, see the screen, and type.

What is this?

pg-kvm is a low-cost, software-only IP-KVM solution built around an ordinary Android phone:

  • A UVC USB camera (e.g. an HDMI capture card) captures the target computer's screen.
  • An Android app streams the video to any browser over WebRTC, with the signaling server embedded in the app itself - no external server needed.
  • Keyboard and mouse events from the browser are relayed over Bluetooth Low Energy (BLE) to an ESP32-S3 board, which replays them to the target PC as a wired USB HID keyboard and mouse.

The result: you can view and control a remote computer from a browser, as if its monitor, keyboard, and mouse were plugged in directly - with the target PC requiring zero software installation.

โš ๏ธ Status: the project is fully working but still being polished. Current end-to-end video latency is around 1 second, which is not yet ideal - optimization is ongoing.

                    โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
                    โ”‚ Browser โ”‚  (you)
                    โ””โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”˜
      video (WebRTC) โ–ฒ   โ”‚   โ–ผ input (WebSocket)
                    โ”Œโ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”
                    โ”‚ Android โ”‚
                    โ”‚   app   โ”‚
                    โ””โ”€โ”€โ–ฒโ”€โ”€โ”€โ–ฒโ”€โ”€โ”˜
 video (USB-OTG) โ–ฒ     โ”‚   โ”‚     โ–ผ input (BLE)
               โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜   โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
           โ”Œโ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”      โ”Œโ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”
           โ”‚   UVC    โ”‚      โ”‚ ESP32-S3 โ”‚
           โ”‚  camera  โ”‚      โ”‚ (bridge) โ”‚
           โ””โ”€โ”€โ”€โ”€โ–ฒโ”€โ”€โ”€โ”€โ”€โ”˜      โ””โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”˜
  video (HDMI)  โ”‚                  โ”‚ input (USB HID) โ–ผ
           โ”Œโ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”
           โ”‚         Target PC          โ”‚
           โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

Highlights

  • ๐Ÿ“น UVC camera capture via a bundled native libuvc - works with most USB capture cards and UVC webcams through USB-OTG.
  • ๐Ÿ“ก Video streaming over WebRTC, with the signaling server (WebSocket, port 3000) running inside the app.
  • โŒจ๏ธ ๐Ÿ–ฑ๏ธ Full remote input: a second WebSocket server (port 3001) receives keyboard/mouse events from the browser and forwards them over BLE to the ESP32-S3.
  • ๐ŸŒ Web frontend (Vue 3 + TypeScript) with i18n support - no client installation required.
  • ๐Ÿ”Œ Target PC stays untouched - input is injected as standard USB HID devices.

Repository structure

.
โ”œโ”€โ”€ pg-kvm-android/        # The Android app + web frontend
โ”‚   โ”œโ”€โ”€ app/               #   Main app: WebRTC streaming, signaling & input-relay servers, BLE
โ”‚   โ”œโ”€โ”€ libausbc/          #   UVC camera capture library (forked/derived from herhansen/libausbc)
โ”‚   โ”œโ”€โ”€ libuvc/            #   Native libuvc (JNI), with libjpeg-turbo and rapidjson
โ”‚   โ”œโ”€โ”€ libnative/         #   Additional native helpers
โ”‚   โ”œโ”€โ”€ frontend/          #   Vue 3 + TS + Vite web viewer/controller
โ”‚   โ””โ”€โ”€ ...
โ”œโ”€โ”€ pg-kvm-esp32s3-dummy/  # Placeholder describing the ESP32-S3 firmware (see below)
โ”œโ”€โ”€ LICENSE                # Apache 2.0
โ””โ”€โ”€ README.md

ESP32-S3 firmware

The ESP32-S3 side runs the open-source ESPRemoteControl firmware by KoStard. pg-kvm's Android app is protocol-compatible with it (BLE GATT, service 2D2A0001-8A5A-4E76-A2E3-1E57D9A1B001), and the firmware source is not bundled here - please download, compile, and flash it yourself. See pg-kvm-esp32s3-dummy/README.md for details.

Getting started

  1. Firmware: clone ESPRemoteControl, build it with PlatformIO, and flash it to an ESP32-S3 board (see its README).
  2. Android app: open pg-kvm-android/ in Android Studio and run it on your phone. Attach a UVC capture card / webcam via USB-OTG.
  3. Pair: in the app, connect to the KBBridge-ESP32S3 BLE device.
  4. Control: open the web page served by the app running on the phone in any browser on the same network, and start working on the remote PC.

Acknowledgements

License

Released under the Apache 2.0 License.


โญ Star this project

If pg-kvm saves you from buying an expensive hardware KVM, please consider giving this repository a Star - it helps others discover the project and keeps development going. Thank you! ๐Ÿ™


ไธญๆ–‡่ฏดๆ˜Ž

(pg ๅณ poor guys - ๆ‡‚็š„้ƒฝๆ‡‚)

็กฌไปถ่ฆๆฑ‚

ๆ‰€้œ€็š„ๅ…จ้ƒจ็กฌไปถๅฐฑ่ฟ™ไบ› - ๆ— ้œ€ไธ“็”จ KVM ๅˆ‡ๆขๅ™จ,ๆ— ้œ€้ขๅค–ๆœๅŠกๅ™จ:

  • ๐Ÿ“ท ไธ€ๅช UVC ่ง†้ข‘้‡‡้›†ๅก(HDMI ่ฝฌ USB,ไพฟๅฎœ็š„ๅณๅฏ)
  • ๐Ÿ”ฒ ไธ€ๅ— ESP32-S3 ๅผ€ๅ‘ๆฟ
  • ๐Ÿ“ฑ ไธ€ๅฐ ๅฎ‰ๅ“ๆ‰‹ๆœบ

ไฝฟ็”จๅœบๆ™ฏ

ๅฎถ้‡Œ่ง’่ฝ้‡Œ่บบ็€ไธ€ๅฐๆœๅŠกๅ™จใ€‚ๅคงๅคšๆ•ฐๆ—ถๅ€™ๅฎƒๅฎ‰้™ๅœฐ่ท‘็€ - ็›ดๅˆฐๆŸๅคฉๅฎƒๆŒ‚ไบ†ใ€ๆ–ญ็ฝ‘่ฟžไธไธŠไบ†,ๆˆ–่€…้œ€่ฆ่ฐƒ ๆ•ด BIOS/UEFIใ€‚่ฟ™ๆ—ถๅ€™ไฝ ๅฟ…้กปๆฌไธ€ๅฐๆ˜พ็คบๅ™จๅ’Œ้”ฎ็›˜่ฟ‡ๅŽป็‰ฉ็†่ฟžๆŽฅ่ฐƒ่ฏ•:ๆ‰พๆ˜พ็คบๅ™จใ€ๆ‰พๅฏน็บฟใ€่…พๆกŒ้ขโ€ฆโ€ฆ ๆฏๆฌก้ƒฝๅพˆๆŠ˜่…พใ€‚

pg-kvm ๆญฃๆ˜ฏไธบ่ฟ™็งๅœบๆ™ฏ่€Œ็”Ÿ:ๅœจๆœๅŠกๅ™จ็š„ HDMI ๅฃไธŠๅธธ้ฉปไธ€ๅช UVC ้‡‡้›†ๅก,USB ๅฃไธŠๆ’ไธ€ไธช ESP32-S3ใ€‚ ไธ‹ๆฌกๅฎƒๅ†็Šฏ็—…,ๆ‰พไธ€ๅฐๅฎ‰ๅ“ๆ‰‹ๆœบ่ฟžไธŠ,ๆ‰“ๅผ€ๆต่งˆๅ™จๅฐฑ่ƒฝ็œ‹ๅˆฐ็”ป้ขใ€็›ดๆŽฅๆ•ฒ้”ฎ็›˜ใ€‚

่ฟ™ๆ˜ฏไป€ไนˆ?

pg-kvm ๆ˜ฏไธ€ๅฅ—ๅ›ด็ป•ๆ™ฎ้€š Android ๆ‰‹ๆœบๆž„ๅปบ็š„ไฝŽๆˆๆœฌใ€็บฏ่ฝฏไปถ IP-KVM ๆ–นๆกˆ:

  • ้€š่ฟ‡ UVC USB ๆ‘„ๅƒๅคด(ๅฆ‚ HDMI ้‡‡้›†ๅก)้‡‡้›†็›ฎๆ ‡็”ต่„‘็š„็”ป้ข;
  • Android ๅบ”็”จ้€š่ฟ‡ WebRTC ๅฐ†็”ป้ขๆŽจ้€ๅˆฐไปปๆ„ๆต่งˆๅ™จ,ไฟกไปคๆœๅŠกๅ™จๅ†…็ฝฎไบŽๅบ”็”จๆœฌ่บซ,ๆ— ้œ€้ขๅค– ้ƒจ็ฝฒๆœๅŠก็ซฏ;
  • ๆต่งˆๅ™จ็ซฏ็š„้”ฎ็›˜ใ€้ผ ๆ ‡ไบ‹ไปถ็ป BLE(ไฝŽๅŠŸ่€—่“็‰™) ่ฝฌๅ‘ๅˆฐ ESP32-S3 ๅผ€ๅ‘ๆฟ,็”ฑๅฎƒไปฅๆœ‰็บฟ USB HID ้”ฎ้ผ ็š„ๅฝขๅผๆณจๅ…ฅ็›ฎๆ ‡็”ต่„‘ใ€‚

ๆ•ˆๆžœ็ญ‰ๅŒไบŽ:ไฝ ๅฏไปฅๅœจๆต่งˆๅ™จ้‡ŒๆŸฅ็œ‹ๅนถๆ“ๆŽง่ฟœ็จ‹็”ต่„‘,ๅฐฑๅƒๆ˜พ็คบๅ™จๅ’Œ้”ฎ้ผ ็›ดๆŽฅๆ’ๅœจไธŠ้ขไธ€ๆ ท - ็›ฎๆ ‡็”ต่„‘ ๆ— ้œ€ๅฎ‰่ฃ…ไปปไฝ•่ฝฏไปถใ€‚

โš ๏ธ ๅฝ“ๅ‰็Šถๆ€:้กน็›ฎๅทฒๅฏๅฎŒๆ•ดไฝฟ็”จ,ไฝ†ไปๅœจๆ‰“็ฃจไธญใ€‚็›ฎๅ‰็ซฏๅˆฐ็ซฏ่ง†้ข‘ๅปถ่ฟŸ็บฆ 1 ็ง’,ๅฐšไธ็†ๆƒณ, ไปๅœจๆŒ็ปญไผ˜ๅŒ–ใ€‚

                    โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
                    โ”‚  ๆต่งˆๅ™จ โ”‚  (ไฝ )
                    โ””โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”˜
      ่ง†้ข‘ (WebRTC) โ–ฒ    โ”‚    โ–ผ ่พ“ๅ…ฅ (WebSocket)
                    โ”Œโ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”
                    โ”‚ Android โ”‚
                    โ”‚   ๅบ”็”จ  โ”‚
                    โ””โ”€โ”€โ–ฒโ”€โ”€โ”€โ–ฒโ”€โ”€โ”˜
 ่ง†้ข‘ (USB-OTG) โ–ฒ      โ”‚   โ”‚      โ–ผ ่พ“ๅ…ฅ (BLE)
               โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜   โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
           โ”Œโ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”      โ”Œโ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”
           โ”‚   UVC    โ”‚      โ”‚ ESP32-S3 โ”‚
           โ”‚   ๆ‘„ๅƒๅคด โ”‚      โ”‚  (ๆกฅๆŽฅๅ™จ) โ”‚
           โ””โ”€โ”€โ”€โ”€โ–ฒโ”€โ”€โ”€โ”€โ”€โ”˜      โ””โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”˜
  ่ง†้ข‘ (HDMI)  โ”‚                   โ”‚ ่พ“ๅ…ฅ (USB HID) โ–ผ
           โ”Œโ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”
           โ”‚          ็›ฎๆ ‡ PC           โ”‚
           โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

็‰นๆ€ง

  • ๐Ÿ“น ๅŸบไบŽ native libuvc ็š„ UVC ๆ‘„ๅƒๅคด้‡‡้›†,้€š่ฟ‡ USB-OTG ๅ…ผๅฎนๅคงๅคšๆ•ฐ้‡‡้›†ๅกๅ’Œๆ‘„ๅƒๅคด;
  • ๐Ÿ“ก ๅŸบไบŽ WebRTC ็š„่ง†้ข‘ๆŽจๆต,ไฟกไปคๆœๅŠกๅ™จ(WebSocket,็ซฏๅฃ 3000)ๅ†…็ฝฎไบŽๅบ”็”จ;
  • โŒจ๏ธ ๐Ÿ–ฑ๏ธ ๅฎŒๆ•ด่ฟœ็จ‹่พ“ๅ…ฅ:็ฌฌไบŒไธช WebSocket ๆœๅŠกๅ™จ(็ซฏๅฃ 3001)ๆŽฅๆ”ถๆต่งˆๅ™จ้”ฎ้ผ ไบ‹ไปถๅนถ็ป BLE ่ฝฌๅ‘่‡ณ ESP32-S3;
  • ๐ŸŒ Web ๅ‰็ซฏ(Vue 3 + TypeScript),ๆ”ฏๆŒๅคš่ฏญ่จ€,ๅฎขๆˆท็ซฏๆ— ้œ€ๅฎ‰่ฃ…;
  • ๐Ÿ”Œ ็›ฎๆ ‡็”ต่„‘้›ถไพตๅ…ฅ - ่พ“ๅ…ฅไปฅๆ ‡ๅ‡† USB HID ่ฎพๅค‡ๆณจๅ…ฅใ€‚

ไป“ๅบ“็ป“ๆž„

.
โ”œโ”€โ”€ pg-kvm-android/        # Android ๅบ”็”จ + Web ๅ‰็ซฏ
โ”‚   โ”œโ”€โ”€ app/               #   ไธปๅบ”็”จ:WebRTC ๆŽจๆตใ€ไฟกไปคไธŽ่พ“ๅ…ฅไธญ็ปงๆœๅŠกๅ™จใ€BLE
โ”‚   โ”œโ”€โ”€ libausbc/          #   UVC ๆ‘„ๅƒๅคด้‡‡้›†ๅบ“(่ก็”Ÿ่‡ช herhansen/libausbc)
โ”‚   โ”œโ”€โ”€ libuvc/            #   Native libuvc(JNI),ๅซ libjpeg-turbo ไธŽ rapidjson
โ”‚   โ”œโ”€โ”€ libnative/         #   ๅ…ถไป– native ่พ…ๅŠฉไปฃ็ 
โ”‚   โ”œโ”€โ”€ frontend/          #   Vue 3 + TS + Vite ็ฝ‘้กตๆŸฅ็œ‹/ๆŽงๅˆถ็ซฏ
โ”‚   โ””โ”€โ”€ ...
โ”œโ”€โ”€ pg-kvm-esp32s3-dummy/  # ESP32-S3 ๅ›บไปถ่ฏดๆ˜Žๅ ไฝ็›ฎๅฝ•(่งไธ‹)
โ”œโ”€โ”€ LICENSE                # Apache 2.0
โ””โ”€โ”€ README.md

ESP32-S3 ๅ›บไปถ

ESP32-S3 ็ซฏ่ฟ่กŒ KoStard ็š„ๅผ€ๆบๅ›บไปถ ESPRemoteControlใ€‚ๆœฌ้กน็›ฎ็š„ Android ๅบ”็”จไธŽๅ…ถ ๅ่ฎฎๅ…ผๅฎน(BLE GATT,ๆœๅŠก UUID 2D2A0001-8A5A-4E76-A2E3-1E57D9A1B001),ๅ›บไปถๆบ็ ๅนถๆœช ๅŒ…ๅซๅœจๆœฌไป“ๅบ“ไธญ,่ฏท่‡ช่กŒไธ‹่ฝฝใ€็ผ–่ฏ‘ๅนถ็ƒงๅฝ•,่ฏฆ่ง pg-kvm-esp32s3-dummy/README.mdใ€‚

ๅฟซ้€ŸไธŠๆ‰‹

  1. ๅ›บไปถ:ๅ…‹้š† ESPRemoteControl,ไฝฟ็”จ PlatformIO ็ผ–่ฏ‘ๅนถ็ƒงๅฝ•ๅˆฐ ESP32-S3 ๅผ€ๅ‘ๆฟ(่ฏฆ่งๅ…ถ README);
  2. Android ๅบ”็”จ:็”จ Android Studio ๆ‰“ๅผ€ pg-kvm-android/ ๅนถ่ฟ่กŒๅˆฐๆ‰‹ๆœบ,้€š่ฟ‡ USB-OTG ๆŽฅๅ…ฅ UVC ้‡‡้›†ๅกๆˆ–ๆ‘„ๅƒๅคด;
  3. ้…ๅฏน:ๅœจๅบ”็”จไธญ่ฟžๆŽฅ KBBridge-ESP32S3 BLE ่ฎพๅค‡;
  4. ๆŽงๅˆถ:ๅœจๅŒไธ€็ฝ‘็ปœ็š„ไปปๆ„ๆต่งˆๅ™จไธญๆ‰“ๅผ€็”ฑ่ฟ่กŒๅœจๆ‰‹ๆœบไธŠ็š„ๆœๅŠกๅ™จๆไพ›็š„็ฝ‘้กต,ๅณๅฏๅผ€ๅง‹ๆ“ไฝœ ่ฟœ็จ‹็”ต่„‘ใ€‚

่‡ด่ฐข

  • Stream - Android ๅบ”็”จ่ก็”Ÿ่‡ชๅ…ถๅผ€ๆบ็คบไพ‹ webrtc-sample-compose(Apache 2.0);
  • KoStard - ESPRemoteControl(ESP32-S3 BLE->USB-HID ๆกฅๆŽฅ ๅ›บไปถ)็š„ไฝœ่€…;
  • herhansen/libausbc ไธŽไธŠๆธธ libuvc ้กน็›ฎ - Android ไธŠ็š„ UVC ๆ‘„ๅƒๅคด้‡‡้›†;
  • jiangdongguo/AndroidUSBCamera - ๆœฌ้กน็›ฎ libuvc ๆจกๅ—ๆ‰€ๅŸบไบŽ็š„ Android UVC ๆ‘„ๅƒๅคด้‡‡้›†ๅผ€ๆบ้กน็›ฎ;
  • WebRTCใ€Vueใ€NimBLE-Arduino ็ญ‰ๅผ€ๆบ็คพๅŒบใ€‚

่ฎธๅฏ่ฏ

ไปฅ Apache 2.0 ่ฎธๅฏ่ฏๅ‘ๅธƒใ€‚


โญ ๆฑ‚ไธช Star

ๅฆ‚ๆžœ pg-kvm ๅธฎไฝ ็œไธ‹ไบ†ไธ€ๅฐๆ˜‚่ดต็š„็กฌไปถ KVM,ๆฌข่ฟŽ็ป™ไป“ๅบ“็‚นไธช Star - ไฝ ็š„ๆ”ฏๆŒ่ƒฝ่ฎฉๆ›ดๅคšไบบๅ‘็Žฐ่ฟ™ไธช ้กน็›ฎ,ไนŸๆ˜ฏๆŒ็ปญๅผ€ๅ‘็š„ๅŠจๅŠ›ใ€‚่ฐข่ฐข!๐Ÿ™

About

Software IP-KVM on Android: stream a UVC camera over WebRTC and control the target machine via BLE HID (ESP32) from any browser.

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages