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

@@ -210,7 +210,11 @@ impl ExtensionManager {
}
/// Build command arguments for an extension
async fn build_args(&self, id: ExtensionId, config: &ExtensionsConfig) -> Result<Vec<String>, String> {
async fn build_args(
&self,
id: ExtensionId,
config: &ExtensionsConfig,
) -> Result<Vec<String>, String> {
match id {
ExtensionId::Ttyd => {
let c = &config.ttyd;
@@ -219,9 +223,11 @@ impl ExtensionManager {
Self::prepare_ttyd_socket().await?;
let mut args = vec![
"-i".to_string(), TTYD_SOCKET_PATH.to_string(), // Unix socket
"-b".to_string(), "/api/terminal".to_string(), // Base path for reverse proxy
"-W".to_string(), // Writable (allow input)
"-i".to_string(),
TTYD_SOCKET_PATH.to_string(), // Unix socket
"-b".to_string(),
"/api/terminal".to_string(), // Base path for reverse proxy
"-W".to_string(), // Writable (allow input)
];
// Add credential if set (still useful for additional security layer)
@@ -313,7 +319,10 @@ impl ExtensionManager {
}
// Remove old socket file if exists
if tokio::fs::try_exists(TTYD_SOCKET_PATH).await.unwrap_or(false) {
if tokio::fs::try_exists(TTYD_SOCKET_PATH)
.await
.unwrap_or(false)
{
tokio::fs::remove_file(TTYD_SOCKET_PATH)
.await
.map_err(|e| format!("Failed to remove old socket: {}", e))?;
@@ -374,8 +383,8 @@ impl ExtensionManager {
/// Start all enabled extensions in parallel
pub async fn start_enabled(&self, config: &ExtensionsConfig) {
use std::pin::Pin;
use futures::Future;
use std::pin::Pin;
let mut start_futures: Vec<Pin<Box<dyn Future<Output = ()> + Send + '_>>> = Vec::new();
@@ -416,10 +425,7 @@ impl ExtensionManager {
/// Stop all running extensions in parallel
pub async fn stop_all(&self) {
let stop_futures: Vec<_> = ExtensionId::all()
.iter()
.map(|id| self.stop(*id))
.collect();
let stop_futures: Vec<_> = ExtensionId::all().iter().map(|id| self.stop(*id)).collect();
futures::future::join_all(stop_futures).await;
}
}