mirror of
https://github.com/weyne85/rustdesk.git
synced 2025-10-29 17:00:05 +00:00
installed windows client save incoming recording to a specific directory (#7974)
Signed-off-by: 21pages <pages21@163.com>
This commit is contained in:
parent
35832f8f7f
commit
09f3850250
@ -485,42 +485,72 @@ class _GeneralState extends State<_General> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Widget record(BuildContext context) {
|
Widget record(BuildContext context) {
|
||||||
|
final showRootDir = isWindows && bind.mainIsInstalled();
|
||||||
return futureBuilder(future: () async {
|
return futureBuilder(future: () async {
|
||||||
String defaultDirectory = await bind.mainDefaultVideoSaveDirectory();
|
String user_dir = await bind.mainVideoSaveDirectory(root: false);
|
||||||
|
String root_dir =
|
||||||
|
showRootDir ? await bind.mainVideoSaveDirectory(root: true) : '';
|
||||||
|
bool user_dir_exists = await Directory(user_dir).exists();
|
||||||
|
bool root_dir_exists =
|
||||||
|
showRootDir ? await Directory(root_dir).exists() : false;
|
||||||
// canLaunchUrl blocked on windows portable, user SYSTEM
|
// canLaunchUrl blocked on windows portable, user SYSTEM
|
||||||
return {'dir': defaultDirectory, 'canlaunch': true};
|
return {
|
||||||
|
'user_dir': user_dir,
|
||||||
|
'root_dir': root_dir,
|
||||||
|
'user_dir_exists': user_dir_exists,
|
||||||
|
'root_dir_exists': root_dir_exists,
|
||||||
|
};
|
||||||
}(), hasData: (data) {
|
}(), hasData: (data) {
|
||||||
Map<String, dynamic> map = data as Map<String, dynamic>;
|
Map<String, dynamic> map = data as Map<String, dynamic>;
|
||||||
String dir = map['dir']!;
|
String user_dir = map['user_dir']!;
|
||||||
String customDirectory =
|
String root_dir = map['root_dir']!;
|
||||||
bind.mainGetOptionSync(key: 'video-save-directory');
|
bool root_dir_exists = map['root_dir_exists']!;
|
||||||
if (customDirectory.isNotEmpty) {
|
bool user_dir_exists = map['user_dir_exists']!;
|
||||||
dir = customDirectory;
|
|
||||||
}
|
|
||||||
bool canlaunch = map['canlaunch']! as bool;
|
|
||||||
|
|
||||||
return _Card(title: 'Recording', children: [
|
return _Card(title: 'Recording', children: [
|
||||||
_OptionCheckBox(context, 'Automatically record incoming sessions',
|
_OptionCheckBox(context, 'Automatically record incoming sessions',
|
||||||
'allow-auto-record-incoming'),
|
'allow-auto-record-incoming'),
|
||||||
|
if (showRootDir)
|
||||||
Row(
|
Row(
|
||||||
children: [
|
children: [
|
||||||
Text('${translate("Directory")}:'),
|
Text('${translate("Incoming")}:'),
|
||||||
Expanded(
|
Expanded(
|
||||||
child: GestureDetector(
|
child: GestureDetector(
|
||||||
onTap: canlaunch ? () => launchUrl(Uri.file(dir)) : null,
|
onTap: root_dir_exists
|
||||||
|
? () => launchUrl(Uri.file(root_dir))
|
||||||
|
: null,
|
||||||
child: Text(
|
child: Text(
|
||||||
dir,
|
root_dir,
|
||||||
softWrap: true,
|
softWrap: true,
|
||||||
style:
|
style: root_dir_exists
|
||||||
const TextStyle(decoration: TextDecoration.underline),
|
? const TextStyle(
|
||||||
|
decoration: TextDecoration.underline)
|
||||||
|
: null,
|
||||||
|
)).marginOnly(left: 10),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
).marginOnly(left: _kContentHMargin),
|
||||||
|
Row(
|
||||||
|
children: [
|
||||||
|
Text('${translate(showRootDir ? "Outgoing" : "Directory")}:'),
|
||||||
|
Expanded(
|
||||||
|
child: GestureDetector(
|
||||||
|
onTap: user_dir_exists
|
||||||
|
? () => launchUrl(Uri.file(user_dir))
|
||||||
|
: null,
|
||||||
|
child: Text(
|
||||||
|
user_dir,
|
||||||
|
softWrap: true,
|
||||||
|
style: user_dir_exists
|
||||||
|
? const TextStyle(decoration: TextDecoration.underline)
|
||||||
|
: null,
|
||||||
)).marginOnly(left: 10),
|
)).marginOnly(left: 10),
|
||||||
),
|
),
|
||||||
ElevatedButton(
|
ElevatedButton(
|
||||||
onPressed: () async {
|
onPressed: () async {
|
||||||
String? initialDirectory;
|
String? initialDirectory;
|
||||||
if (await Directory.fromUri(Uri.directory(dir))
|
if (await Directory.fromUri(Uri.directory(user_dir))
|
||||||
.exists()) {
|
.exists()) {
|
||||||
initialDirectory = dir;
|
initialDirectory = user_dir;
|
||||||
}
|
}
|
||||||
String? selectedDirectory = await FilePicker.platform
|
String? selectedDirectory = await FilePicker.platform
|
||||||
.getDirectoryPath(initialDirectory: initialDirectory);
|
.getDirectoryPath(initialDirectory: initialDirectory);
|
||||||
|
|||||||
@ -525,7 +525,7 @@ class _SettingsState extends State<SettingsPage> with WidgetsBindingObserver {
|
|||||||
builder: (ctx, data) => Offstage(
|
builder: (ctx, data) => Offstage(
|
||||||
offstage: !data.hasData,
|
offstage: !data.hasData,
|
||||||
child: Text("${translate("Directory")}: ${data.data}")),
|
child: Text("${translate("Directory")}: ${data.data}")),
|
||||||
future: bind.mainDefaultVideoSaveDirectory()),
|
future: bind.mainVideoSaveDirectory(root: false)),
|
||||||
initialValue: _autoRecordIncomingSession,
|
initialValue: _autoRecordIncomingSession,
|
||||||
onToggle: (v) async {
|
onToggle: (v) async {
|
||||||
await bind.mainSetOption(
|
await bind.mainSetOption(
|
||||||
|
|||||||
@ -943,7 +943,7 @@ class RustdeskImpl {
|
|||||||
throw UnimplementedError();
|
throw UnimplementedError();
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<String> mainDefaultVideoSaveDirectory({dynamic hint}) {
|
Future<String> mainVideoSaveDirectory({required bool root, dynamic hint}) {
|
||||||
throw UnimplementedError();
|
throw UnimplementedError();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -26,7 +26,7 @@ const MIN_SECS: u64 = 1;
|
|||||||
pub struct RecorderContext {
|
pub struct RecorderContext {
|
||||||
pub server: bool,
|
pub server: bool,
|
||||||
pub id: String,
|
pub id: String,
|
||||||
pub default_dir: String,
|
pub dir: String,
|
||||||
pub filename: String,
|
pub filename: String,
|
||||||
pub width: usize,
|
pub width: usize,
|
||||||
pub height: usize,
|
pub height: usize,
|
||||||
@ -36,18 +36,11 @@ pub struct RecorderContext {
|
|||||||
|
|
||||||
impl RecorderContext {
|
impl RecorderContext {
|
||||||
pub fn set_filename(&mut self) -> ResultType<()> {
|
pub fn set_filename(&mut self) -> ResultType<()> {
|
||||||
let mut dir = Config::get_option("video-save-directory");
|
if !PathBuf::from(&self.dir).exists() {
|
||||||
if !dir.is_empty() {
|
std::fs::create_dir_all(&self.dir)?;
|
||||||
if !PathBuf::from(&dir).exists() {
|
|
||||||
std::fs::create_dir_all(&dir)?;
|
|
||||||
}
|
}
|
||||||
} else {
|
let file = if self.server { "incoming" } else { "outgoing" }.to_string()
|
||||||
dir = self.default_dir.clone();
|
+ "_"
|
||||||
if !dir.is_empty() && !PathBuf::from(&dir).exists() {
|
|
||||||
std::fs::create_dir_all(&dir)?;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
let file = if self.server { "s" } else { "c" }.to_string()
|
|
||||||
+ &self.id.clone()
|
+ &self.id.clone()
|
||||||
+ &chrono::Local::now().format("_%Y%m%d%H%M%S%3f_").to_string()
|
+ &chrono::Local::now().format("_%Y%m%d%H%M%S%3f_").to_string()
|
||||||
+ &self.format.to_string().to_lowercase()
|
+ &self.format.to_string().to_lowercase()
|
||||||
@ -59,7 +52,10 @@ impl RecorderContext {
|
|||||||
} else {
|
} else {
|
||||||
".mp4"
|
".mp4"
|
||||||
};
|
};
|
||||||
self.filename = PathBuf::from(&dir).join(file).to_string_lossy().to_string();
|
self.filename = PathBuf::from(&self.dir)
|
||||||
|
.join(file)
|
||||||
|
.to_string_lossy()
|
||||||
|
.to_string();
|
||||||
log::info!("video will save to {}", self.filename);
|
log::info!("video will save to {}", self.filename);
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1112,7 +1112,7 @@ impl VideoHandler {
|
|||||||
self.recorder = Recorder::new(RecorderContext {
|
self.recorder = Recorder::new(RecorderContext {
|
||||||
server: false,
|
server: false,
|
||||||
id,
|
id,
|
||||||
default_dir: crate::ui_interface::default_video_save_directory(),
|
dir: crate::ui_interface::video_save_directory(false),
|
||||||
filename: "".to_owned(),
|
filename: "".to_owned(),
|
||||||
width: w as _,
|
width: w as _,
|
||||||
height: h as _,
|
height: h as _,
|
||||||
|
|||||||
@ -1145,8 +1145,8 @@ pub fn main_change_language(lang: String) {
|
|||||||
send_to_cm(&crate::ipc::Data::Language(lang));
|
send_to_cm(&crate::ipc::Data::Language(lang));
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn main_default_video_save_directory() -> String {
|
pub fn main_video_save_directory(root: bool) -> String {
|
||||||
default_video_save_directory()
|
video_save_directory(root)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn main_set_user_default_option(key: String, value: String) {
|
pub fn main_set_user_default_option(key: String, value: String) {
|
||||||
|
|||||||
@ -607,5 +607,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
|||||||
("Follow remote window focus", ""),
|
("Follow remote window focus", ""),
|
||||||
("default_proxy_tip", ""),
|
("default_proxy_tip", ""),
|
||||||
("no_audio_input_device_tip", ""),
|
("no_audio_input_device_tip", ""),
|
||||||
|
("Incoming", ""),
|
||||||
|
("Outgoing", ""),
|
||||||
].iter().cloned().collect();
|
].iter().cloned().collect();
|
||||||
}
|
}
|
||||||
|
|||||||
@ -607,5 +607,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
|||||||
("Follow remote window focus", ""),
|
("Follow remote window focus", ""),
|
||||||
("default_proxy_tip", ""),
|
("default_proxy_tip", ""),
|
||||||
("no_audio_input_device_tip", ""),
|
("no_audio_input_device_tip", ""),
|
||||||
|
("Incoming", ""),
|
||||||
|
("Outgoing", ""),
|
||||||
].iter().cloned().collect();
|
].iter().cloned().collect();
|
||||||
}
|
}
|
||||||
|
|||||||
@ -607,5 +607,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
|||||||
("Follow remote window focus", ""),
|
("Follow remote window focus", ""),
|
||||||
("default_proxy_tip", ""),
|
("default_proxy_tip", ""),
|
||||||
("no_audio_input_device_tip", ""),
|
("no_audio_input_device_tip", ""),
|
||||||
|
("Incoming", ""),
|
||||||
|
("Outgoing", ""),
|
||||||
].iter().cloned().collect();
|
].iter().cloned().collect();
|
||||||
}
|
}
|
||||||
|
|||||||
@ -607,5 +607,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
|||||||
("Follow remote window focus", "跟随远程窗口焦点"),
|
("Follow remote window focus", "跟随远程窗口焦点"),
|
||||||
("default_proxy_tip", "默认代理协议及端口为 Socks5 和 1080"),
|
("default_proxy_tip", "默认代理协议及端口为 Socks5 和 1080"),
|
||||||
("no_audio_input_device_tip", "未找到音频输入设备"),
|
("no_audio_input_device_tip", "未找到音频输入设备"),
|
||||||
|
("Incoming", "被控"),
|
||||||
|
("Outgoing", "主控"),
|
||||||
].iter().cloned().collect();
|
].iter().cloned().collect();
|
||||||
}
|
}
|
||||||
|
|||||||
@ -607,5 +607,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
|||||||
("Follow remote window focus", "Sledovat zaměření vzdáleného okna"),
|
("Follow remote window focus", "Sledovat zaměření vzdáleného okna"),
|
||||||
("default_proxy_tip", "Výchozí protokol a port jsou Socks5 a 1080"),
|
("default_proxy_tip", "Výchozí protokol a port jsou Socks5 a 1080"),
|
||||||
("no_audio_input_device_tip", "Nebylo nalezeno žádné vstupní zvukové zařízení."),
|
("no_audio_input_device_tip", "Nebylo nalezeno žádné vstupní zvukové zařízení."),
|
||||||
|
("Incoming", ""),
|
||||||
|
("Outgoing", ""),
|
||||||
].iter().cloned().collect();
|
].iter().cloned().collect();
|
||||||
}
|
}
|
||||||
|
|||||||
@ -607,5 +607,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
|||||||
("Follow remote window focus", ""),
|
("Follow remote window focus", ""),
|
||||||
("default_proxy_tip", ""),
|
("default_proxy_tip", ""),
|
||||||
("no_audio_input_device_tip", ""),
|
("no_audio_input_device_tip", ""),
|
||||||
|
("Incoming", ""),
|
||||||
|
("Outgoing", ""),
|
||||||
].iter().cloned().collect();
|
].iter().cloned().collect();
|
||||||
}
|
}
|
||||||
|
|||||||
@ -607,5 +607,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
|||||||
("Follow remote window focus", "Dem Fokus des entfernten Fensters folgen"),
|
("Follow remote window focus", "Dem Fokus des entfernten Fensters folgen"),
|
||||||
("default_proxy_tip", ""),
|
("default_proxy_tip", ""),
|
||||||
("no_audio_input_device_tip", ""),
|
("no_audio_input_device_tip", ""),
|
||||||
|
("Incoming", ""),
|
||||||
|
("Outgoing", ""),
|
||||||
].iter().cloned().collect();
|
].iter().cloned().collect();
|
||||||
}
|
}
|
||||||
|
|||||||
@ -607,5 +607,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
|||||||
("Follow remote window focus", ""),
|
("Follow remote window focus", ""),
|
||||||
("default_proxy_tip", ""),
|
("default_proxy_tip", ""),
|
||||||
("no_audio_input_device_tip", ""),
|
("no_audio_input_device_tip", ""),
|
||||||
|
("Incoming", ""),
|
||||||
|
("Outgoing", ""),
|
||||||
].iter().cloned().collect();
|
].iter().cloned().collect();
|
||||||
}
|
}
|
||||||
|
|||||||
@ -607,5 +607,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
|||||||
("Follow remote window focus", ""),
|
("Follow remote window focus", ""),
|
||||||
("default_proxy_tip", ""),
|
("default_proxy_tip", ""),
|
||||||
("no_audio_input_device_tip", ""),
|
("no_audio_input_device_tip", ""),
|
||||||
|
("Incoming", ""),
|
||||||
|
("Outgoing", ""),
|
||||||
].iter().cloned().collect();
|
].iter().cloned().collect();
|
||||||
}
|
}
|
||||||
|
|||||||
@ -607,5 +607,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
|||||||
("Follow remote window focus", "Seguir ventana remota activa"),
|
("Follow remote window focus", "Seguir ventana remota activa"),
|
||||||
("default_proxy_tip", ""),
|
("default_proxy_tip", ""),
|
||||||
("no_audio_input_device_tip", ""),
|
("no_audio_input_device_tip", ""),
|
||||||
|
("Incoming", ""),
|
||||||
|
("Outgoing", ""),
|
||||||
].iter().cloned().collect();
|
].iter().cloned().collect();
|
||||||
}
|
}
|
||||||
|
|||||||
@ -607,5 +607,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
|||||||
("Follow remote window focus", ""),
|
("Follow remote window focus", ""),
|
||||||
("default_proxy_tip", ""),
|
("default_proxy_tip", ""),
|
||||||
("no_audio_input_device_tip", ""),
|
("no_audio_input_device_tip", ""),
|
||||||
|
("Incoming", ""),
|
||||||
|
("Outgoing", ""),
|
||||||
].iter().cloned().collect();
|
].iter().cloned().collect();
|
||||||
}
|
}
|
||||||
|
|||||||
@ -607,5 +607,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
|||||||
("Follow remote window focus", ""),
|
("Follow remote window focus", ""),
|
||||||
("default_proxy_tip", ""),
|
("default_proxy_tip", ""),
|
||||||
("no_audio_input_device_tip", ""),
|
("no_audio_input_device_tip", ""),
|
||||||
|
("Incoming", ""),
|
||||||
|
("Outgoing", ""),
|
||||||
].iter().cloned().collect();
|
].iter().cloned().collect();
|
||||||
}
|
}
|
||||||
|
|||||||
@ -607,5 +607,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
|||||||
("Follow remote window focus", ""),
|
("Follow remote window focus", ""),
|
||||||
("default_proxy_tip", ""),
|
("default_proxy_tip", ""),
|
||||||
("no_audio_input_device_tip", ""),
|
("no_audio_input_device_tip", ""),
|
||||||
|
("Incoming", ""),
|
||||||
|
("Outgoing", ""),
|
||||||
].iter().cloned().collect();
|
].iter().cloned().collect();
|
||||||
}
|
}
|
||||||
|
|||||||
@ -607,5 +607,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
|||||||
("Follow remote window focus", ""),
|
("Follow remote window focus", ""),
|
||||||
("default_proxy_tip", ""),
|
("default_proxy_tip", ""),
|
||||||
("no_audio_input_device_tip", ""),
|
("no_audio_input_device_tip", ""),
|
||||||
|
("Incoming", ""),
|
||||||
|
("Outgoing", ""),
|
||||||
].iter().cloned().collect();
|
].iter().cloned().collect();
|
||||||
}
|
}
|
||||||
|
|||||||
@ -607,5 +607,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
|||||||
("Follow remote window focus", ""),
|
("Follow remote window focus", ""),
|
||||||
("default_proxy_tip", ""),
|
("default_proxy_tip", ""),
|
||||||
("no_audio_input_device_tip", ""),
|
("no_audio_input_device_tip", ""),
|
||||||
|
("Incoming", ""),
|
||||||
|
("Outgoing", ""),
|
||||||
].iter().cloned().collect();
|
].iter().cloned().collect();
|
||||||
}
|
}
|
||||||
|
|||||||
@ -607,5 +607,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
|||||||
("Follow remote window focus", ""),
|
("Follow remote window focus", ""),
|
||||||
("default_proxy_tip", ""),
|
("default_proxy_tip", ""),
|
||||||
("no_audio_input_device_tip", ""),
|
("no_audio_input_device_tip", ""),
|
||||||
|
("Incoming", ""),
|
||||||
|
("Outgoing", ""),
|
||||||
].iter().cloned().collect();
|
].iter().cloned().collect();
|
||||||
}
|
}
|
||||||
|
|||||||
@ -607,5 +607,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
|||||||
("Follow remote window focus", ""),
|
("Follow remote window focus", ""),
|
||||||
("default_proxy_tip", ""),
|
("default_proxy_tip", ""),
|
||||||
("no_audio_input_device_tip", ""),
|
("no_audio_input_device_tip", ""),
|
||||||
|
("Incoming", ""),
|
||||||
|
("Outgoing", ""),
|
||||||
].iter().cloned().collect();
|
].iter().cloned().collect();
|
||||||
}
|
}
|
||||||
|
|||||||
@ -607,5 +607,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
|||||||
("Follow remote window focus", "Segui focus finestra remota"),
|
("Follow remote window focus", "Segui focus finestra remota"),
|
||||||
("default_proxy_tip", "Protocollo e porta predefiniti sono Socks5 e 1080"),
|
("default_proxy_tip", "Protocollo e porta predefiniti sono Socks5 e 1080"),
|
||||||
("no_audio_input_device_tip", "Nessun dispositivo input audio trovato."),
|
("no_audio_input_device_tip", "Nessun dispositivo input audio trovato."),
|
||||||
|
("Incoming", ""),
|
||||||
|
("Outgoing", ""),
|
||||||
].iter().cloned().collect();
|
].iter().cloned().collect();
|
||||||
}
|
}
|
||||||
|
|||||||
@ -607,5 +607,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
|||||||
("Follow remote window focus", ""),
|
("Follow remote window focus", ""),
|
||||||
("default_proxy_tip", ""),
|
("default_proxy_tip", ""),
|
||||||
("no_audio_input_device_tip", ""),
|
("no_audio_input_device_tip", ""),
|
||||||
|
("Incoming", ""),
|
||||||
|
("Outgoing", ""),
|
||||||
].iter().cloned().collect();
|
].iter().cloned().collect();
|
||||||
}
|
}
|
||||||
|
|||||||
@ -607,5 +607,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
|||||||
("Follow remote window focus", ""),
|
("Follow remote window focus", ""),
|
||||||
("default_proxy_tip", ""),
|
("default_proxy_tip", ""),
|
||||||
("no_audio_input_device_tip", ""),
|
("no_audio_input_device_tip", ""),
|
||||||
|
("Incoming", ""),
|
||||||
|
("Outgoing", ""),
|
||||||
].iter().cloned().collect();
|
].iter().cloned().collect();
|
||||||
}
|
}
|
||||||
|
|||||||
@ -607,5 +607,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
|||||||
("Follow remote window focus", ""),
|
("Follow remote window focus", ""),
|
||||||
("default_proxy_tip", ""),
|
("default_proxy_tip", ""),
|
||||||
("no_audio_input_device_tip", ""),
|
("no_audio_input_device_tip", ""),
|
||||||
|
("Incoming", ""),
|
||||||
|
("Outgoing", ""),
|
||||||
].iter().cloned().collect();
|
].iter().cloned().collect();
|
||||||
}
|
}
|
||||||
|
|||||||
@ -607,5 +607,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
|||||||
("Follow remote window focus", ""),
|
("Follow remote window focus", ""),
|
||||||
("default_proxy_tip", ""),
|
("default_proxy_tip", ""),
|
||||||
("no_audio_input_device_tip", ""),
|
("no_audio_input_device_tip", ""),
|
||||||
|
("Incoming", ""),
|
||||||
|
("Outgoing", ""),
|
||||||
].iter().cloned().collect();
|
].iter().cloned().collect();
|
||||||
}
|
}
|
||||||
|
|||||||
@ -607,5 +607,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
|||||||
("Follow remote window focus", "Sekot attālā loga fokusam"),
|
("Follow remote window focus", "Sekot attālā loga fokusam"),
|
||||||
("default_proxy_tip", ""),
|
("default_proxy_tip", ""),
|
||||||
("no_audio_input_device_tip", ""),
|
("no_audio_input_device_tip", ""),
|
||||||
|
("Incoming", ""),
|
||||||
|
("Outgoing", ""),
|
||||||
].iter().cloned().collect();
|
].iter().cloned().collect();
|
||||||
}
|
}
|
||||||
|
|||||||
@ -607,5 +607,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
|||||||
("Follow remote window focus", ""),
|
("Follow remote window focus", ""),
|
||||||
("default_proxy_tip", ""),
|
("default_proxy_tip", ""),
|
||||||
("no_audio_input_device_tip", ""),
|
("no_audio_input_device_tip", ""),
|
||||||
|
("Incoming", ""),
|
||||||
|
("Outgoing", ""),
|
||||||
].iter().cloned().collect();
|
].iter().cloned().collect();
|
||||||
}
|
}
|
||||||
|
|||||||
@ -607,5 +607,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
|||||||
("Follow remote window focus", "Volg de focus van het venster op afstand"),
|
("Follow remote window focus", "Volg de focus van het venster op afstand"),
|
||||||
("default_proxy_tip", ""),
|
("default_proxy_tip", ""),
|
||||||
("no_audio_input_device_tip", ""),
|
("no_audio_input_device_tip", ""),
|
||||||
|
("Incoming", ""),
|
||||||
|
("Outgoing", ""),
|
||||||
].iter().cloned().collect();
|
].iter().cloned().collect();
|
||||||
}
|
}
|
||||||
|
|||||||
@ -607,5 +607,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
|||||||
("Follow remote window focus", "Podążaj za aktywnością zdalnych okien"),
|
("Follow remote window focus", "Podążaj za aktywnością zdalnych okien"),
|
||||||
("default_proxy_tip", ""),
|
("default_proxy_tip", ""),
|
||||||
("no_audio_input_device_tip", ""),
|
("no_audio_input_device_tip", ""),
|
||||||
|
("Incoming", ""),
|
||||||
|
("Outgoing", ""),
|
||||||
].iter().cloned().collect();
|
].iter().cloned().collect();
|
||||||
}
|
}
|
||||||
|
|||||||
@ -607,5 +607,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
|||||||
("Follow remote window focus", ""),
|
("Follow remote window focus", ""),
|
||||||
("default_proxy_tip", ""),
|
("default_proxy_tip", ""),
|
||||||
("no_audio_input_device_tip", ""),
|
("no_audio_input_device_tip", ""),
|
||||||
|
("Incoming", ""),
|
||||||
|
("Outgoing", ""),
|
||||||
].iter().cloned().collect();
|
].iter().cloned().collect();
|
||||||
}
|
}
|
||||||
|
|||||||
@ -607,5 +607,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
|||||||
("Follow remote window focus", ""),
|
("Follow remote window focus", ""),
|
||||||
("default_proxy_tip", ""),
|
("default_proxy_tip", ""),
|
||||||
("no_audio_input_device_tip", ""),
|
("no_audio_input_device_tip", ""),
|
||||||
|
("Incoming", ""),
|
||||||
|
("Outgoing", ""),
|
||||||
].iter().cloned().collect();
|
].iter().cloned().collect();
|
||||||
}
|
}
|
||||||
|
|||||||
@ -607,5 +607,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
|||||||
("Follow remote window focus", ""),
|
("Follow remote window focus", ""),
|
||||||
("default_proxy_tip", ""),
|
("default_proxy_tip", ""),
|
||||||
("no_audio_input_device_tip", ""),
|
("no_audio_input_device_tip", ""),
|
||||||
|
("Incoming", ""),
|
||||||
|
("Outgoing", ""),
|
||||||
].iter().cloned().collect();
|
].iter().cloned().collect();
|
||||||
}
|
}
|
||||||
|
|||||||
@ -607,5 +607,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
|||||||
("Follow remote window focus", "Следовать за фокусом удалённого окна"),
|
("Follow remote window focus", "Следовать за фокусом удалённого окна"),
|
||||||
("default_proxy_tip", ""),
|
("default_proxy_tip", ""),
|
||||||
("no_audio_input_device_tip", ""),
|
("no_audio_input_device_tip", ""),
|
||||||
|
("Incoming", ""),
|
||||||
|
("Outgoing", ""),
|
||||||
].iter().cloned().collect();
|
].iter().cloned().collect();
|
||||||
}
|
}
|
||||||
|
|||||||
@ -607,5 +607,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
|||||||
("Follow remote window focus", "Nasledovať vzdialené zameranie okna"),
|
("Follow remote window focus", "Nasledovať vzdialené zameranie okna"),
|
||||||
("default_proxy_tip", "Predvolený protokol a port sú Socks5 a 1080"),
|
("default_proxy_tip", "Predvolený protokol a port sú Socks5 a 1080"),
|
||||||
("no_audio_input_device_tip", "Nenašlo sa žiadne vstupné zvukové zariadenie."),
|
("no_audio_input_device_tip", "Nenašlo sa žiadne vstupné zvukové zariadenie."),
|
||||||
|
("Incoming", ""),
|
||||||
|
("Outgoing", ""),
|
||||||
].iter().cloned().collect();
|
].iter().cloned().collect();
|
||||||
}
|
}
|
||||||
|
|||||||
@ -607,5 +607,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
|||||||
("Follow remote window focus", ""),
|
("Follow remote window focus", ""),
|
||||||
("default_proxy_tip", ""),
|
("default_proxy_tip", ""),
|
||||||
("no_audio_input_device_tip", ""),
|
("no_audio_input_device_tip", ""),
|
||||||
|
("Incoming", ""),
|
||||||
|
("Outgoing", ""),
|
||||||
].iter().cloned().collect();
|
].iter().cloned().collect();
|
||||||
}
|
}
|
||||||
|
|||||||
@ -607,5 +607,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
|||||||
("Follow remote window focus", ""),
|
("Follow remote window focus", ""),
|
||||||
("default_proxy_tip", ""),
|
("default_proxy_tip", ""),
|
||||||
("no_audio_input_device_tip", ""),
|
("no_audio_input_device_tip", ""),
|
||||||
|
("Incoming", ""),
|
||||||
|
("Outgoing", ""),
|
||||||
].iter().cloned().collect();
|
].iter().cloned().collect();
|
||||||
}
|
}
|
||||||
|
|||||||
@ -607,5 +607,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
|||||||
("Follow remote window focus", ""),
|
("Follow remote window focus", ""),
|
||||||
("default_proxy_tip", ""),
|
("default_proxy_tip", ""),
|
||||||
("no_audio_input_device_tip", ""),
|
("no_audio_input_device_tip", ""),
|
||||||
|
("Incoming", ""),
|
||||||
|
("Outgoing", ""),
|
||||||
].iter().cloned().collect();
|
].iter().cloned().collect();
|
||||||
}
|
}
|
||||||
|
|||||||
@ -607,5 +607,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
|||||||
("Follow remote window focus", ""),
|
("Follow remote window focus", ""),
|
||||||
("default_proxy_tip", ""),
|
("default_proxy_tip", ""),
|
||||||
("no_audio_input_device_tip", ""),
|
("no_audio_input_device_tip", ""),
|
||||||
|
("Incoming", ""),
|
||||||
|
("Outgoing", ""),
|
||||||
].iter().cloned().collect();
|
].iter().cloned().collect();
|
||||||
}
|
}
|
||||||
|
|||||||
@ -607,5 +607,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
|||||||
("Follow remote window focus", ""),
|
("Follow remote window focus", ""),
|
||||||
("default_proxy_tip", ""),
|
("default_proxy_tip", ""),
|
||||||
("no_audio_input_device_tip", ""),
|
("no_audio_input_device_tip", ""),
|
||||||
|
("Incoming", ""),
|
||||||
|
("Outgoing", ""),
|
||||||
].iter().cloned().collect();
|
].iter().cloned().collect();
|
||||||
}
|
}
|
||||||
|
|||||||
@ -607,5 +607,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
|||||||
("Follow remote window focus", ""),
|
("Follow remote window focus", ""),
|
||||||
("default_proxy_tip", ""),
|
("default_proxy_tip", ""),
|
||||||
("no_audio_input_device_tip", ""),
|
("no_audio_input_device_tip", ""),
|
||||||
|
("Incoming", ""),
|
||||||
|
("Outgoing", ""),
|
||||||
].iter().cloned().collect();
|
].iter().cloned().collect();
|
||||||
}
|
}
|
||||||
|
|||||||
@ -607,5 +607,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
|||||||
("Follow remote window focus", ""),
|
("Follow remote window focus", ""),
|
||||||
("default_proxy_tip", ""),
|
("default_proxy_tip", ""),
|
||||||
("no_audio_input_device_tip", ""),
|
("no_audio_input_device_tip", ""),
|
||||||
|
("Incoming", ""),
|
||||||
|
("Outgoing", ""),
|
||||||
].iter().cloned().collect();
|
].iter().cloned().collect();
|
||||||
}
|
}
|
||||||
|
|||||||
@ -607,5 +607,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
|||||||
("Follow remote window focus", "跟隨遠端視窗焦點"),
|
("Follow remote window focus", "跟隨遠端視窗焦點"),
|
||||||
("default_proxy_tip", ""),
|
("default_proxy_tip", ""),
|
||||||
("no_audio_input_device_tip", ""),
|
("no_audio_input_device_tip", ""),
|
||||||
|
("Incoming", ""),
|
||||||
|
("Outgoing", ""),
|
||||||
].iter().cloned().collect();
|
].iter().cloned().collect();
|
||||||
}
|
}
|
||||||
|
|||||||
@ -607,5 +607,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
|||||||
("Follow remote window focus", ""),
|
("Follow remote window focus", ""),
|
||||||
("default_proxy_tip", ""),
|
("default_proxy_tip", ""),
|
||||||
("no_audio_input_device_tip", ""),
|
("no_audio_input_device_tip", ""),
|
||||||
|
("Incoming", ""),
|
||||||
|
("Outgoing", ""),
|
||||||
].iter().cloned().collect();
|
].iter().cloned().collect();
|
||||||
}
|
}
|
||||||
|
|||||||
@ -607,5 +607,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
|||||||
("Follow remote window focus", ""),
|
("Follow remote window focus", ""),
|
||||||
("default_proxy_tip", ""),
|
("default_proxy_tip", ""),
|
||||||
("no_audio_input_device_tip", ""),
|
("no_audio_input_device_tip", ""),
|
||||||
|
("Incoming", ""),
|
||||||
|
("Outgoing", ""),
|
||||||
].iter().cloned().collect();
|
].iter().cloned().collect();
|
||||||
}
|
}
|
||||||
|
|||||||
@ -53,7 +53,7 @@ use scrap::{
|
|||||||
codec::{Encoder, EncoderCfg, Quality},
|
codec::{Encoder, EncoderCfg, Quality},
|
||||||
record::{Recorder, RecorderContext},
|
record::{Recorder, RecorderContext},
|
||||||
vpxcodec::{VpxEncoderConfig, VpxVideoCodecId},
|
vpxcodec::{VpxEncoderConfig, VpxVideoCodecId},
|
||||||
CodecFormat, CodecName, Display, Frame, TraitCapturer,
|
CodecFormat, Display, Frame, TraitCapturer,
|
||||||
};
|
};
|
||||||
#[cfg(windows)]
|
#[cfg(windows)]
|
||||||
use std::sync::Once;
|
use std::sync::Once;
|
||||||
@ -752,6 +752,10 @@ fn get_recorder(
|
|||||||
codec_format: &CodecFormat,
|
codec_format: &CodecFormat,
|
||||||
record_incoming: bool,
|
record_incoming: bool,
|
||||||
) -> Arc<Mutex<Option<Recorder>>> {
|
) -> Arc<Mutex<Option<Recorder>>> {
|
||||||
|
#[cfg(windows)]
|
||||||
|
let root = crate::platform::is_root();
|
||||||
|
#[cfg(not(windows))]
|
||||||
|
let root = false;
|
||||||
let recorder = if record_incoming {
|
let recorder = if record_incoming {
|
||||||
use crate::hbbs_http::record_upload;
|
use crate::hbbs_http::record_upload;
|
||||||
|
|
||||||
@ -765,7 +769,7 @@ fn get_recorder(
|
|||||||
Recorder::new(RecorderContext {
|
Recorder::new(RecorderContext {
|
||||||
server: true,
|
server: true,
|
||||||
id: Config::get_id(),
|
id: Config::get_id(),
|
||||||
default_dir: crate::ui_interface::default_video_save_directory(),
|
dir: crate::ui_interface::video_save_directory(root),
|
||||||
filename: "".to_owned(),
|
filename: "".to_owned(),
|
||||||
width,
|
width,
|
||||||
height,
|
height,
|
||||||
|
|||||||
@ -600,8 +600,8 @@ impl UI {
|
|||||||
get_langs()
|
get_langs()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn default_video_save_directory(&self) -> String {
|
fn video_save_directory(&self, root: bool) -> String {
|
||||||
default_video_save_directory()
|
video_save_directory(root)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn handle_relay_id(&self, id: String) -> String {
|
fn handle_relay_id(&self, id: String) -> String {
|
||||||
@ -723,7 +723,7 @@ impl sciter::EventHandler for UI {
|
|||||||
fn has_hwcodec();
|
fn has_hwcodec();
|
||||||
fn has_vram();
|
fn has_vram();
|
||||||
fn get_langs();
|
fn get_langs();
|
||||||
fn default_video_save_directory();
|
fn video_save_directory(bool);
|
||||||
fn handle_relay_id(String);
|
fn handle_relay_id(String);
|
||||||
fn get_login_device_info();
|
fn get_login_device_info();
|
||||||
fn support_remove_wallpaper();
|
fn support_remove_wallpaper();
|
||||||
|
|||||||
@ -248,8 +248,9 @@ class Enhancements: Reactor.Component {
|
|||||||
} else if (v.indexOf("allow-") == 0) {
|
} else if (v.indexOf("allow-") == 0) {
|
||||||
handler.set_option(v, handler.get_option(v) == 'Y' ? '' : 'Y');
|
handler.set_option(v, handler.get_option(v) == 'Y' ? '' : 'Y');
|
||||||
} else if (v == 'screen-recording') {
|
} else if (v == 'screen-recording') {
|
||||||
var dir = handler.get_option("video-save-directory");
|
var show_root_dir = is_win && handler.is_installed();
|
||||||
if (!dir) dir = handler.default_video_save_directory();
|
var user_dir = handler.video_save_directory(false);
|
||||||
|
var root_dir = show_root_dir ? handler.video_save_directory(true) : "";
|
||||||
var ts0 = handler.get_option("enable-record-session") == '' ? { checked: true } : {};
|
var ts0 = handler.get_option("enable-record-session") == '' ? { checked: true } : {};
|
||||||
var ts1 = handler.get_option("allow-auto-record-incoming") == 'Y' ? { checked: true } : {};
|
var ts1 = handler.get_option("allow-auto-record-incoming") == 'Y' ? { checked: true } : {};
|
||||||
msgbox("custom-recording", translate('Recording'),
|
msgbox("custom-recording", translate('Recording'),
|
||||||
@ -257,7 +258,8 @@ class Enhancements: Reactor.Component {
|
|||||||
<div><button|checkbox(enable_record_session) {ts0}>{translate('Enable recording session')}</button></div>
|
<div><button|checkbox(enable_record_session) {ts0}>{translate('Enable recording session')}</button></div>
|
||||||
<div><button|checkbox(auto_record_incoming) {ts1}>{translate('Automatically record incoming sessions')}</button></div>
|
<div><button|checkbox(auto_record_incoming) {ts1}>{translate('Automatically record incoming sessions')}</button></div>
|
||||||
<div>
|
<div>
|
||||||
<div style="word-wrap:break-word"><span>{translate("Directory")}: </span><span #folderPath>{dir}</span></div>
|
{show_root_dir ? <div style="word-wrap:break-word"><span>{translate("Incoming")}: </span><span>{root_dir}</span></div> : ""}
|
||||||
|
<div style="word-wrap:break-word"><span>{translate(show_root_dir ? "Outgoing" : "Directory")}: </span><span #folderPath>{user_dir}</span></div>
|
||||||
<div> <button #select_directory .link>{translate('Change')}</button> </div>
|
<div> <button #select_directory .link>{translate('Change')}</button> </div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@ -778,7 +778,7 @@ pub fn get_langs() -> String {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn default_video_save_directory() -> String {
|
pub fn video_save_directory(root: bool) -> String {
|
||||||
let appname = crate::get_app_name();
|
let appname = crate::get_app_name();
|
||||||
// ui process can show it correctly Once vidoe process created it.
|
// ui process can show it correctly Once vidoe process created it.
|
||||||
let try_create = |path: &std::path::Path| {
|
let try_create = |path: &std::path::Path| {
|
||||||
@ -792,6 +792,20 @@ pub fn default_video_save_directory() -> String {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
if root {
|
||||||
|
// Currently, only installed windows run as root
|
||||||
|
#[cfg(windows)]
|
||||||
|
{
|
||||||
|
let drive = std::env::var("SystemDrive").unwrap_or("C:".to_owned());
|
||||||
|
let dir =
|
||||||
|
std::path::PathBuf::from(format!("{drive}\\ProgramData\\RustDesk\\recording",));
|
||||||
|
return dir.to_string_lossy().to_string();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
let dir = Config::get_option("video-save-directory");
|
||||||
|
if !dir.is_empty() {
|
||||||
|
return dir;
|
||||||
|
}
|
||||||
#[cfg(any(target_os = "android", target_os = "ios"))]
|
#[cfg(any(target_os = "android", target_os = "ios"))]
|
||||||
if let Ok(home) = config::APP_HOME_DIR.read() {
|
if let Ok(home) = config::APP_HOME_DIR.read() {
|
||||||
let mut path = home.to_owned();
|
let mut path = home.to_owned();
|
||||||
@ -858,7 +872,7 @@ pub fn default_video_save_directory() -> String {
|
|||||||
return parent.to_string_lossy().to_string();
|
return parent.to_string_lossy().to_string();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
"".to_owned()
|
Default::default()
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user