Compare commits

...

11 Commits

Author SHA1 Message Date
mofeng-git
da84a6d09f feat: 为 Onecloud Pro、Octopus-Planet 添加 DRM 设备支持(HDMI 环出模拟) 2025-10-12 15:26:43 +08:00
SilentWind
9c35c68eda fix: 修复 kvmd 访问硬件加速设备的权限规则 2025-10-12 09:22:26 +08:00
mofeng-git
651f9a4f4e feat: 更新演示站点地址 2025-10-11 15:43:04 +08:00
mofeng-git
7777f5e490 feat: 更新说明文档 2025-10-11 11:21:47 +08:00
mofeng-git
3ab5e2b431 fix: 修复 OEC TURBO 硬件编解码权限问题 2025-10-01 07:42:08 +08:00
mofeng-git
65874c6b43 fix: 修复 docker 版本VNC 服务权限问题 2025-09-30 23:53:35 +08:00
mofeng-git
67b943c151 fix: 修复 dnsmasq 软件包启动问题,解决引入的 DNS 解析 BUG 2025-09-30 23:53:28 +08:00
mofeng-git
593de19df5 fix: 更新网页部分文本 2025-09-30 21:32:35 +08:00
SilentWind
5296e61281 fix 2025-09-30 13:08:03 +08:00
mofeng-git
1729badc55 feat: 一些新功能和修复
1.启用初步 DRM 显示支持
2.预装 gostc 内网穿透
3.修复 systemd.journal 缺失问题
2025-09-29 21:18:41 +08:00
mofeng-git
9373790f37 feat: 更新设备配置和服务依赖
- 在 devices.sh 中启用 rc-local.service,以确保 kvmd 服务的正常运行
- 更新 ustreamer 配置,修正音频设备参数
- 修改 kvmd.service 文件,添加对 rc-local.service 的依赖
2025-09-28 23:43:04 +08:00
18 changed files with 179 additions and 41 deletions

View File

@@ -11,8 +11,8 @@
[![GitHub license](https://img.shields.io/github/license/mofeng-git/One-KVM)](https://github.com/mofeng-git/One-KVM/blob/master/LICENSE)
<p>
<a href="https://one-kvm.mofeng.run">📖 详细文档</a>
<a href="https://kvmd-demo.mofeng.run">🚀 在线演示</a>
<a href="https://docs.one-kvm.cn">📖 详细文档</a>
<a href="https://demo.one-kvm.cn/">🚀 在线演示</a>
<a href="#快速开始">⚡ 快速开始</a>
<a href="#功能介绍">📊 功能介绍</a>
</p>
@@ -68,7 +68,7 @@
|:--------:|:-------:|:-----:|:------:|:------:|
| 简体中文 WebUI | ✅ | ❌ | ✅ | ✅ |
| 远程视频流 | MJPEG/H.264 | MJPEG/H.264 | MJPEG/H.264 | MJPEG/H.264 |
| H.264 视频编码 | CPU | GPU | 未知 | GPU |
| H.264 视频编码 | CPU/GPU | GPU | 未知 | GPU |
| 远程音频流 | ✅ | ✅ | ✅ | ✅ |
| 远程鼠键控制 | OTG/CH9329 | OTG/CH9329/Pico/Bluetooth | OTG | OTG |
| VNC 控制 | ✅ | ✅ | ✅ | ✅ |
@@ -87,7 +87,7 @@ Docker 版本支持 OTG 或 CH9329 作为虚拟 HID兼容 amd64、arm64、arm
#### 一键脚本部署
```bash
curl -sSL https://one-kvm.mofeng.run/quick_start.sh -o quick_start.sh && bash quick_start.sh
curl -sSL https://docs.one-kvm.cn/quick_start.sh -o quick_start.sh && bash quick_start.sh
```
#### 手动部署
@@ -157,6 +157,7 @@ sudo docker run --name kvmd -itd \
- **GitHub Releases** [https://github.com/mofeng-git/One-KVM/releases](https://github.com/mofeng-git/One-KVM/releases)
**其他下载方式:**
- **免登录高速下载:** [http://sd1.files.one-kvm.cn/](http://sd1.files.one-kvm.cn/)(由群友赞助,支持直链,接入 EdgeOne CDN建议使用多线程下载工具下载获取最高速度
- **免登录下载:** [https://pan.huang1111.cn/s/mxkx3T1](https://pan.huang1111.cn/s/mxkx3T1) (由 Huang1111公益计划 提供)
- **百度网盘:** [https://pan.baidu.com/s/166-2Y8PBF4SbHXFkGmFJYg?pwd=o9aj](https://pan.baidu.com/s/166-2Y8PBF4SbHXFkGmFJYg?pwd=o9aj) 提取码o9aj
@@ -170,19 +171,7 @@ sudo docker run --name kvmd -itd \
| Virtualbox | Virtualbox-uefi | USB 采集卡、CH9329 | 241004 | ✅ |
| s905l3a 通用包 | E900v22c | USB 采集卡、OTG | 241004 | ✅ |
| 我家云 | Chainedbox | USB 采集卡、OTG | 241004 | ✅ |
| 龙芯久久派 | 2k0300 | USB 采集卡、CH9329 | 241025 | |
## 🤝 贡献指南
欢迎各种形式的贡献!
### 如何贡献
1. **Fork 本仓库**
2. **创建功能分支:** `git checkout -b feature/AmazingFeature`
3. **提交更改:** `git commit -m 'Add some AmazingFeature'`
4. **推送到分支:** `git push origin feature/AmazingFeature`
5. **提交 Pull Request**
| 龙芯久久派 | 2k0300 | USB 采集卡、CH9329 | 241025 | |
### 报告问题
@@ -280,6 +269,30 @@ sudo docker run --name kvmd -itd \
- 爱发电用户_e3202
- 一语念白
- 云边
- 爱发电用户_5a711
- 爱发电用户_9a706
- T0m9ir1SUKI
- 爱发电用户_56d52
- 爱发电用户_3N6F
- DUSK
- 飘零
- .
- 饭太稀
-
- ......
</details>
@@ -296,6 +309,14 @@ sudo docker run --name kvmd -itd \
**文件存储服务:**
- **[Huang1111公益计划](https://pan.huang1111.cn/s/mxkx3T1)** - 提供免登录下载服务
**云服务商**
- **[林枫云](https://www.dkdun.cn)** - 赞助了本项目宁波大带宽服务器
![林枫云](./img/36076FEFF0898A80EBD5756D28F4076C.png)
林枫云主营国内外地域的精品线路业务服务器、高主频游戏服务器和大带宽服务器。
## 📚 其他
### 使用的开源项目

View File

@@ -87,6 +87,18 @@ RUN sed -i 's/deb.debian.org/mirrors.tuna.tsinghua.edu.cn/' /etc/apt/sources.lis
fi \
&& curl https://github.com/tsl0922/ttyd/releases/download/1.7.7/ttyd.$ARCH -L -o /usr/local/bin/ttyd \
&& chmod +x /usr/local/bin/ttyd \
&& mkdir -p /tmp/gostc && cd /tmp/gostc \
&& case ${TARGETARCH} in \
amd64) GOSTC_ARCH=amd64_v1 ;; \
arm) GOSTC_ARCH=arm_7 ;; \
arm64) GOSTC_ARCH=arm64_v8.0 ;; \
*) echo "Unsupported architecture for gostc: ${TARGETARCH}" && exit 1 ;; \
esac \
&& curl -L https://github.com/mofeng-git/gostc-open/releases/download/v2.0.8-beta.2/gostc_linux_${GOSTC_ARCH}.tar.gz -o gostc.tar.gz \
&& tar -xzf gostc.tar.gz \
&& mv gostc /usr/bin/ \
&& chmod +x /usr/bin/gostc \
&& cd / && rm -rf /tmp/gostc \
&& adduser kvmd --gecos "" --disabled-password \
&& ln -sf /usr/share/tesseract-ocr/*/tessdata /usr/share/tessdata \
&& mkdir -p /etc/kvmd_backup/override.d \
@@ -98,6 +110,8 @@ RUN sed -i 's/deb.debian.org/mirrors.tuna.tsinghua.edu.cn/' /etc/apt/sources.lis
/run/kvmd \
/tmp/kvmd-nginx \
&& touch /run/kvmd/ustreamer.sock \
&& groupadd kvmd-selfauth \
&& usermod -a -G kvmd-selfauth root \
&& apt clean \
&& rm -rf /var/lib/apt/lists/* \
&& rm -rf /tmp/lib /tmp/wheel \

View File

@@ -162,9 +162,9 @@ RUN if [ ${TARGETARCH} = arm64 ]; then \
RUN sed --in-place --expression 's|^#include "refcount.h"$|#include "../refcount.h"|g' /usr/include/janus/plugins/plugin.h \
&& git clone --depth=1 https://github.com/mofeng-git/ustreamer /tmp/ustreamer \
&& if [ ${TARGETARCH} = arm64 ]; then \
make -j$(nproc) WITH_PYTHON=1 WITH_JANUS=1 WITH_FFMPEG=1 WITH_MPP=1 -C /tmp/ustreamer; \
make -j$(nproc) WITH_PYTHON=1 WITH_JANUS=1 WITH_FFMPEG=1 WITH_MPP=1 WITH_DRM=1 -C /tmp/ustreamer; \
else \
make -j$(nproc) WITH_PYTHON=1 WITH_JANUS=1 WITH_FFMPEG=1 -C /tmp/ustreamer; \
make -j$(nproc) WITH_PYTHON=1 WITH_JANUS=1 WITH_FFMPEG=1 WITH_DRM=1 -C /tmp/ustreamer; \
fi \
&& /tmp/ustreamer/ustreamer -v \
&& /tmp/ustreamer/ustreamer-dump -v \

View File

@@ -331,6 +331,9 @@ config_octopus_flanet_files() {
download_file_if_missing "$config_file" || echo "警告:下载 Octopus-Planet 配置文件失败"
sudo cp "$config_file" "$ROOTFS/etc/model_database.conf" || echo "警告:复制 model_database.conf 失败"
echo "信息:为 Octopus-Planet 添加 DRM 设备支持..."
run_in_chroot "sed -i \"/--device=\\/dev\\/video0/a\\ - \\\"--drm-device=/dev/dri/card0\\\"\" /etc/kvmd/override.yaml"
}
config_orangepi_zero_files() {
@@ -344,7 +347,18 @@ config_orangepi_zero_files() {
config_onecloud_pro_files() {
echo "信息:配置 Onecloud Pro 特定文件..."
echo "信息Onecloud Pro 特定配置完成。"
echo "信息:为 Onecloud Pro 添加 DRM 设备支持..."
run_in_chroot "sed -i \"/--device=\\/dev\\/video0/a\\ - \\\"--drm-device=/dev/dri/card0\\\"\" /etc/kvmd/override.yaml"
}
config_onecloud_files() {
echo "信息:配置 Onecloud 特定文件..."
echo "信息:为 Onecloud 添加 DRM 设备支持..."
run_in_chroot "sed -i \"/--device=\\/dev\\/video0/a\\ - \\\"--drm-device=/dev/dri/card1\\\"\" /etc/kvmd/override.yaml"
echo "信息Onecloud 特定配置完成。"
}
oec_turbo_rootfs() {
@@ -374,14 +388,25 @@ config_oec_turbo_files() {
echo "信息:配置 VPU 硬件编码支持..."
run_in_chroot "sed -i 's/--h264-hwenc=disabled/--h264-hwenc=rkmpp/g' /etc/kvmd/override.yaml"
# 配置 rc.local 自启脚本,添加设备权限设置
echo "信息:配置 rc.local 自启脚本..."
run_in_chroot "cat > /etc/rc.local << 'EOF'
#!/bin/bash
chmod 777 /dev/mpp_service /dev/rga
exit 0
echo "信息:配置 udev 规则以授权 kvmd 组访问硬件设备..."
run_in_chroot "cat > /etc/udev/rules.d/99-kvmd-hw-access.rules <<'EOF'
# Generic hardware access for kvmd
# Safe on all platforms — rules only apply if device exists
# Rockchip MPP (rkmpp)
KERNEL==\"mpp_service\", GROUP=\"kvmd\", MODE=\"0660\"
# DMA-Heap (used by modern MPP)
SUBSYSTEM==\"dma_heap\", KERNEL==\"system\", GROUP=\"kvmd\", MODE=\"0660\"
SUBSYSTEM==\"dma_heap\", KERNEL==\"system-uncached\", GROUP=\"kvmd\", MODE=\"0660\"
SUBSYSTEM==\"dma_heap\", KERNEL==\"reserved\", GROUP=\"kvmd\", MODE=\"0660\"
# Optional legacy Rockchip devices
KERNEL==\"rkvdec\", GROUP=\"kvmd\", MODE=\"0660\"
KERNEL==\"rkvenc\", GROUP=\"kvmd\", MODE=\"0660\"
KERNEL==\"rga\", GROUP=\"kvmd\", MODE=\"0660\"
EOF"
run_in_chroot "chmod +x /etc/rc.local"
# 替换 DTB 文件
replace_oec_turbo_dtb

View File

@@ -110,7 +110,7 @@ install_base_packages() {
iptables network-manager curl kmod libmicrohttpd12 libjansson4 libssl3 \\
libsofia-sip-ua0 libglib2.0-0 libopus0 libogg0 libcurl4 libconfig9 \\
python3-pip net-tools libavcodec59 libavformat59 libavutil57 libswscale6 \\
libavfilter8 libavdevice59 v4l-utils libv4l-0 nano unzip dnsmasq && \\
libavfilter8 libavdevice59 v4l-utils libv4l-0 nano unzip dnsmasq python3-systemd && \\
apt clean && \\
rm -rf /var/lib/apt/lists/*
"
@@ -194,7 +194,9 @@ configure_system() {
sed -i 's/8080/80/g' /etc/kvmd/override.yaml && \\
sed -i 's/4430/443/g' /etc/kvmd/override.yaml && \\
chown kvmd -R /var/lib/kvmd/msd/ && \\
systemctl enable dnsmasq kvmd kvmd-otg kvmd-nginx kvmd-vnc kvmd-ipmi kvmd-webterm kvmd-janus kvmd-media && \\
rm /etc/resolv.conf && \\
printf '%s\\n' 'nameserver 1.1.1.1' 'nameserver 1.0.0.1' > /etc/resolv.conf && \
systemctl enable dnsmasq kvmd kvmd-otg kvmd-nginx kvmd-vnc kvmd-ipmi kvmd-webterm kvmd-janus kvmd-media kvmd-gostc && \\
systemctl disable nginx systemd-resolved && \\
rm -rf /One-KVM
"
@@ -221,6 +223,54 @@ install_webterm() {
"
}
install_gostc() {
local arch="$1" # armhf, aarch64, x86_64
local gostc_arch="$arch"
local gostc_version="v2.0.8-beta.2"
# 根据架构映射下载文件名
case "$arch" in
armhf) gostc_arch="arm_7" ;;
aarch64) gostc_arch="arm64_v8.0" ;;
x86_64|amd64) gostc_arch="amd64_v1" ;;
*) echo "错误:不支持的架构 $arch"; exit 1 ;;
esac
echo "信息:在 chroot 环境中下载并安装 gostc ($gostc_arch)..."
run_in_chroot "
mkdir -p /tmp/gostc && cd /tmp/gostc && \\
curl -L https://github.com/mofeng-git/gostc-open/releases/download/${gostc_version}/gostc_linux_${gostc_arch}.tar.gz -o gostc.tar.gz && \\
tar -xzf gostc.tar.gz && \\
mv gostc /usr/bin/ && \\
chmod +x /usr/bin/gostc && \\
cd / && rm -rf /tmp/gostc
"
echo "信息:创建 gostc systemd 服务文件..."
run_in_chroot "
cat > /etc/systemd/system/kvmd-gostc.service << 'EOF'
[Unit]
Description=基于FRP开发的内网穿透 客户端/节点
ConditionFileIsExecutable=/usr/bin/gostc
After=network.target
[Service]
StartLimitInterval=5
StartLimitBurst=10
ExecStart=/usr/bin/gostc \"-web-addr\" \"0.0.0.0:18080\"
WorkingDirectory=/usr/bin
Restart=always
RestartSec=10
EnvironmentFile=-/etc/sysconfig/gostc
[Install]
WantedBy=multi-user.target
EOF
"
echo "信息gostc 安装和配置完成"
}
apply_kvmd_tweaks() {
local arch="$1" # armhf, aarch64, x86_64
local device_type="$2" # "gpio" or "video1" or other
@@ -283,6 +333,8 @@ apply_kvmd_tweaks() {
fi
fi
echo "信息KVMD 配置调整完成。"
run_in_chroot "apt remove -y --purge systemd-resolved"
}
# --- 整体安装流程 ---
@@ -324,6 +376,7 @@ install_and_configure_kvmd() {
configure_network "$network_type"
install_python_deps
configure_kvmd_core
install_gostc "$arch" # 安装 gostc
configure_system
install_webterm "$arch" # 传递原始架构名给ttyd下载
apply_kvmd_tweaks "$arch" "$device_type"

View File

@@ -2,6 +2,6 @@ video: {
sink = "kvmd::ustreamer::h264"
}
acap: {
device = "hw:0"
device = "hw:0,0"
tc358743 = "/dev/video0"
}

View File

@@ -53,6 +53,17 @@ stdout_logfile=/dev/stdout
stdout_logfile_maxbytes = 0
redirect_stderr=true
[program:kvmd-gostc]
command=/usr/bin/gostc -web-addr 0.0.0.0:18080
autostart=true
autorestart=true
startsecs=5
priority=300
stopasgroup=true
stdout_logfile=/dev/stdout
stdout_logfile_maxbytes = 0
redirect_stderr=true
[program:clean_when_exit]
command=/etc/kvmd/clean_when_exit.sh
autostart=true

View File

@@ -6,4 +6,4 @@
#
# NEVER use the same passwords for KVMD, IPMI and VNCAuth users.
admin
admin -> admin:admin

View File

@@ -1,6 +1,6 @@
[Unit]
Description=One-KVM - The main daemon
After=network.target network-online.target nss-lookup.target
After=network.target network-online.target nss-lookup.target rc-local.service
[Service]
User=kvmd

View File

@@ -0,0 +1,6 @@
name: GOSTC
description: GOSTC Server
icon: share/svg/gostc.svg
path: extras/gostc
daemon: kvmd-gostc
place: 11

View File

@@ -0,0 +1,7 @@
location /extras/gostc {
proxy_pass http://127.0.0.1:18080;
include /etc/kvmd/nginx/loc-proxy.conf;
include /etc/kvmd/nginx/loc-websocket.conf;
include /etc/kvmd/nginx/loc-login.conf;
include /etc/kvmd/nginx/loc-nocache.conf;
}

View File

@@ -657,7 +657,7 @@
</div>
</td>
<td>&nbsp;</td>
<td>Writable:
<td i18n="msd-rw-switch">Writable:
</td>
<td align="right">
<div class="switch-box">

View File

@@ -103,10 +103,10 @@ function __showKvmdInfo(info) {
if (info.meta !== null && info.meta.server && info.meta.server.host) {
$("kvmd-meta-server-host").innerText = info.meta.server.host;
document.title = `${info.meta.server.host} | PiKVM Index`;
document.title = `${info.meta.server.host} | One-KVM Index`;
} else {
$("kvmd-meta-server-host").innerHTML = "<i>Invalid meta</i>";
document.title = "PiKVM Index";
document.title = "One-KVM Index";
}
}

View File

@@ -118,7 +118,7 @@ export function Keyboard(__recordWsEvent) {
}
} else {
if (is_captured) {
title = "Keyboard captured, PiKVM offline";
title = "Keyboard captured, One-KVM offline";
}
}
$("hid-keyboard-led").className = led;

View File

@@ -169,7 +169,7 @@ export function Mouse(__getGeometry, __recordWsEvent) {
}
} else {
if (is_captured) {
title = "Mouse captured, PiKVM offline";
title = "Mouse captured, One-KVM offline";
}
}
$("hid-mouse-led").className = led;

View File

@@ -46,7 +46,7 @@ export function Streamer() {
var __init__ = function() {
__streamer = new MjpegStreamer(__setActive, __setInactive, __setInfo, __organizeHook);
$("stream-led").title = "No stream from PiKVM";
$("stream-led").title = "No stream from One-KVM";
tools.slider.setParams($("stream-quality-slider"), 5, 100, 5, 80, function(value) {
$("stream-quality-value").innerText = `${value}%`;
@@ -289,7 +289,7 @@ export function Streamer() {
var __setInactive = function() {
$("stream-led").className = "led-gray";
$("stream-led").title = "No stream from PiKVM";
$("stream-led").title = "No stream from One-KVM";
};
var __setControlsEnabled = function(enabled) {
@@ -317,7 +317,7 @@ export function Streamer() {
if (text.length > 0) {
title += text;
} else {
title += "No stream from PiKVM";
title += "No stream from One-KVM";
}
}
el_grab.innerText = el_info.innerText = title;

View File

@@ -166,7 +166,7 @@ export function MediaStreamer(__setActive, __setInactive, __setInfo, __organizeH
var __setupCodec = function(formats) {
__closeDecoder();
if (formats.h264 === undefined) {
let msg = "No H.264 stream available on PiKVM";
let msg = "No H.264 stream available on One-KVM";
__setInfo(false, false, msg);
__logInfo(msg);
return;

1
web/share/svg/gostc.svg Normal file

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 30 KiB