From bd196c4533db4b9ea515fcc73b7a70530ad6644e Mon Sep 17 00:00:00 2001 From: jlvihv Date: Tue, 25 Jun 2024 23:41:07 +0800 Subject: [PATCH] forward --- src-tauri/src/ffmpeg.rs | 2 +- src-tauri/src/lib.rs | 1 + src-tauri/src/manager.rs | 23 +++++++++++++++++++++-- src/lib/components/sidebar.svelte | 10 +++++----- src/lib/i18n/cn.json | 5 +++-- src/lib/i18n/en.json | 3 ++- src/routes/live/forward/+page.svelte | 7 +++++-- 7 files changed, 38 insertions(+), 13 deletions(-) diff --git a/src-tauri/src/ffmpeg.rs b/src-tauri/src/ffmpeg.rs index b7668a7..077acfe 100644 --- a/src-tauri/src/ffmpeg.rs +++ b/src-tauri/src/ffmpeg.rs @@ -30,7 +30,7 @@ pub fn execute_ffmpeg_command(ffmpeg_command: Vec) -> Result { ); return Err(anyhow::anyhow!(error_message)); } - println!("录制进程启动:{:?}", child.id()); + println!("进程启动:{:?}", child.id()); Ok(child) } diff --git a/src-tauri/src/lib.rs b/src-tauri/src/lib.rs index 8c18655..9157f5b 100644 --- a/src-tauri/src/lib.rs +++ b/src-tauri/src/lib.rs @@ -57,6 +57,7 @@ pub fn run() { manager::ffmpeg_api::execute_ffmpeg_command, manager::ffmpeg_api::execute_ffmpeg_command_return_output, manager::ffmpeg_api::get_image_info, + manager::ffmpeg_api::kill_child, manager::request_api::request, manager::request_api::try_request_get_status, manager::request_api::request_post, diff --git a/src-tauri/src/manager.rs b/src-tauri/src/manager.rs index f864a55..cfe9d94 100644 --- a/src-tauri/src/manager.rs +++ b/src-tauri/src/manager.rs @@ -16,6 +16,9 @@ use std::{path::PathBuf, process::Child}; // 用一个 dashmap 用来保存已经开始的录制任务 pub static TASKS: Lazy> = Lazy::new(|| DashMap::new()); +// 全局 dashmap,键是 id,值是 ffmpeg 进程 +static CHILDS: Lazy> = Lazy::new(|| DashMap::new()); + /// 内部方法,不对外暴露 pub mod inner { use super::*; @@ -417,9 +420,25 @@ pub mod ffmpeg_api { /// 执行 ffmpeg 命令 #[tauri::command] - pub async fn execute_ffmpeg_command(ffmpeg_command: Vec) -> Result<(), String> { - ffmpeg::execute_ffmpeg_command(ffmpeg_command) + pub async fn execute_ffmpeg_command(ffmpeg_command: Vec) -> Result { + let child = ffmpeg::execute_ffmpeg_command(ffmpeg_command) .map_err(|e| format!("Could not run ffmpeg command: {}", e))?; + let child_id = child.id(); + CHILDS.insert(child.id(), child); + Ok(child_id) + } + + /// 杀掉 ffmpeg 进程 + #[tauri::command] + pub async fn kill_child(id: u32) -> Result<(), String> { + if let Some((_id, mut child)) = CHILDS.remove(&id) { + child + .kill() + .map_err(|e| format!("Could not kill child process: {}", e))?; + child + .wait() + .map_err(|e| format!("Could not wait for child process: {}", e))?; + } Ok(()) } diff --git a/src/lib/components/sidebar.svelte b/src/lib/components/sidebar.svelte index 2963ef1..e812c9c 100644 --- a/src/lib/components/sidebar.svelte +++ b/src/lib/components/sidebar.svelte @@ -15,11 +15,11 @@ href: '/record/plan' }, // { label: $t('streamPush'), icon: 'icon-[fluent--video-28-regular]', href: '/live' }, - // { - // label: $t('streamForward'), - // icon: 'icon-[fluent--square-arrow-forward-32-regular]', - // href: '/live/forward' - // }, + { + label: $t('streamForward'), + icon: 'icon-[fluent--square-arrow-forward-32-regular]', + href: '/live/forward' + }, { label: $t('settings'), icon: 'icon-[fluent--settings-32-regular]', href: '/config' } ]; diff --git a/src/lib/i18n/cn.json b/src/lib/i18n/cn.json index 7409431..333b810 100644 --- a/src/lib/i18n/cn.json +++ b/src/lib/i18n/cn.json @@ -96,7 +96,7 @@ "planDeleteFailed": "删除计划失败", "planAdded": "已添加计划", "xiaohongshu": "小红书", - "streamForwardWarning": "警告:直播流转发是实验性功能,目前仅支持转发到小红书,且未来可能移除此功能。使用此功能可能导致您的平台账号被封禁,请谨慎使用。若您执意使用此功能,对您造成的任何损失,我概不负责。", + "streamForwardWarning": "警告:直播流转发是实验性功能,目前仅支持转发到小红书,且未来可能移除此功能。使用此功能可能导致您的平台账号被封禁,请谨慎使用。若您执意使用此功能,对您造成的任何损失,我概不负责。目前功能不完整,开始转发后,请不要切换页面,不然就找不回来了,您只能从任务管理器中结束 ffmpeg 进程。", "startForward": "开始转发", "streamPush": "直播推流", "streamForward": "直播转发", @@ -141,5 +141,6 @@ "parseError": "解析直播流地址错误,请刷新试试", "useProxy": "使用代理录制", "useProxyPlaceholder": "请输入代理地址", - "advancedOptions": "高级选项" + "advancedOptions": "高级选项", + "stopForward": "停止转发" } diff --git a/src/lib/i18n/en.json b/src/lib/i18n/en.json index f5edac5..8e080d0 100644 --- a/src/lib/i18n/en.json +++ b/src/lib/i18n/en.json @@ -142,5 +142,6 @@ "parseError": "Failed to parse live stream address, please refresh and try again", "useProxy": "Use proxy to record", "useProxyPlaceholder": "Please enter the proxy address", - "advancedOptions": "Advanced options" + "advancedOptions": "Advanced options", + "stopForward": "Stop forwarding" } diff --git a/src/routes/live/forward/+page.svelte b/src/routes/live/forward/+page.svelte index 1e9d45e..b923fbe 100644 --- a/src/routes/live/forward/+page.svelte +++ b/src/routes/live/forward/+page.svelte @@ -13,6 +13,7 @@ // 关键信息变量 let url = $state(''); + let id = $state(0); const xiaohongshuPushServer = 'rtmp://live-push.xhscdn.com/live'; let liveInfo: LiveInfo | undefined = $state(); let errorMessage = $state(''); @@ -66,9 +67,10 @@ } let ffmpegCommand = buildFFmpegForwardCommand(streamUrl, outputUrl); try { - await invoke('execute_ffmpeg_command', { ffmpegCommand }); + id = await invoke('execute_ffmpeg_command', { ffmpegCommand }); // 只要不异常,就认为成功了 forwarding = true; + toast.success('已经开始转发啦'); } catch (e) { toast.error(e as string); forwarding = false; @@ -77,8 +79,9 @@ async function stopForward() { try { - await invoke('stop_ffmpeg_command'); + await invoke('kill_child', { id }); forwarding = false; + toast.success('已经停止转发啦'); } catch (e) { toast.error(e as string); }