feat(video): 事务化切换与前端统一编排,增强视频输入格式支持

- 后端:切换事务+transition_id,/stream/mode 返回 switching/transition_id 与实际 codec

- 事件:新增 mode_switching/mode_ready,config/webrtc_ready/mode_changed 关联事务

- 编码/格式:扩展 NV21/NV16/NV24/RGB/BGR 输入与转换链路,RKMPP direct input 优化

- 前端:useVideoSession 统一切换,失败回退真实切回 MJPEG,菜单格式同步修复

- 清理:useVideoStream 降级为 MJPEG-only
This commit is contained in:
mofeng-git
2026-01-11 10:41:57 +08:00
parent 9feb74b72c
commit 206594e292
110 changed files with 3955 additions and 2251 deletions

View File

@@ -14,9 +14,7 @@ use std::sync::Arc;
use tokio::io::{AsyncReadExt, AsyncWriteExt};
use tokio::net::UnixStream;
use tokio_tungstenite::tungstenite::{
client::IntoClientRequest,
http::HeaderValue,
Message as TungsteniteMessage,
client::IntoClientRequest, http::HeaderValue, Message as TungsteniteMessage,
};
use crate::error::AppError;
@@ -60,10 +58,9 @@ async fn handle_terminal_websocket(client_ws: WebSocket, query_string: String) {
}
};
request.headers_mut().insert(
"Sec-WebSocket-Protocol",
HeaderValue::from_static("tty"),
);
request
.headers_mut()
.insert("Sec-WebSocket-Protocol", HeaderValue::from_static("tty"));
// Create WebSocket connection to ttyd
let ws_stream = match tokio_tungstenite::client_async(request, unix_stream).await {
@@ -143,7 +140,11 @@ pub async fn terminal_proxy(
// Build HTTP request to forward
let method = req.method().as_str();
let query = req.uri().query().map(|q| format!("?{}", q)).unwrap_or_default();
let query = req
.uri()
.query()
.map(|q| format!("?{}", q))
.unwrap_or_default();
let uri_path = if path_str.is_empty() {
format!("/api/terminal/{}", query)
} else {
@@ -203,7 +204,8 @@ pub async fn terminal_proxy(
.unwrap_or(200);
// Build response
let mut builder = Response::builder().status(StatusCode::from_u16(status_code).unwrap_or(StatusCode::OK));
let mut builder =
Response::builder().status(StatusCode::from_u16(status_code).unwrap_or(StatusCode::OK));
// Forward response headers
for line in headers_part.lines().skip(1) {