跳转至内容
  • 版块
  • 最新
  • 标签
  • 热门
  • 用户
  • 群组
皮肤
  • 浅色
  • Brite
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • 深色
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • 默认(不使用皮肤)
  • 不使用皮肤
折叠
品牌标识

抡锤者

  1. 主页
  2. AI硬件
  3. # 🎬 用ESP32-S3实施廉价KVM-over-IP — 完整折腾报告

# 🎬 用ESP32-S3实施廉价KVM-over-IP — 完整折腾报告

已定时 已固定 已锁定 已移动 AI硬件
9 帖子 5 发布者 226 浏览
  • 从旧到新
  • 从新到旧
  • 最多赞同
回复
  • 在新帖中回复
登录后回复
此主题已被删除。只有拥有主题管理权限的用户可以查看。
  • A 离线
    A 离线
    abaalei
    技术大牛 劳动模范
    编写于 最后由 abaalei 编辑
    #1

    项目仓库: https://github.com/peterhon168/esp32-kvm-webcontrol
    源项目: KMChris/esp32-kvm-ip
    日期: 2026-06-18


    第一部分:技术报告

    一、缘起:为什么要做这个?

    远程管理服务器通常需要:

    • iDRAC/iLO/iBMC — 企业级方案,贵,老主板没有(我手上另一块超微的X10-Dai也一样没有)
    • PiKVM — 好方案,但树莓派被炒到天价,而且HDMI转CSI模块也不便宜
    • 串口/SSH — 能敲命令,但看不到BIOS、看不到启动过程、装系统抓瞎

    目标:用 ESP32-S3(¥25)+ USB HDMI采集卡(¥25) 实现一个能看画面、能键鼠操作的远程KVM(供货商为PDD)。

    二、硬件清单 & 成本

    组件 型号 成本 说明
    主控 ESP32-S3 N16R8 ~¥25 双核240MHz,USB OTG,WiFi
    采集卡 MS2103 USB HDMI (345f:2130) ~¥25 USB 3.0,支持1080p@30 MJPEG
    目标机 X99双路工作站 已有 被控机器,HDMI+USB接入
    宿主主机 TrueNAS SCALE / Ubuntu VM 已有 跑流服务+网桥

    总硬件增量成本: ¥80(相比PiKVM动辄¥500+)

    三、系统架构

    ┌───────────────┐   HDMI    ┌──────────────────┐
    │  目标机        │──────────→│ USB 2103 采集卡   │
    │  (X99 工作站)  │           │ (MS2103芯片)      │
    │               │   USB     │                   │
    │               │──────────→│   ESP32-S3        │
    └───────────────┘           │   (HID注入)       │
                                └────────┬─────────┘
                                         │ WiFi UDP :4210
                                         ▼
    ┌────────────────────────────────────────────────────┐
    │              网络层                                 │
    ├────────────────────────────────────────────────────┤
    │  KVM网桥 (Python): WebSocket ←→ UDP 转换           │
    │  视频流: ffmpeg → Python MJPEG HTTP Server :8000    │
    │  Web UI: http://kvm-bridge-ip:18088                 │
    └────────────────────────────────────────────────────┘
    

    数据流

    浏览器 ←WebSocket JSON→ KVM网桥 ←UDP 16字节包→ ESP32-S3 ←USB HID→ 目标机
    浏览器 ←HTTP MJPEG──→ MJPEG流服务器 ←pipe── ffmpeg ←v4l2── 采集卡 ←HDMI── 目标机
    

    延迟实测

    环节 延迟
    视频采集 → 串流 ~33ms (30fps)
    网络传输 <1ms (局域网)
    鼠标键盘注入 ~5ms (UDP→ESP32→USB)
    端到端画面延迟 ~100-150ms (不含显示器)

    四、ESP32-S3 固件

    4.1 固件修改(vs 源项目)

    源项目 KMChris/esp32-kvm-ip 原本设计是一个Windows客户端通过UDP直连ESP32,需要Windows跑一个hook程序捕获键鼠。我们改成了:

    1. WiFi修复:认证模式 WIFI_AUTH_WPA2_WPA3_PSK → WIFI_AUTH_WPA2_PSK
      • 原因:sdkconfig没开WPA3,连WiFi永远失败
    2. 重连逻辑修复:把事件回调内的 vTaskDelay 改为独立 reconnect_task
      • 原因:WiFi事件循环内阻塞导致后续事件无法处理
    3. UDP协议不变:16字节固定包格式,兼容原始协议

    4.2 编译烧录

    # 在Windows ESP-IDF环境
    idf.py build flash monitor
    # OTG口接目标机USB,UART口接电脑(可以同时插)
    

    4.3 ESP32 IP分配

    ESP32连WiFi后通过DHCP获取IP。在我们的网络里分配到 192.168.0.209。

    五、USB HDMI采集卡 — MS2103 深坑记录

    5.1 芯片识别

    ID 345f:2130 MACROSILICON OCap Video
    UVC 1.00, USB 3.0 SuperSpeed
    支持格式:
      Raw:    YUYV 4:2:2 最高 3840×2160
      MJPEG:  Motion-JPEG 最高 3840×2160
    

    5.2 血泪坑:v4l2不兼容

    这个MS2103芯片是出了名的奇葩——标准v4l2 ioctl全都不吃:

    • VIDIOC_S_FMT → Inappropriate ioctl for device
    • VIDIOC_G_FMT → 同上
    • VIDIOC_REQBUFS → 同上
    • VIDIOC_STREAMON → 同上
    • 直接 read() → Invalid argument

    市面上唯一能驱动它的只有 ffmpeg(内置了MS210x的workaround)。

    5.3 最终方案

    # 下载静态ffmpeg二进制(John Van Sickle编译版)
    wget https://johnvansickle.com/ffmpeg/releases/ffmpeg-release-amd64-static.tar.xz
    tar -xf ffmpeg-release-amd64-static.tar.xz
    
    # 捕获MJPEG帧并通过Python服务推流
    ffmpeg -f v4l2 -input_format mjpeg -video_size 1920x1080 -framerate 30 \
      -i /dev/video0 -f image2pipe -vcodec copy - | python3 mjpeg_server.py
    

    Python MJPEG服务器用纯标准库(http.server + queue + threading),不需要装任何第三方包。

    六、宿主机的选择折腾

    6.1 尝试路线

    (Hermes Agent的宿主机truenas,ubuntu是.240,没有给他授权root权限,所以下面报了一堆错)

    路线 结果 原因
    直接插240 Ubuntu VM ❌ 不行 VM没有物理USB口
    TrueNAS USB Passthrough到240 ❌ 热插不生效 需要重启VM,但Hermes网关在240上不能断
    TrueNAS直接装uStreamer(apt) ❌ 封锁 TrueNAS策略禁用包管理器
    TrueNAS Docker ❌ 封锁 dockerd需要root
    TrueNAS Python原生流服务 ✅ 成功 /var/tmp可写、有Python3.11+PIL、无noexec
    ffmpeg静态二进制跑在TrueNAS ✅ 成功 下载到/var/tmp,可执行
    TrueNAS Init Script开机自启 ✅ 成功 midclt call initshutdownscript.create

    6.2 架构决策

    采集卡最终插在 TrueNAS (192.168.0.160) 上,因为:

    • TrueNAS 有 USB 3.0 口
    • 采集卡通过 VM USB Passthrough 热添加不成功(其实是成功的,全过程没有重启宿主机及VM)nid
    • TrueNAS 的 /var 是 ZFS 数据集(非 tmpfs),文件重启不丢
    • Python3.11 + PIL 可用
    • /var/tmp 没挂 noexec

    6.3 开机自启配置(TrueNAS Init Script)

    midclt call initshutdownscript.create '{
      "type": "SCRIPT",
      "script": "/var/tmp/mjpeg_server.py",
      "when": "POSTINIT",
      "enabled": true,
      "timeout": 60
    }'
    

    七、KVM网桥

    7.1 kvm_bridge 架构

    # server.py — 核心逻辑
    # 1. WebSocket服务器 → 接收浏览器键鼠事件(JSON)
    # 2. UDP客户端 → 转发给ESP32(16字节二进制包)
    # 3. HTTP服务器 → 提供Web UI + 配置API
    
    # 配置 config.env
    ESP_IP=192.168.0.209        # ESP32 IP
    ESP_PORT=4210                # ESP32 UDP端口
    WS_PORT=18765                # WebSocket端口
    HTTP_PORT=18088              # Web UI端口
    USTREAMER_URL=http://192.168.0.160:8000/stream  # MJPEG视频流
    

    7.2 Web UI 特性

    • 单页面HTML + CSS + JS(无框架依赖)
    • WebSocket自动重连
    • 鼠标 Pointer Lock API(按Alt+L切换锁定/解锁)
    • BIOS兼容(相对坐标模式)
    • 视频流iframe内嵌uStreamer画面
    • 连通性检测(ESP32在线→绿,离线→黄色警告)

    7.3 PM2进程管理

    pm2 start server.py --name kvm-bridge
    pm2 save
    

    八、完整搭建步骤(从零开始)

    Step 1: 硬件连接

    目标机HDMI → 采集卡 → 宿主机USB
    目标机USB  → ESP32-S3 OTG口
    ESP32-S3 UART口 → 电脑(烧录用,运行时不用)
    

    Step 2: 烧录ESP32固件

    # Windows + ESP-IDF
    idf.py build flash monitor
    # 记下ESP32的IP(从路由器DHCP表查)
    

    Step 3: 宿主机上部署流服务

    # 如果是Ubuntu(最简单)
    apt install ustreamer
    ustreamer -d /dev/video0 -m MJPEG -p 8000 -r 1920x1080
    
    # 如果是TrueNAS(需要折腾)
    # 下载ffmpeg静态二进制 + Python MJPEG服务器脚本
    # 部署到 /var/tmp/,配Init Script开机自启
    

    Step 4: 部署KVM网桥

    # 任何有Python3的机器
    pip3 install websockets
    cp config.env.example config.env
    # 编辑 config.env 填入ESP32 IP和流URL
    python3 server.py
    
    # 或通过PM2守护
    pm2 start server.py --name kvm-bridge
    

    Step 5: 打开浏览器

    http://<bridge-ip>:18088
    → 点击「连接」建立WebSocket
    → 点击「加载」显示视频流
    → 点击视频区域 → 锁定鼠标 → 开始操作
    

    九、避坑总结

    ┌─────────────────────────────────────────────────────────────┐
    │ 🕳️ 坑1: MS2103采集卡标准v4l2 ioctl不能用                   │
    │    ✅ 解决: 只能用ffmpeg(有内置workaround)                 │
    │                                                             │
    │ 🕳️ 坑2: TrueNAS是"安全加固"系统                            │
    │    ✅ 解决: apt/Docker都被锁,用静态二进制+Python纯std库    │
    │                                                             │
    │ 🕳️ 坑3: TrueNAS默认不许跑二进制(noexec)                    │
    │    ✅ 解决: /var/tmp 没有noexec,放那                      │
    │                                                             │
    │ 🕳️ 坑4: VM USB热插不生效                                   │
    │    ✅ 解决: 既然Hermes在VM上不能重启,物理机直插跑服务      │
    │                                                             │
    │ 🕳️ 坑5: ESP32连不上WiFi                                    │
    │    ✅ 解决: 固件认证改 WPA2_PSK,重连改独立task             │
    │                                                             │
    │ 🕳️ 坑6: ESP32断线后不自动重连                              │
    │    ✅ 解决: 事件回调内vTaskDelay阻塞 → 独立reconnect_task   │
    └─────────────────────────────────────────────────────────────┘
    

    项目地址: https://github.com/peterhon168/esp32-kvm-webcontrol
    参考: https://github.com/KMChris/esp32-kvm-ip
    采集卡问题参考: https://www.mjt.me.uk/posts/fixing-missing-macrosilicon-ms2109/

    c8e2170e-2cd4-4d69-a2cb-d17862727432-image.jpeg
    4db94f99-dabd-4091-9857-b62d5f934b5b-image.jpeg

    1 条回复 最后回复
    4
    • CS6C 离线
      CS6C 离线
      CS6
      技术大牛 劳动模范
      编写于 最后由 编辑
      #2

      大佬請收下我膝蓋,我偷懶直接買了 IPKVM

      A 1 条回复 最后回复
      0
      • ,terryT terry 固定了此主题
      • CS6C CS6

        大佬請收下我膝蓋,我偷懶直接買了 IPKVM

        A 离线
        A 离线
        abaalei
        技术大牛 劳动模范
        编写于 最后由 编辑
        #3

        @CS6 不用不用,我也是在youtube看到有博主提了一嘴(在一条评测10元?20元?显卡的那里),然后跟gemini讨论,获得了操作建议,然后找kiro对源仓库代码进行修改,然后最终实施部署就给hermes进行

        1 条回复 最后回复
        0
        • F 离线
          F 离线
          fly86
          编写于 最后由 编辑
          #4

          牛逼,S3这么强

          A 1 条回复 最后回复
          0
          • F fly86

            牛逼,S3这么强

            A 离线
            A 离线
            abaalei
            技术大牛 劳动模范
            编写于 最后由 编辑
            #5

            @fly86 没有,S3在这套系统内就只作为虚拟键盘使用,就是因为它的性能不够,才需要调用truenas中闲置的性能来推流,不过我这都是穷折腾罢了

            F 1 条回复 最后回复
            0
            • A abaalei

              @fly86 没有,S3在这套系统内就只作为虚拟键盘使用,就是因为它的性能不够,才需要调用truenas中闲置的性能来推流,不过我这都是穷折腾罢了

              F 离线
              F 离线
              fly86
              编写于 最后由 编辑
              #6

              @abaalei 很利害了

              1 条回复 最后回复
              0
              • ,系统 取消固定了此主题
              • Capri SwicordC 离线
                Capri SwicordC 离线
                Capri Swicord
                编写于 最后由 编辑
                #7

                牛逼,建议整个套件挂淘宝,多一个选择

                A 1 条回复 最后回复
                0
                • H 离线
                  H 离线
                  hyaska
                  编写于 最后由 编辑
                  #8

                  666,像我这种不愿意折腾的,买维谛的av3108,加上vga适配器

                  1 条回复 最后回复
                  0
                  • Capri SwicordC Capri Swicord

                    牛逼,建议整个套件挂淘宝,多一个选择

                    A 离线
                    A 离线
                    abaalei
                    技术大牛 劳动模范
                    编写于 最后由 编辑
                    #9

                    @Capri-Swicord 哈哈,这个可以有!

                    1 条回复 最后回复
                    0

                    你好!看起来您对这段对话很感兴趣,但您还没有一个账号。

                    厌倦了每次访问都刷到同样的帖子?您注册账号后,您每次返回时都能精准定位到您上次浏览的位置,并可选择接收新回复通知(通过邮件或推送通知)。您还能收藏书签、为帖子顶,向社区成员表达您的欣赏。

                    有了你的建议,这篇帖子会更精彩哦 💗

                    注册 登录
                    回复
                    • 在新帖中回复
                    登录后回复
                    • 从旧到新
                    • 从新到旧
                    • 最多赞同


                    • 登录

                    • 没有帐号? 注册

                    • 第一个帖子
                      最后一个帖子
                    0
                    • 版块
                    • 最新
                    • 标签
                    • 热门
                    • 用户
                    • 群组