From 150057f92ded133b0e2b32a7331d8303ab9930a4 Mon Sep 17 00:00:00 2001 From: 21pages Date: Wed, 12 Oct 2022 16:06:15 +0800 Subject: [PATCH] fix default video save directory Signed-off-by: 21pages --- .../desktop/pages/desktop_setting_page.dart | 6 +-- libs/scrap/src/common/record.rs | 43 ++++++++----------- src/client.rs | 3 +- src/core_main.rs | 3 ++ src/platform/linux.rs | 12 ++++++ src/platform/macos.rs | 12 ++++++ src/platform/windows.rs | 13 ++++++ src/server/video_service.rs | 3 +- src/ui_interface.rs | 24 ++++++++++- 9 files changed, 87 insertions(+), 32 deletions(-) diff --git a/flutter/lib/desktop/pages/desktop_setting_page.dart b/flutter/lib/desktop/pages/desktop_setting_page.dart index 1534f9394..7dc18679d 100644 --- a/flutter/lib/desktop/pages/desktop_setting_page.dart +++ b/flutter/lib/desktop/pages/desktop_setting_page.dart @@ -338,8 +338,8 @@ class _GeneralState extends State<_General> { } else { dir = defaultDirectory; } - final canlaunch = await canLaunchUrl(Uri.file(dir)); - return {'dir': dir, 'canlaunch': canlaunch}; + // canLaunchUrl blocked on windows portable, user SYSTEM + return {'dir': dir, 'canlaunch': true}; }(), hasData: (data) { Map map = data as Map; String dir = map['dir']!; @@ -703,7 +703,7 @@ class _Network extends StatefulWidget { class _NetworkState extends State<_Network> with AutomaticKeepAliveClientMixin { @override bool get wantKeepAlive => true; - bool locked = true; + bool locked = bind.mainIsInstalled(); @override Widget build(BuildContext context) { diff --git a/libs/scrap/src/common/record.rs b/libs/scrap/src/common/record.rs index e8bbacf02..83bd9eee7 100644 --- a/libs/scrap/src/common/record.rs +++ b/libs/scrap/src/common/record.rs @@ -3,7 +3,7 @@ use hbb_common::anyhow::anyhow; use hbb_common::{ bail, chrono, config::Config, - directories_next, + log, message_proto::{message, video_frame, EncodedVideoFrame, Message}, ResultType, }; @@ -23,7 +23,7 @@ use webm::mux::{self, Segment, Track, VideoTrack, Writer}; const MIN_SECS: u64 = 1; #[derive(Debug, Clone, PartialEq)] -pub enum RecodeCodecID { +pub enum RecordCodecID { VP9, H264, H265, @@ -32,10 +32,11 @@ pub enum RecodeCodecID { #[derive(Debug, Clone)] pub struct RecorderContext { pub id: String, + pub default_dir: String, pub filename: String, pub width: usize, pub height: usize, - pub codec_id: RecodeCodecID, + pub codec_id: RecordCodecID, } impl RecorderContext { @@ -46,30 +47,22 @@ impl RecorderContext { std::fs::create_dir_all(&dir)?; } } else { - dir = Self::default_save_directory(); + dir = self.default_dir.clone(); if !dir.is_empty() && !PathBuf::from(&dir).exists() { std::fs::create_dir_all(&dir)?; } } let file = self.id.clone() + &chrono::Local::now().format("_%Y%m%d%H%M%S").to_string() - + if self.codec_id == RecodeCodecID::VP9 { + + if self.codec_id == RecordCodecID::VP9 { ".webm" } else { ".mp4" }; self.filename = PathBuf::from(&dir).join(file).to_string_lossy().to_string(); + log::info!("video save to:{}", self.filename); Ok(()) } - - pub fn default_save_directory() -> String { - if let Some(user) = directories_next::UserDirs::new() { - if let Some(video_dir) = user.video_dir() { - return video_dir.join("RustDesk").to_string_lossy().to_string(); - } - } - "".to_owned() - } } unsafe impl Send for Recorder {} @@ -105,7 +98,7 @@ impl Recorder { pub fn new(mut ctx: RecorderContext) -> ResultType { ctx.set_filename()?; let recorder = match ctx.codec_id { - RecodeCodecID::VP9 => Recorder { + RecordCodecID::VP9 => Recorder { inner: Box::new(WebmRecorder::new(ctx.clone())?), ctx, }, @@ -123,7 +116,7 @@ impl Recorder { fn change(&mut self, mut ctx: RecorderContext) -> ResultType<()> { ctx.set_filename()?; self.inner = match ctx.codec_id { - RecodeCodecID::VP9 => Box::new(WebmRecorder::new(ctx.clone())?), + RecordCodecID::VP9 => Box::new(WebmRecorder::new(ctx.clone())?), #[cfg(feature = "hwcodec")] _ => Box::new(HwRecorder::new(ctx.clone())?), #[cfg(not(feature = "hwcodec"))] @@ -144,9 +137,9 @@ impl Recorder { pub fn write_frame(&mut self, frame: &video_frame::Union) -> ResultType<()> { match frame { video_frame::Union::Vp9s(vp9s) => { - if self.ctx.codec_id != RecodeCodecID::VP9 { + if self.ctx.codec_id != RecordCodecID::VP9 { self.change(RecorderContext { - codec_id: RecodeCodecID::VP9, + codec_id: RecordCodecID::VP9, ..self.ctx.clone() })?; } @@ -154,25 +147,25 @@ impl Recorder { } #[cfg(feature = "hwcodec")] video_frame::Union::H264s(h264s) => { - if self.ctx.codec_id != RecodeCodecID::H264 { + if self.ctx.codec_id != RecordCodecID::H264 { self.change(RecorderContext { - codec_id: RecodeCodecID::H264, + codec_id: RecordCodecID::H264, ..self.ctx.clone() })?; } - if self.ctx.codec_id == RecodeCodecID::H264 { + if self.ctx.codec_id == RecordCodecID::H264 { h264s.frames.iter().map(|f| self.write_video(f)).count(); } } #[cfg(feature = "hwcodec")] video_frame::Union::H265s(h265s) => { - if self.ctx.codec_id != RecodeCodecID::H265 { + if self.ctx.codec_id != RecordCodecID::H265 { self.change(RecorderContext { - codec_id: RecodeCodecID::H265, + codec_id: RecordCodecID::H265, ..self.ctx.clone() })?; } - if self.ctx.codec_id == RecodeCodecID::H265 { + if self.ctx.codec_id == RecordCodecID::H265 { h265s.frames.iter().map(|f| self.write_video(f)).count(); } } @@ -266,7 +259,7 @@ impl RecorderApi for HwRecorder { filename: ctx.filename.clone(), width: ctx.width, height: ctx.height, - is265: ctx.codec_id == RecodeCodecID::H265, + is265: ctx.codec_id == RecordCodecID::H265, framerate: crate::hwcodec::DEFAULT_TIME_BASE[1] as _, }) .map_err(|_| anyhow!("Failed to create hardware muxer"))?; diff --git a/src/client.rs b/src/client.rs index df18d9b0a..8723480f3 100644 --- a/src/client.rs +++ b/src/client.rs @@ -860,10 +860,11 @@ impl VideoHandler { if start { self.recorder = Recorder::new(RecorderContext { id, + default_dir: crate::ui_interface::default_video_save_directory(), filename: "".to_owned(), width: w as _, height: h as _, - codec_id: scrap::record::RecodeCodecID::VP9, + codec_id: scrap::record::RecordCodecID::VP9, }) .map_or(Default::default(), |r| Arc::new(Mutex::new(Some(r)))); } else { diff --git a/src/core_main.rs b/src/core_main.rs index 416c2965f..5a72cea9c 100644 --- a/src/core_main.rs +++ b/src/core_main.rs @@ -33,6 +33,9 @@ pub fn core_main() -> Option> { } if _is_connect { return core_main_invoke_new_connection(std::env::args()); + } + if args.contains(&"--install".to_string()) { + is_setup = true; } if is_setup { if args.is_empty() { diff --git a/src/platform/linux.rs b/src/platform/linux.rs index 89e2d296d..5ff69d732 100644 --- a/src/platform/linux.rs +++ b/src/platform/linux.rs @@ -4,6 +4,7 @@ use hbb_common::{allow_err, bail, log}; use libc::{c_char, c_int, c_void}; use std::{ cell::RefCell, + path::PathBuf, sync::{ atomic::{AtomicBool, Ordering}, Arc, @@ -516,6 +517,17 @@ pub fn get_active_username() -> String { get_value_of_seat0(2) } +pub fn get_active_user_home() -> Option { + let username = get_active_username(); + if !username.is_empty() { + let home = PathBuf::from(format!("/home/{}", username)); + if home.exists() { + return Some(home); + } + } + None +} + pub fn is_prelogin() -> bool { let n = get_active_userid().len(); n < 4 && n > 1 diff --git a/src/platform/macos.rs b/src/platform/macos.rs index 1a8096587..3273a22a5 100644 --- a/src/platform/macos.rs +++ b/src/platform/macos.rs @@ -20,6 +20,7 @@ use hbb_common::{bail, log}; use include_dir::{include_dir, Dir}; use objc::{class, msg_send, sel, sel_impl}; use scrap::{libc::c_void, quartz::ffi::*}; +use std::path::PathBuf; static PRIVILEGES_SCRIPTS_DIR: Dir = include_dir!("$CARGO_MANIFEST_DIR/src/platform/privileges_scripts"); @@ -374,6 +375,17 @@ pub fn get_active_userid() -> String { get_active_user("-n") } +pub fn get_active_user_home() -> Option { + let username = get_active_username(); + if !username.is_empty() { + let home = PathBuf::from(format!("/Users/{}", username)); + if home.exists() { + return Some(home); + } + } + None +} + pub fn is_prelogin() -> bool { get_active_userid() == "0" } diff --git a/src/platform/windows.rs b/src/platform/windows.rs index 6732f2c36..190a49a16 100644 --- a/src/platform/windows.rs +++ b/src/platform/windows.rs @@ -10,6 +10,7 @@ use std::io::prelude::*; use std::{ ffi::{CString, OsString}, fs, io, mem, + path::PathBuf, sync::{Arc, Mutex}, time::{Duration, Instant}, }; @@ -734,6 +735,18 @@ pub fn get_active_username() -> String { .to_owned() } +pub fn get_active_user_home() -> Option { + let username = get_active_username(); + if !username.is_empty() { + let drive = std::env::var("SystemDrive").unwrap_or("C:".to_owned()); + let home = PathBuf::from(format!("{}\\Users\\{}", drive, username)); + if home.exists() { + return Some(home); + } + } + None +} + pub fn is_prelogin() -> bool { let username = get_active_username(); username.is_empty() || username == "SYSTEM" diff --git a/src/server/video_service.rs b/src/server/video_service.rs index ad6f5f620..fad66ffb4 100644 --- a/src/server/video_service.rs +++ b/src/server/video_service.rs @@ -443,10 +443,11 @@ fn run(sp: GenericService) -> ResultType<()> { let recorder = if !Config::get_option("allow-auto-record-incoming").is_empty() { Recorder::new(RecorderContext { id: "local".to_owned(), + default_dir: crate::ui_interface::default_video_save_directory(), filename: "".to_owned(), width: c.width, height: c.height, - codec_id: scrap::record::RecodeCodecID::VP9, + codec_id: scrap::record::RecordCodecID::VP9, }) .map_or(Default::default(), |r| Arc::new(Mutex::new(Some(r)))) } else { diff --git a/src/ui_interface.rs b/src/ui_interface.rs index c42a99037..9952a5b35 100644 --- a/src/ui_interface.rs +++ b/src/ui_interface.rs @@ -10,6 +10,7 @@ use hbb_common::password_security; use hbb_common::{ allow_err, config::{self, Config, LocalConfig, PeerConfig, RENDEZVOUS_PORT, RENDEZVOUS_TIMEOUT}, + directories_next, futures::future::join_all, log, protobuf::Message as _, @@ -19,8 +20,8 @@ use hbb_common::{ tokio::{self, sync::mpsc, time}, }; -use crate::common::SOFTWARE_UPDATE_URL; use crate::ipc; +use crate::{common::SOFTWARE_UPDATE_URL, platform}; type Message = RendezvousMessage; @@ -731,7 +732,26 @@ pub fn get_langs() -> String { #[inline] pub fn default_video_save_directory() -> String { - scrap::record::RecorderContext::default_save_directory() + let appname = crate::get_app_name(); + if let Some(user) = directories_next::UserDirs::new() { + if let Some(video_dir) = user.video_dir() { + return video_dir.join(appname).to_string_lossy().to_string(); + } + } + if let Some(home) = platform::get_active_user_home() { + let name = if cfg!(target_os = "macos") { + "Movies" + } else { + "Videos" + }; + return home.join(name).join(appname).to_string_lossy().to_string(); + } + if let Ok(exe) = std::env::current_exe() { + if let Some(dir) = exe.parent() { + return dir.join("videos").to_string_lossy().to_string(); + } + } + "".to_owned() } #[inline]