auto record outgoing (#9711)

* Add option auto record outgoing session
* In the same connection, all displays and all windows share the same
  recording state.

todo:

Android check external storage permission

Known issue:

* Sciter old issue, stop the process directly without stop record, the record file can't play.

Signed-off-by: 21pages <sunboeasy@gmail.com>
This commit is contained in:
21pages
2024-10-21 14:34:06 +08:00
committed by GitHub
parent 289076aa70
commit e8187588c1
65 changed files with 442 additions and 322 deletions

View File

@@ -30,7 +30,6 @@ pub use file_trait::FileManager;
#[cfg(not(feature = "flutter"))]
#[cfg(not(any(target_os = "android", target_os = "ios")))]
use hbb_common::tokio::sync::mpsc::UnboundedSender;
use hbb_common::tokio::sync::mpsc::{unbounded_channel, UnboundedReceiver};
use hbb_common::{
allow_err,
anyhow::{anyhow, Context},
@@ -54,11 +53,15 @@ use hbb_common::{
},
AddrMangle, ResultType, Stream,
};
use hbb_common::{
config::keys::OPTION_ALLOW_AUTO_RECORD_OUTGOING,
tokio::sync::mpsc::{unbounded_channel, UnboundedReceiver},
};
pub use helper::*;
use scrap::{
codec::Decoder,
record::{Recorder, RecorderContext},
CodecFormat, ImageFormat, ImageRgb,
CodecFormat, ImageFormat, ImageRgb, ImageTexture,
};
use crate::{
@@ -1146,7 +1149,7 @@ impl AudioHandler {
pub struct VideoHandler {
decoder: Decoder,
pub rgb: ImageRgb,
pub texture: *mut c_void,
pub texture: ImageTexture,
recorder: Arc<Mutex<Option<Recorder>>>,
record: bool,
_display: usize, // useful for debug
@@ -1172,7 +1175,7 @@ impl VideoHandler {
VideoHandler {
decoder: Decoder::new(format, luid),
rgb: ImageRgb::new(ImageFormat::ARGB, crate::get_dst_align_rgba()),
texture: std::ptr::null_mut(),
texture: Default::default(),
recorder: Default::default(),
record: false,
_display,
@@ -1220,11 +1223,14 @@ impl VideoHandler {
}
self.first_frame = false;
if self.record {
self.recorder
.lock()
.unwrap()
.as_mut()
.map(|r| r.write_frame(frame));
self.recorder.lock().unwrap().as_mut().map(|r| {
let (w, h) = if *pixelbuffer {
(self.rgb.w, self.rgb.h)
} else {
(self.texture.w, self.texture.h)
};
r.write_frame(frame, w, h).ok();
});
}
res
}
@@ -1248,17 +1254,14 @@ impl VideoHandler {
}
/// Start or stop screen record.
pub fn record_screen(&mut self, start: bool, w: i32, h: i32, id: String) {
pub fn record_screen(&mut self, start: bool, id: String, display: usize) {
self.record = false;
if start {
self.recorder = Recorder::new(RecorderContext {
server: false,
id,
dir: crate::ui_interface::video_save_directory(false),
filename: "".to_owned(),
width: w as _,
height: h as _,
format: scrap::CodecFormat::VP9,
display,
tx: None,
})
.map_or(Default::default(), |r| Arc::new(Mutex::new(Some(r))));
@@ -1347,6 +1350,7 @@ pub struct LoginConfigHandler {
password_source: PasswordSource, // where the sent password comes from
shared_password: Option<String>, // Store the shared password
pub enable_trusted_devices: bool,
pub record: bool,
}
impl Deref for LoginConfigHandler {
@@ -1438,6 +1442,7 @@ impl LoginConfigHandler {
self.adapter_luid = adapter_luid;
self.selected_windows_session_id = None;
self.shared_password = shared_password;
self.record = Config::get_bool_option(OPTION_ALLOW_AUTO_RECORD_OUTGOING);
}
/// Check if the client should auto login.
@@ -2227,7 +2232,7 @@ pub enum MediaData {
AudioFrame(Box<AudioFrame>),
AudioFormat(AudioFormat),
Reset(Option<usize>),
RecordScreen(bool, usize, i32, i32, String),
RecordScreen(bool),
}
pub type MediaSender = mpsc::Sender<MediaData>;
@@ -2303,10 +2308,16 @@ where
let start = std::time::Instant::now();
let format = CodecFormat::from(&vf);
if !handler_controller_map.contains_key(&display) {
let mut handler = VideoHandler::new(format, display);
let record = session.lc.read().unwrap().record;
let id = session.lc.read().unwrap().id.clone();
if record {
handler.record_screen(record, id, display);
}
handler_controller_map.insert(
display,
VideoHandlerController {
handler: VideoHandler::new(format, display),
handler,
skip_beginning: 0,
},
);
@@ -2325,7 +2336,7 @@ where
video_callback(
display,
&mut handler_controller.handler.rgb,
handler_controller.handler.texture,
handler_controller.handler.texture.texture,
pixelbuffer,
);
@@ -2399,18 +2410,19 @@ where
}
}
}
MediaData::RecordScreen(start, display, w, h, id) => {
log::info!("record screen command: start: {start}, display: {display}");
// Compatible with the sciter version(single ui session).
// For the sciter version, there're no multi-ui-sessions for one connection.
// The display is always 0, video_handler_controllers.len() is always 1. So we use the first video handler.
if let Some(handler_controler) = handler_controller_map.get_mut(&display) {
handler_controler.handler.record_screen(start, w, h, id);
} else if handler_controller_map.len() == 1 {
if let Some(handler_controler) =
handler_controller_map.values_mut().next()
{
handler_controler.handler.record_screen(start, w, h, id);
MediaData::RecordScreen(start) => {
log::info!("record screen command: start: {start}");
let record = session.lc.read().unwrap().record;
session.update_record_status(start);
if record != start {
session.lc.write().unwrap().record = start;
let id = session.lc.read().unwrap().id.clone();
for (display, handler_controler) in handler_controller_map.iter_mut() {
handler_controler.handler.record_screen(
start,
id.clone(),
*display,
);
}
}
}
@@ -3169,7 +3181,7 @@ pub enum Data {
SetConfirmOverrideFile((i32, i32, bool, bool, bool)),
AddJob((i32, String, String, i32, bool, bool)),
ResumeJob((i32, bool)),
RecordScreen(bool, usize, i32, i32, String),
RecordScreen(bool),
ElevateDirect,
ElevateWithLogon(String, String),
NewVoiceCall,

View File

@@ -837,10 +837,8 @@ impl<T: InvokeUiSession> Remote<T> {
self.handle_job_status(id, -1, err);
}
}
Data::RecordScreen(start, display, w, h, id) => {
let _ = self
.video_sender
.send(MediaData::RecordScreen(start, display, w, h, id));
Data::RecordScreen(start) => {
let _ = self.video_sender.send(MediaData::RecordScreen(start));
}
Data::ElevateDirect => {
let mut request = ElevationRequest::new();
@@ -1218,7 +1216,7 @@ impl<T: InvokeUiSession> Remote<T> {
crate::plugin::handle_listen_event(
crate::plugin::EVENT_ON_CONN_CLIENT.to_owned(),
self.handler.get_id(),
)
);
}
if self.handler.is_file_transfer() {

View File

@@ -17,7 +17,7 @@ use serde::Serialize;
use serde_json::json;
use std::{
collections::HashMap,
collections::{HashMap, HashSet},
ffi::CString,
os::raw::{c_char, c_int, c_void},
str::FromStr,
@@ -1010,6 +1010,10 @@ impl InvokeUiSession for FlutterHandler {
rgba_data.valid = false;
}
}
fn update_record_status(&self, start: bool) {
self.push_event("record_status", &[("start", &start.to_string())], &[]);
}
}
impl FlutterHandler {
@@ -1830,7 +1834,6 @@ pub(super) fn session_update_virtual_display(session: &FlutterSession, index: i3
// sessions mod is used to avoid the big lock of sessions' map.
pub mod sessions {
use std::collections::HashSet;
use super::*;

View File

@@ -241,21 +241,17 @@ pub fn session_is_multi_ui_session(session_id: SessionID) -> SyncReturn<bool> {
}
}
pub fn session_record_screen(
session_id: SessionID,
start: bool,
display: usize,
width: usize,
height: usize,
) {
pub fn session_record_screen(session_id: SessionID, start: bool) {
if let Some(session) = sessions::get_session_by_session_id(&session_id) {
session.record_screen(start, display as _, width as _, height as _);
session.record_screen(start);
}
}
pub fn session_record_status(session_id: SessionID, status: bool) {
pub fn session_get_is_recording(session_id: SessionID) -> SyncReturn<bool> {
if let Some(session) = sessions::get_session_by_session_id(&session_id) {
session.record_status(status);
SyncReturn(session.is_recording())
} else {
SyncReturn(false)
}
}

View File

@@ -364,6 +364,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("Recording", "التسجيل"),
("Directory", "المسار"),
("Automatically record incoming sessions", "تسجيل الجلسات القادمة تلقائيا"),
("Automatically record outgoing sessions", ""),
("Change", "تغيير"),
("Start session recording", "بدء تسجيل الجلسة"),
("Stop session recording", "ايقاف تسجيل الجلسة"),

View File

@@ -364,6 +364,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("Recording", "Запіс"),
("Directory", "Тэчка"),
("Automatically record incoming sessions", "Аўтаматычна запісваць уваходныя сесіі"),
("Automatically record outgoing sessions", ""),
("Change", "Змяніць"),
("Start session recording", "Пачаць запіс сесіі"),
("Stop session recording", "Спыніць запіс сесіі"),

View File

@@ -364,6 +364,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("Recording", "Записване"),
("Directory", "Директория"),
("Automatically record incoming sessions", "Автоматичен запис на входящи сесии"),
("Automatically record outgoing sessions", ""),
("Change", "Промяна"),
("Start session recording", "Започванена запис"),
("Stop session recording", "Край на запис"),

View File

@@ -364,6 +364,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("Recording", "Gravació"),
("Directory", "Contactes"),
("Automatically record incoming sessions", "Enregistrament automàtic de sessions entrants"),
("Automatically record outgoing sessions", ""),
("Change", "Canvia"),
("Start session recording", "Inicia la gravació de la sessió"),
("Stop session recording", "Atura la gravació de la sessió"),

View File

@@ -363,7 +363,8 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("Unpin Toolbar", "取消固定工具栏"),
("Recording", "录屏"),
("Directory", "目录"),
("Automatically record incoming sessions", "自动录制来访会话"),
("Automatically record incoming sessions", "自动录制传入会话"),
("Automatically record outgoing sessions", "自动录制传出会话"),
("Change", "更改"),
("Start session recording", "开始录屏"),
("Stop session recording", "结束录屏"),

View File

@@ -364,6 +364,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("Recording", "Nahrávání"),
("Directory", "Adresář"),
("Automatically record incoming sessions", "Automaticky nahrávat příchozí relace"),
("Automatically record outgoing sessions", ""),
("Change", "Změnit"),
("Start session recording", "Spustit záznam relace"),
("Stop session recording", "Zastavit záznam relace"),

View File

@@ -364,6 +364,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("Recording", "Optager"),
("Directory", "Mappe"),
("Automatically record incoming sessions", "Optag automatisk indgående sessioner"),
("Automatically record outgoing sessions", ""),
("Change", "Ændr"),
("Start session recording", "Start sessionsoptagelse"),
("Stop session recording", "Stop sessionsoptagelse"),

View File

@@ -364,6 +364,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("Recording", "Aufnahme"),
("Directory", "Verzeichnis"),
("Automatically record incoming sessions", "Eingehende Sitzungen automatisch aufzeichnen"),
("Automatically record outgoing sessions", ""),
("Change", "Ändern"),
("Start session recording", "Sitzungsaufzeichnung starten"),
("Stop session recording", "Sitzungsaufzeichnung beenden"),

View File

@@ -364,6 +364,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("Recording", "Εγγραφή"),
("Directory", "Φάκελος εγγραφών"),
("Automatically record incoming sessions", "Αυτόματη εγγραφή εισερχόμενων συνεδριών"),
("Automatically record outgoing sessions", ""),
("Change", "Αλλαγή"),
("Start session recording", "Έναρξη εγγραφής συνεδρίας"),
("Stop session recording", "Διακοπή εγγραφής συνεδρίας"),

View File

@@ -364,6 +364,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("Recording", ""),
("Directory", ""),
("Automatically record incoming sessions", ""),
("Automatically record outgoing sessions", ""),
("Change", ""),
("Start session recording", ""),
("Stop session recording", ""),

View File

@@ -364,6 +364,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("Recording", "Grabando"),
("Directory", "Directorio"),
("Automatically record incoming sessions", "Grabación automática de sesiones entrantes"),
("Automatically record outgoing sessions", ""),
("Change", "Cambiar"),
("Start session recording", "Comenzar grabación de sesión"),
("Stop session recording", "Detener grabación de sesión"),

View File

@@ -364,6 +364,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("Recording", ""),
("Directory", ""),
("Automatically record incoming sessions", ""),
("Automatically record outgoing sessions", ""),
("Change", ""),
("Start session recording", ""),
("Stop session recording", ""),

View File

@@ -364,6 +364,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("Recording", "Grabatzen"),
("Directory", "Direktorioa"),
("Automatically record incoming sessions", "Automatikoki grabatu sarrerako saioak"),
("Automatically record outgoing sessions", ""),
("Change", "Aldatu"),
("Start session recording", "Hasi saioaren grabaketa"),
("Stop session recording", "Gelditu saioaren grabaketa"),

View File

@@ -364,6 +364,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("Recording", "در حال ضبط"),
("Directory", "مسیر"),
("Automatically record incoming sessions", "ضبط خودکار جلسات ورودی"),
("Automatically record outgoing sessions", ""),
("Change", "تغییر"),
("Start session recording", "شروع ضبط جلسه"),
("Stop session recording", "توقف ضبط جلسه"),

View File

@@ -364,6 +364,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("Recording", "Enregistrement"),
("Directory", "Répertoire"),
("Automatically record incoming sessions", "Enregistrement automatique des sessions entrantes"),
("Automatically record outgoing sessions", ""),
("Change", "Modifier"),
("Start session recording", "Commencer l'enregistrement"),
("Stop session recording", "Stopper l'enregistrement"),

View File

@@ -364,6 +364,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("Recording", ""),
("Directory", ""),
("Automatically record incoming sessions", ""),
("Automatically record outgoing sessions", ""),
("Change", ""),
("Start session recording", ""),
("Stop session recording", ""),

View File

@@ -364,6 +364,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("Recording", "Snimanje"),
("Directory", "Mapa"),
("Automatically record incoming sessions", "Automatski snimi dolazne sesije"),
("Automatically record outgoing sessions", ""),
("Change", "Promijeni"),
("Start session recording", "Započni snimanje sesije"),
("Stop session recording", "Zaustavi snimanje sesije"),

View File

@@ -364,6 +364,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("Recording", "Felvétel"),
("Directory", "Könyvtár"),
("Automatically record incoming sessions", "A bejövő munkamenetek automatikus rögzítése"),
("Automatically record outgoing sessions", ""),
("Change", "Változtatás"),
("Start session recording", "Munkamenet rögzítés indítása"),
("Stop session recording", "Munkamenet rögzítés leállítása"),

View File

@@ -364,6 +364,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("Recording", "Perekaman"),
("Directory", "Direktori"),
("Automatically record incoming sessions", "Otomatis merekam sesi masuk"),
("Automatically record outgoing sessions", ""),
("Change", "Ubah"),
("Start session recording", "Mulai sesi perekaman"),
("Stop session recording", "Hentikan sesi perekaman"),

View File

@@ -364,6 +364,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("Recording", "Registrazione"),
("Directory", "Cartella"),
("Automatically record incoming sessions", "Registra automaticamente le sessioni in entrata"),
("Automatically record outgoing sessions", ""),
("Change", "Modifica"),
("Start session recording", "Inizia registrazione sessione"),
("Stop session recording", "Ferma registrazione sessione"),

View File

@@ -364,6 +364,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("Recording", "録画"),
("Directory", "ディレクトリ"),
("Automatically record incoming sessions", "受信したセッションを自動で記録する"),
("Automatically record outgoing sessions", ""),
("Change", "変更"),
("Start session recording", "セッションの録画を開始"),
("Stop session recording", "セッションの録画を停止"),

View File

@@ -364,6 +364,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("Recording", "녹화"),
("Directory", "경로"),
("Automatically record incoming sessions", "들어오는 세션을 자동으로 녹화"),
("Automatically record outgoing sessions", ""),
("Change", "변경"),
("Start session recording", "세션 녹화 시작"),
("Stop session recording", "세션 녹화 중지"),

View File

@@ -364,6 +364,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("Recording", ""),
("Directory", ""),
("Automatically record incoming sessions", ""),
("Automatically record outgoing sessions", ""),
("Change", ""),
("Start session recording", ""),
("Stop session recording", ""),

View File

@@ -364,6 +364,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("Recording", "Įrašymas"),
("Directory", "Katalogas"),
("Automatically record incoming sessions", "Automatiškai įrašyti įeinančius seansus"),
("Automatically record outgoing sessions", ""),
("Change", "Keisti"),
("Start session recording", "Pradėti seanso įrašinėjimą"),
("Stop session recording", "Sustabdyti seanso įrašinėjimą"),

View File

@@ -364,6 +364,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("Recording", "Ierakstīšana"),
("Directory", "Direktorija"),
("Automatically record incoming sessions", "Automātiski ierakstīt ienākošās sesijas"),
("Automatically record outgoing sessions", ""),
("Change", "Mainīt"),
("Start session recording", "Sākt sesijas ierakstīšanu"),
("Stop session recording", "Apturēt sesijas ierakstīšanu"),

View File

@@ -364,6 +364,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("Recording", "Opptak"),
("Directory", "Mappe"),
("Automatically record incoming sessions", "Ta opp innkommende sesjoner automatisk"),
("Automatically record outgoing sessions", ""),
("Change", "Rediger"),
("Start session recording", "Start sesjonsopptak"),
("Stop session recording", "Stopp sesjonsopptak"),

View File

@@ -364,6 +364,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("Recording", "Opnemen"),
("Directory", "Map"),
("Automatically record incoming sessions", "Automatisch inkomende sessies opnemen"),
("Automatically record outgoing sessions", ""),
("Change", "Wissel"),
("Start session recording", "Start de sessieopname"),
("Stop session recording", "Stop de sessieopname"),

View File

@@ -364,6 +364,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("Recording", "Nagrywanie"),
("Directory", "Folder"),
("Automatically record incoming sessions", "Automatycznie nagrywaj sesje przychodzące"),
("Automatically record outgoing sessions", ""),
("Change", "Zmień"),
("Start session recording", "Zacznij nagrywać sesję"),
("Stop session recording", "Zatrzymaj nagrywanie sesji"),

View File

@@ -364,6 +364,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("Recording", ""),
("Directory", ""),
("Automatically record incoming sessions", ""),
("Automatically record outgoing sessions", ""),
("Change", ""),
("Start session recording", ""),
("Stop session recording", ""),

View File

@@ -364,6 +364,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("Recording", "Gravando"),
("Directory", "Diretório"),
("Automatically record incoming sessions", "Gravar automaticamente sessões de entrada"),
("Automatically record outgoing sessions", ""),
("Change", "Alterar"),
("Start session recording", "Iniciar gravação da sessão"),
("Stop session recording", "Parar gravação da sessão"),

View File

@@ -364,6 +364,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("Recording", "Înregistrare"),
("Directory", "Director"),
("Automatically record incoming sessions", "Înregistrează automat sesiunile viitoare"),
("Automatically record outgoing sessions", ""),
("Change", "Modifică"),
("Start session recording", "Începe înregistrarea"),
("Stop session recording", "Oprește înregistrarea"),

View File

@@ -364,6 +364,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("Recording", "Запись"),
("Directory", "Папка"),
("Automatically record incoming sessions", "Автоматически записывать входящие сеансы"),
("Automatically record outgoing sessions", ""),
("Change", "Изменить"),
("Start session recording", "Начать запись сеанса"),
("Stop session recording", "Остановить запись сеанса"),

View File

@@ -364,6 +364,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("Recording", "Nahrávanie"),
("Directory", "Adresár"),
("Automatically record incoming sessions", "Automaticky nahrávať prichádzajúce relácie"),
("Automatically record outgoing sessions", ""),
("Change", "Zmeniť"),
("Start session recording", "Spustiť záznam relácie"),
("Stop session recording", "Zastaviť záznam relácie"),

View File

@@ -364,6 +364,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("Recording", "Snemanje"),
("Directory", "Imenik"),
("Automatically record incoming sessions", "Samodejno snemaj vhodne seje"),
("Automatically record outgoing sessions", ""),
("Change", "Spremeni"),
("Start session recording", "Začni snemanje seje"),
("Stop session recording", "Ustavi snemanje seje"),

View File

@@ -364,6 +364,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("Recording", "Regjistrimi"),
("Directory", "Direktoria"),
("Automatically record incoming sessions", "Regjistro automatikisht seancat hyrëse"),
("Automatically record outgoing sessions", ""),
("Change", "Ndrysho"),
("Start session recording", "Fillo regjistrimin e sesionit"),
("Stop session recording", "Ndalo regjistrimin e sesionit"),

View File

@@ -364,6 +364,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("Recording", "Snimanje"),
("Directory", "Direktorijum"),
("Automatically record incoming sessions", "Automatski snimaj dolazne sesije"),
("Automatically record outgoing sessions", ""),
("Change", "Promeni"),
("Start session recording", "Započni snimanje sesije"),
("Stop session recording", "Zaustavi snimanje sesije"),

View File

@@ -364,6 +364,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("Recording", "Spelar in"),
("Directory", "Katalog"),
("Automatically record incoming sessions", "Spela in inkommande sessioner automatiskt"),
("Automatically record outgoing sessions", ""),
("Change", "Byt"),
("Start session recording", "Starta inspelning"),
("Stop session recording", "Avsluta inspelning"),

View File

@@ -364,6 +364,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("Recording", ""),
("Directory", ""),
("Automatically record incoming sessions", ""),
("Automatically record outgoing sessions", ""),
("Change", ""),
("Start session recording", ""),
("Stop session recording", ""),

View File

@@ -364,6 +364,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("Recording", "การบันทึก"),
("Directory", "ไดเรกทอรี่"),
("Automatically record incoming sessions", "บันทึกเซสชันขาเข้าโดยอัตโนมัติ"),
("Automatically record outgoing sessions", ""),
("Change", "เปลี่ยน"),
("Start session recording", "เริ่มต้นการบันทึกเซสชัน"),
("Stop session recording", "หยุดการบันทึกเซสซัน"),

View File

@@ -364,6 +364,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("Recording", "Kayıt Ediliyor"),
("Directory", "Klasör"),
("Automatically record incoming sessions", "Gelen oturumları otomatik olarak kayıt et"),
("Automatically record outgoing sessions", ""),
("Change", "Değiştir"),
("Start session recording", "Oturum kaydını başlat"),
("Stop session recording", "Oturum kaydını sonlandır"),

View File

@@ -364,6 +364,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("Recording", "錄製"),
("Directory", "路徑"),
("Automatically record incoming sessions", "自動錄製連入的工作階段"),
("Automatically record outgoing sessions", ""),
("Change", "變更"),
("Start session recording", "開始錄影"),
("Stop session recording", "停止錄影"),

View File

@@ -364,6 +364,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("Recording", "Запис"),
("Directory", "Директорія"),
("Automatically record incoming sessions", "Автоматично записувати вхідні сеанси"),
("Automatically record outgoing sessions", ""),
("Change", "Змінити"),
("Start session recording", "Розпочати запис сеансу"),
("Stop session recording", "Закінчити запис сеансу"),

View File

@@ -364,6 +364,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("Recording", "Đang ghi hình"),
("Directory", "Thư mục"),
("Automatically record incoming sessions", "Tự động ghi những phiên kết nối vào"),
("Automatically record outgoing sessions", ""),
("Change", "Thay đổi"),
("Start session recording", "Bắt đầu ghi hình phiên kết nối"),
("Stop session recording", "Dừng ghi hình phiên kết nối"),

View File

@@ -487,6 +487,8 @@ fn run(vs: VideoService) -> ResultType<()> {
let repeat_encode_max = 10;
let mut encode_fail_counter = 0;
let mut first_frame = true;
let capture_width = c.width;
let capture_height = c.height;
while sp.ok() {
#[cfg(windows)]
@@ -576,6 +578,8 @@ fn run(vs: VideoService) -> ResultType<()> {
recorder.clone(),
&mut encode_fail_counter,
&mut first_frame,
capture_width,
capture_height,
)?;
frame_controller.set_send(now, send_conn_ids);
}
@@ -632,6 +636,8 @@ fn run(vs: VideoService) -> ResultType<()> {
recorder.clone(),
&mut encode_fail_counter,
&mut first_frame,
capture_width,
capture_height,
)?;
frame_controller.set_send(now, send_conn_ids);
}
@@ -722,7 +728,13 @@ fn setup_encoder(
);
Encoder::set_fallback(&encoder_cfg);
let codec_format = Encoder::negotiated_codec();
let recorder = get_recorder(c.width, c.height, &codec_format, record_incoming);
let recorder = get_recorder(
c.width,
c.height,
&codec_format,
record_incoming,
display_idx,
);
let use_i444 = Encoder::use_i444(&encoder_cfg);
let encoder = Encoder::new(encoder_cfg.clone(), use_i444)?;
Ok((encoder, encoder_cfg, codec_format, use_i444, recorder))
@@ -809,6 +821,7 @@ fn get_recorder(
height: usize,
codec_format: &CodecFormat,
record_incoming: bool,
display: usize,
) -> Arc<Mutex<Option<Recorder>>> {
#[cfg(windows)]
let root = crate::platform::is_root();
@@ -828,10 +841,7 @@ fn get_recorder(
server: true,
id: Config::get_id(),
dir: crate::ui_interface::video_save_directory(root),
filename: "".to_owned(),
width,
height,
format: codec_format.clone(),
display,
tx,
})
.map_or(Default::default(), |r| Arc::new(Mutex::new(Some(r))))
@@ -910,6 +920,8 @@ fn handle_one_frame(
recorder: Arc<Mutex<Option<Recorder>>>,
encode_fail_counter: &mut usize,
first_frame: &mut bool,
width: usize,
height: usize,
) -> ResultType<HashSet<i32>> {
sp.snapshot(|sps| {
// so that new sub and old sub share the same encoder after switch
@@ -933,7 +945,7 @@ fn handle_one_frame(
.lock()
.unwrap()
.as_mut()
.map(|r| r.write_message(&msg));
.map(|r| r.write_message(&msg, width, height));
send_conn_ids = sp.send_video_frame(msg);
}
Err(e) => {

View File

@@ -301,26 +301,12 @@ class Header: Reactor.Component {
}
event click $(span#recording) (_, me) {
recording = !recording;
header.update();
handler.record_status(recording);
// 0 is just a dummy value. It will be ignored by the handler.
if (recording) {
handler.refresh_video(0);
if (handler.version_cmp(pi.version, '1.2.4') >= 0) handler.record_screen(recording, pi.current_display, display_width, display_height);
}
else {
handler.record_screen(recording, pi.current_display, display_width, display_height);
}
handler.record_screen(!recording)
}
event click $(#screen) (_, me) {
if (pi.current_display == me.index) return;
if (recording) {
recording = false;
handler.record_screen(false, pi.current_display, display_width, display_height);
handler.record_status(false);
}
handler.switch_display(me.index);
}
@@ -518,6 +504,7 @@ if (!(is_file_transfer || is_port_forward)) {
handler.updatePi = function(v) {
pi = v;
recording = handler.is_recording();
header.update();
if (is_port_forward) {
view.windowState = View.WINDOW_MINIMIZED;
@@ -682,3 +669,8 @@ handler.setConnectionType = function(secured, direct) {
direct_connection: direct,
});
}
handler.updateRecordStatus = function(status) {
recording = status;
header.update();
}

View File

@@ -253,10 +253,12 @@ class Enhancements: Reactor.Component {
var root_dir = show_root_dir ? handler.video_save_directory(true) : "";
var ts0 = handler.get_option("enable-record-session") == '' ? { checked: true } : {};
var ts1 = handler.get_option("allow-auto-record-incoming") == 'Y' ? { checked: true } : {};
var ts2 = handler.get_option("allow-auto-record-outgoing") == 'Y' ? { checked: true } : {};
msgbox("custom-recording", translate('Recording'),
<div .form>
<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_outgoing) {ts2}>{translate('Automatically record outgoing sessions')}</button></div>
<div>
{show_root_dir ? <div style="word-wrap:break-word"><span>{translate("Incoming")}:&nbsp;&nbsp;</span><span>{root_dir}</span></div> : ""}
<div style="word-wrap:break-word"><span>{translate(show_root_dir ? "Outgoing" : "Directory")}:&nbsp;&nbsp;</span><span #folderPath>{user_dir}</span></div>
@@ -267,6 +269,7 @@ class Enhancements: Reactor.Component {
if (!res) return;
handler.set_option("enable-record-session", res.enable_record_session ? '' : 'N');
handler.set_option("allow-auto-record-incoming", res.auto_record_incoming ? 'Y' : '');
handler.set_option("allow-auto-record-outgoing", res.auto_record_outgoing ? 'Y' : '');
handler.set_option("video-save-directory", $(#folderPath).text);
});
}

View File

@@ -335,6 +335,10 @@ impl InvokeUiSession for SciterHandler {
}
fn next_rgba(&self, _display: usize) {}
fn update_record_status(&self, start: bool) {
self.call("updateRecordStatus", &make_args!(start));
}
}
pub struct SciterSession(Session<SciterHandler>);
@@ -478,8 +482,7 @@ impl sciter::EventHandler for SciterSession {
fn save_image_quality(String);
fn save_custom_image_quality(i32);
fn refresh_video(i32);
fn record_screen(bool, i32, i32, i32);
fn record_status(bool);
fn record_screen(bool);
fn get_toggle_option(String);
fn is_privacy_mode_supported();
fn toggle_option(String);
@@ -496,6 +499,7 @@ impl sciter::EventHandler for SciterSession {
fn close_voice_call();
fn version_cmp(String, String);
fn set_selected_windows_session_id(String);
fn is_recording();
}
}

View File

@@ -389,22 +389,17 @@ impl<T: InvokeUiSession> Session<T> {
self.send(Data::Message(LoginConfigHandler::refresh()));
}
pub fn record_screen(&self, start: bool, display: i32, w: i32, h: i32) {
self.send(Data::RecordScreen(
start,
display as usize,
w,
h,
self.get_id(),
));
}
pub fn record_status(&self, status: bool) {
pub fn record_screen(&self, start: bool) {
let mut misc = Misc::new();
misc.set_client_record_status(status);
misc.set_client_record_status(start);
let mut msg = Message::new();
msg.set_misc(misc);
self.send(Data::Message(msg));
self.send(Data::RecordScreen(start));
}
pub fn is_recording(&self) -> bool {
self.lc.read().unwrap().record
}
pub fn save_custom_image_quality(&self, custom_image_quality: i32) {
@@ -1557,6 +1552,7 @@ pub trait InvokeUiSession: Send + Sync + Clone + 'static + Sized + Default {
fn set_current_display(&self, disp_idx: i32);
#[cfg(feature = "flutter")]
fn is_multi_ui_session(&self) -> bool;
fn update_record_status(&self, start: bool);
}
impl<T: InvokeUiSession> Deref for Session<T> {