更新 README - 添加 Rust 编译指南和 Python/Rust 对比
This commit is contained in:
244
README.md
244
README.md
@@ -4,6 +4,8 @@
|
|||||||
|
|
||||||
面向32台终端的内网低延迟屏幕广播系统,支持网络投屏、硬件接口互通、一键自动化运维。
|
面向32台终端的内网低延迟屏幕广播系统,支持网络投屏、硬件接口互通、一键自动化运维。
|
||||||
|
|
||||||
|
本项目提供 **Python (PySide6)** 和 **Rust (egui)** 两个版本的投屏控制客户端。
|
||||||
|
|
||||||
## 需求说明
|
## 需求说明
|
||||||
|
|
||||||
当前会议投屏需求涉及通过视频矩阵系统向32台终端设备进行同步投屏。具体模式可分为以下两类:
|
当前会议投屏需求涉及通过视频矩阵系统向32台终端设备进行同步投屏。具体模式可分为以下两类:
|
||||||
@@ -18,6 +20,17 @@
|
|||||||
|
|
||||||
参考文档:<https://docs.qq.com/doc/DQXFpdHN5Rk9yRGpC>
|
参考文档:<https://docs.qq.com/doc/DQXFpdHN5Rk9yRGpC>
|
||||||
|
|
||||||
|
## 客户端版本对比
|
||||||
|
|
||||||
|
| 特性 | Python (PySide6) | Rust (egui) |
|
||||||
|
|------|------------------|-------------|
|
||||||
|
| **GUI 框架** | PySide6 (Qt) | egui (即时模式) |
|
||||||
|
| **编译方式** | PyInstaller | Cargo + GNU 工具链 |
|
||||||
|
| **文件大小** | ~50MB | ~4MB |
|
||||||
|
| **启动速度** | 较慢 | 快 |
|
||||||
|
| **依赖** | 需 Python 运行时 | 独立可执行文件 |
|
||||||
|
| **界面风格** | 原生 Windows 风格 | 自定义风格 |
|
||||||
|
|
||||||
## 整体部署步骤(细化版)
|
## 整体部署步骤(细化版)
|
||||||
|
|
||||||
### 步骤1:MediaMTX服务器端
|
### 步骤1:MediaMTX服务器端
|
||||||
@@ -48,13 +61,24 @@
|
|||||||
|
|
||||||
### 主播端:推送本机屏幕
|
### 主播端:推送本机屏幕
|
||||||
|
|
||||||
**方案A:使用push\_screen.py脚本**
|
**方案A:使用 Rust 客户端(推荐)**
|
||||||
|
|
||||||
|
1. **下载预编译版本**
|
||||||
|
- 从 Releases 下载 `push_screen.exe`
|
||||||
|
- 或使用源码自行编译(见下方编译说明)
|
||||||
|
|
||||||
|
2. **运行程序**
|
||||||
|
- 双击运行 `push_screen.exe`
|
||||||
|
- 点击「设置」按钮配置服务器IP和FFmpeg路径
|
||||||
|
- 点击「开始全屏投屏」按钮开始推流
|
||||||
|
|
||||||
|
**方案B:使用 Python 客户端**
|
||||||
|
|
||||||
- 双击运行 `push_screen.py`
|
- 双击运行 `push_screen.py`
|
||||||
- 点击「一键全屏投屏」按钮
|
- 点击「一键全屏投屏」按钮
|
||||||
- 脚本会自动启动MediaMTX并开始推流
|
- 脚本会自动启动MediaMTX并开始推流
|
||||||
|
|
||||||
**方案B:使用mss抓屏+FFmpeg推流**
|
**方案C:使用mss抓屏+FFmpeg推流**
|
||||||
|
|
||||||
```python
|
```python
|
||||||
import subprocess
|
import subprocess
|
||||||
@@ -217,6 +241,166 @@ MediaMTX 会返回内置的 WebRTC 播放页面,浏览器会自动播放HDMI
|
|||||||
|
|
||||||
所有32台终端均可通过浏览器访问上述地址观看视频会议内容。
|
所有32台终端均可通过浏览器访问上述地址观看视频会议内容。
|
||||||
|
|
||||||
|
## Rust 客户端编译指南
|
||||||
|
|
||||||
|
### 环境准备
|
||||||
|
|
||||||
|
1. **安装 Rust**
|
||||||
|
- 下载地址:`https://rustup.rs/`
|
||||||
|
- 安装时选择 `x86_64-pc-windows-gnu` 目标
|
||||||
|
|
||||||
|
2. **安装 MinGW-w64**(GNU 工具链)
|
||||||
|
- 推荐通过 MSYS2 安装:`pacman -S mingw-w64-x86_64-toolchain`
|
||||||
|
- 或下载 winlibs MinGW-w64
|
||||||
|
|
||||||
|
3. **添加 Rust 目标**
|
||||||
|
```bash
|
||||||
|
rustup target add x86_64-pc-windows-gnu
|
||||||
|
```
|
||||||
|
|
||||||
|
### 项目结构
|
||||||
|
|
||||||
|
```
|
||||||
|
push_screen_rust/
|
||||||
|
├── Cargo.toml # 项目配置
|
||||||
|
├── build.rs # 构建脚本(用于嵌入图标)
|
||||||
|
├── app.rc # Windows 资源文件
|
||||||
|
├── vi.ico # 应用程序图标
|
||||||
|
└── src/
|
||||||
|
└── main.rs # 主程序
|
||||||
|
```
|
||||||
|
|
||||||
|
### 依赖库对照(PySide6 vs Rust)
|
||||||
|
|
||||||
|
| Python/PySide6 | Rust 等效库 | 用途 |
|
||||||
|
|----------------|-------------|------|
|
||||||
|
| PySide6 (Qt) | `eframe` + `egui` | GUI 框架 |
|
||||||
|
| `QThread` | `std::thread` + `mpsc` | 多线程 |
|
||||||
|
| `QTimer` | `std::time::Duration` + 线程休眠 | 定时器 |
|
||||||
|
| `socket` | `std::net::TcpStream` | 网络检测 |
|
||||||
|
| `subprocess` | `std::process::Command` | 进程管理 |
|
||||||
|
| `json` | `serde` + `serde_json` | JSON 序列化 |
|
||||||
|
| `logging` | `tracing` + `tracing-subscriber` | 日志记录 |
|
||||||
|
| `requests` | `reqwest` | HTTP 客户端 |
|
||||||
|
|
||||||
|
### 编译参数对照(PyInstaller vs Cargo)
|
||||||
|
|
||||||
|
| PyInstaller 参数 | Cargo/Rust 等效配置 | 说明 |
|
||||||
|
|------------------|---------------------|------|
|
||||||
|
| `--onefile` | `lto = true` + `strip = true` | 优化体积 |
|
||||||
|
| `--windowed` | `#![windows_subsystem = "windows"]` | 隐藏控制台 |
|
||||||
|
| `--icon=vi.ico` | `windres app.rc -O coff -o app.res` + 链接 | 嵌入图标 |
|
||||||
|
| `--noconsole` | `windows_subsystem` 属性 | 无控制台窗口 |
|
||||||
|
|
||||||
|
### 编译步骤
|
||||||
|
|
||||||
|
1. **进入项目目录**
|
||||||
|
```bash
|
||||||
|
cd push_screen_rust
|
||||||
|
```
|
||||||
|
|
||||||
|
2. **编译资源文件(图标)**
|
||||||
|
```bash
|
||||||
|
windres app.rc -O coff -o app.res
|
||||||
|
```
|
||||||
|
|
||||||
|
3. **配置构建脚本**(`build.rs`)
|
||||||
|
```rust
|
||||||
|
use std::env;
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let target = env::var("TARGET").unwrap();
|
||||||
|
if target.contains("windows") {
|
||||||
|
println!("cargo:rustc-link-arg=app.res");
|
||||||
|
}
|
||||||
|
println!("cargo:rerun-if-changed=app.rc");
|
||||||
|
println!("cargo:rerun-if-changed=vi.ico");
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
4. **配置 Cargo.toml**
|
||||||
|
```toml
|
||||||
|
[package]
|
||||||
|
name = "push_screen_rust"
|
||||||
|
version = "0.1.0"
|
||||||
|
edition = "2021"
|
||||||
|
build = "build.rs"
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
eframe = { version = "0.24", features = ["default"] }
|
||||||
|
egui = "0.24"
|
||||||
|
tokio = { version = "1", features = ["full"] }
|
||||||
|
serde = { version = "1.0", features = ["derive"] }
|
||||||
|
serde_json = "1.0"
|
||||||
|
reqwest = { version = "0.11", features = ["json"] }
|
||||||
|
tracing = "0.1"
|
||||||
|
tracing-subscriber = "0.3"
|
||||||
|
winapi = { version = "0.3", features = ["winuser", "windef", "wingdi", ...] }
|
||||||
|
|
||||||
|
[profile.release]
|
||||||
|
opt-level = 3
|
||||||
|
lto = true
|
||||||
|
# strip = true # 取消注释以进一步减小体积
|
||||||
|
|
||||||
|
[[bin]]
|
||||||
|
name = "push_screen"
|
||||||
|
path = "src/main.rs"
|
||||||
|
```
|
||||||
|
|
||||||
|
5. **编译发布版本**
|
||||||
|
```bash
|
||||||
|
cargo build --release --target x86_64-pc-windows-gnu
|
||||||
|
```
|
||||||
|
|
||||||
|
6. **输出文件**
|
||||||
|
- 位置:`target/x86_64-pc-windows-gnu/release/push_screen.exe`
|
||||||
|
- 大小:约 4-5 MB
|
||||||
|
|
||||||
|
### 关键代码说明
|
||||||
|
|
||||||
|
**隐藏控制台窗口**
|
||||||
|
```rust
|
||||||
|
#![windows_subsystem = "windows"]
|
||||||
|
```
|
||||||
|
|
||||||
|
**设置 UTF-8 编码(解决中文乱码)**
|
||||||
|
```rust
|
||||||
|
#[cfg(windows)]
|
||||||
|
extern "system" {
|
||||||
|
fn SetConsoleOutputCP(wCodePageID: u32) -> i32;
|
||||||
|
fn SetConsoleCP(wCodePageID: u32) -> i32;
|
||||||
|
}
|
||||||
|
|
||||||
|
fn set_utf8_encoding() {
|
||||||
|
#[cfg(windows)]
|
||||||
|
unsafe {
|
||||||
|
SetConsoleOutputCP(65001); // UTF-8
|
||||||
|
SetConsoleCP(65001);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
**加载中文字体**
|
||||||
|
```rust
|
||||||
|
fn configure_fonts(ctx: &egui::Context) {
|
||||||
|
let mut fonts = egui::FontDefinitions::default();
|
||||||
|
|
||||||
|
// 从系统加载中文字体
|
||||||
|
let font_paths = [
|
||||||
|
r"C:\Windows\Fonts\msyh.ttc", // 微软雅黑
|
||||||
|
r"C:\Windows\Fonts\simsun.ttc", // 宋体
|
||||||
|
];
|
||||||
|
|
||||||
|
for font_path in &font_paths {
|
||||||
|
if let Ok(font_data) = std::fs::read(font_path) {
|
||||||
|
// 加载字体...
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ctx.set_fonts(fonts);
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
## 测试方案
|
## 测试方案
|
||||||
|
|
||||||
使用1台台式机模拟MediaMTX服务器,2台笔记本分别模拟信号源和观众,测试两种场景。
|
使用1台台式机模拟MediaMTX服务器,2台笔记本分别模拟信号源和观众,测试两种场景。
|
||||||
@@ -249,7 +433,7 @@ MediaMTX 会返回内置的 WebRTC 播放页面,浏览器会自动播放HDMI
|
|||||||
确认控制台显示端口监听正常
|
确认控制台显示端口监听正常
|
||||||
|
|
||||||
2. **笔记本A启动推流**
|
2. **笔记本A启动推流**
|
||||||
- 运行 `push_screen.py`
|
- 运行 `push_screen.exe` (Rust) 或 `push_screen.py` (Python)
|
||||||
- 或使用命令行推流:
|
- 或使用命令行推流:
|
||||||
```bat
|
```bat
|
||||||
ffmpeg -f gdigrab -framerate 30 -i desktop -c:v libx264 -preset ultrafast -tune zerolatency -f rtsp rtsp://192.168.1.100:8554/screen
|
ffmpeg -f gdigrab -framerate 30 -i desktop -c:v libx264 -preset ultrafast -tune zerolatency -f rtsp rtsp://192.168.1.100:8554/screen
|
||||||
@@ -319,21 +503,57 @@ D:\ScreenCast
|
|||||||
│ └── mediamtx.exe
|
│ └── mediamtx.exe
|
||||||
├── ffmpeg/ # FFmpeg解压目录
|
├── ffmpeg/ # FFmpeg解压目录
|
||||||
│ └── bin/ffmpeg.exe
|
│ └── bin/ffmpeg.exe
|
||||||
├── push_screen.py # 投屏源推流脚本(一键采集)
|
├── push_screen_rust/ # Rust 客户端源码
|
||||||
|
│ ├── Cargo.toml
|
||||||
|
│ ├── build.rs
|
||||||
|
│ ├── app.rc
|
||||||
|
│ ├── vi.ico
|
||||||
|
│ └── src/main.rs
|
||||||
|
├── push_screen.exe # Rust 编译后的可执行文件(推荐)
|
||||||
|
├── push_screen.py # Python 投屏源推流脚本
|
||||||
├── auto_receive.py # 终端自动打开浏览器脚本
|
├── auto_receive.py # 终端自动打开浏览器脚本
|
||||||
└── manage_server.py # 运维总控脚本(启动/切换模式/停止)
|
└── manage_server.py # 运维总控脚本
|
||||||
```
|
```
|
||||||
|
|
||||||
## 核心Python脚本
|
## 核心脚本说明
|
||||||
|
|
||||||
### 脚本1:投屏源推流脚本(push\_screen.py)
|
### Rust 客户端(push_screen_rust)
|
||||||
|
|
||||||
功能:双击即可采集Win10屏幕,自动推流到MediaMTX,无需敲命令;支持「全屏/指定窗口」投屏,带可视化提示。
|
**功能**:轻量级投屏控制客户端,单文件可执行,无需运行时依赖。
|
||||||
|
|
||||||
### 脚本2:终端自动打开浏览器脚本(auto\_receive.py)
|
**特性**:
|
||||||
|
- 实时状态检测(FFmpeg、服务器、端口)
|
||||||
|
- 配置持久化(config.json)
|
||||||
|
- 一键开始/停止推流
|
||||||
|
- 中文字体支持
|
||||||
|
- 自定义应用程序图标
|
||||||
|
|
||||||
功能:双击脚本自动打开Chrome浏览器(全屏),直接跳转到投屏/会议流页面;支持批量部署到32台终端,无需手动输入地址。
|
**编译命令**:
|
||||||
|
```bash
|
||||||
|
cd push_screen_rust
|
||||||
|
windres app.rc -O coff -o app.res
|
||||||
|
cargo build --release --target x86_64-pc-windows-gnu
|
||||||
|
```
|
||||||
|
|
||||||
### 脚本3:运维总控脚本(manage\_server.py)
|
### Python 客户端(push_screen.py)
|
||||||
|
|
||||||
功能:一站式运维(启动MediaMTX、切换两种模式、批量控制32台终端、停止所有服务),适合管理员操作。
|
**功能**:基于 PySide6 的投屏控制界面,功能完善。
|
||||||
|
|
||||||
|
**特性**:
|
||||||
|
- 可视化配置界面
|
||||||
|
- 实时状态指示器
|
||||||
|
- 日志显示
|
||||||
|
- 设置对话框
|
||||||
|
|
||||||
|
**运行命令**:
|
||||||
|
```bash
|
||||||
|
python push_screen.py
|
||||||
|
```
|
||||||
|
|
||||||
|
### 终端自动打开浏览器脚本(auto_receive.py)
|
||||||
|
|
||||||
|
**功能**:双击脚本自动打开Chrome浏览器(全屏),直接跳转到投屏/会议流页面;支持批量部署到32台终端,无需手动输入地址。
|
||||||
|
|
||||||
|
### 运维总控脚本(manage_server.py)
|
||||||
|
|
||||||
|
**功能**:一站式运维(启动MediaMTX、切换两种模式、批量控制32台终端、停止所有服务),适合管理员操作。
|
||||||
|
|||||||
Reference in New Issue
Block a user