把桌面端从 Slint 迁到 Tauri v2,后端先落地,界面待接。拆成三层: - desktop/core(cam-core,67 测试):从旧 client/ 抽出的非界面部分。UDP 接收按 发送方重组、装甲板发现与血量、帧率窗口、槽位分配、配置与密码。 - desktop/src-tauri(27 测试):Tauri 后端。回环 WebSocket 推二进制 JPEG、 每 200ms 一份状态快照、密码闸门、截图、ffmpeg 录制 mp4、演示数据源。 - protocol:新增 ArmorHealth::decode_from,把帧头里的 sender_id 交出来—— 装甲板一直带着 MAC 派生 id 在广播,旧解码路径把它丢了,所以"装甲板下拉可选" 不需要改固件。 几个改对了的旧问题: - 槽位分配:旧实现只排除"槽位自己原来那个 id",于是队伍一的板子一离线,它的槽位 会去拿队伍二那块,两格显示同一块板子。现在候选要排除另一个槽位占着的 id。 - 帧率窗口的基线:掉线又回来的板子带着一个很大的累计帧数回来,从 0 起算会报出 几百 fps。改成 seeded + 用"已结算窗口数"判断有没有读数。 - 密码哈希:password-hash 能解析 `$argon2id$broken` 这种截断串,于是"配置坏了" 会被读成"密码错了"。现在要求盐与摘要都在。 - 录制文件名:同一秒停一次再开一次会用同一个名字,ffmpeg 的 -y 静默覆盖上一段。 现在先收尾上一段再开新的,并且重名往后排号。 - 两道闸门:帧的限制与发现列表的限制分开。设置界面需要列候选摄像头,但**画面** 不需要——旧版把两件事绑在一道闸门上,只能在"能列候选"和"挡住对手"之间二选一。 测试:protocol 15、cam-core 67、desktop 27,其中录制那条真的起 ffmpeg 并用 ffprobe 读回帧数与分辨率(只断言"文件存在"会漏掉空容器)。
58 lines
1.8 KiB
TOML
58 lines
1.8 KiB
TOML
[package]
|
|
name = "cam-desktop"
|
|
version = "0.1.0"
|
|
edition = "2021"
|
|
description = "ESP32 图传与装甲板系统的桌面端"
|
|
rust-version = "1.77"
|
|
|
|
[build-dependencies]
|
|
tauri-build = { version = "2", features = [] }
|
|
|
|
[dependencies]
|
|
# `protocol-asset` 打开自定义资源协议,录制出来的 mp4 才能在界面里直接回放
|
|
# (前端用 convertFileSrc 把它变成一个 <video> 能播的 URL)。
|
|
tauri = { version = "2", features = ["protocol-asset"] }
|
|
|
|
# 只用来"在访达里显示"与"用系统播放器打开"。所有调用都走我们自己的 Rust 命令,
|
|
# 所以前端不需要装 @tauri-apps/plugin-opener,也不需要给它开权限。
|
|
tauri-plugin-opener = "2"
|
|
|
|
# 非界面部分:UDP 接收/重组、装甲板、配置、密码、槽位分配。它自己带 64 个测试。
|
|
cam-core = { path = "../core" }
|
|
|
|
# 线路格式与固件共享。
|
|
protocol = { path = "../../protocol" }
|
|
|
|
serde = { version = "1", features = ["derive"] }
|
|
serde_json = "1"
|
|
log = "0.4"
|
|
env_logger = "0.11"
|
|
anyhow = "1"
|
|
|
|
# 回环通道的随机 token。
|
|
rand = "0.9"
|
|
|
|
# 本地 WebSocket 视频通道。用 tokio-tungstenite 而不是 Tauri 的自定义协议:
|
|
# 二进制消息不经 JSON/IPC 序列化,前端拿到的就是原始 JPEG 字节,可以直接交给
|
|
# 浏览器的原生 JPEG 解码器(createImageBitmap)。
|
|
tokio = { version = "1", features = [
|
|
"rt-multi-thread",
|
|
"net",
|
|
"sync",
|
|
"io-util",
|
|
"macros",
|
|
"time",
|
|
] }
|
|
tokio-tungstenite = "0.30"
|
|
futures-util = "0.3"
|
|
|
|
# 截图要 PNG(相机出的 JPEG 不带 alpha、也可能被播放器当照片处理),所以要解码再编码。
|
|
# demo 模式也用它合成假画面。
|
|
image = { version = "0.25", default-features = false, features = ["jpeg", "png"] }
|
|
|
|
# 文件名里的时间戳:现场看目录时要能一眼看出是哪一局录的。
|
|
chrono = "0.4"
|
|
|
|
[profile.release]
|
|
opt-level = 2
|