Merge pull request #6084 from 21pages/av1_record

AV1 record
This commit is contained in:
RustDesk
2023-10-19 14:23:35 +08:00
committed by GitHub
14 changed files with 151 additions and 88 deletions

View File

@@ -224,11 +224,8 @@ List<TTextMenu> toolbarControls(BuildContext context, String id, FFI ffi) {
));
}
// record
var codecFormat = ffi.qualityMonitorModel.data.codecFormat;
if (!isDesktop &&
(ffi.recordingModel.start ||
(perms["recording"] != false &&
(codecFormat == "VP8" || codecFormat == "VP9")))) {
(ffi.recordingModel.start || (perms["recording"] != false))) {
v.add(TTextMenu(
child: Row(
children: [

View File

@@ -677,7 +677,8 @@ class _ImagePaintState extends State<ImagePaint> {
} else {
final key = cache.updateGetKey(scale);
if (!cursor.cachedKeys.contains(key)) {
debugPrint("Register custom cursor with key $key (${cache.hotx},${cache.hoty})");
debugPrint(
"Register custom cursor with key $key (${cache.hotx},${cache.hoty})");
// [Safety]
// It's ok to call async registerCursor in current synchronous context,
// because activating the cursor is also an async call and will always

View File

@@ -478,7 +478,7 @@ class _RemoteToolbarState extends State<RemoteToolbar> {
toolbarItems.add(_ChatMenu(id: widget.id, ffi: widget.ffi));
toolbarItems.add(_VoiceCallMenu(id: widget.id, ffi: widget.ffi));
}
toolbarItems.add(_RecordMenu(ffi: widget.ffi));
toolbarItems.add(_RecordMenu());
toolbarItems.add(_CloseMenu(id: widget.id, ffi: widget.ffi));
return Column(
mainAxisSize: MainAxisSize.min,
@@ -1646,17 +1646,17 @@ class _VoiceCallMenu extends StatelessWidget {
}
class _RecordMenu extends StatelessWidget {
final FFI ffi;
const _RecordMenu({Key? key, required this.ffi}) : super(key: key);
const _RecordMenu({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
var ffiModel = Provider.of<FfiModel>(context);
var ffi = Provider.of<FfiModel>(context);
var recordingModel = Provider.of<RecordingModel>(context);
final visible =
recordingModel.start || ffiModel.permissions['recording'] != false;
(recordingModel.start || ffi.permissions['recording'] != false) &&
ffi.pi.currentDisplay != kAllDisplayValue;
if (!visible) return Offstage();
final menuButton = _IconMenuButton(
return _IconMenuButton(
assetName: 'assets/rec.svg',
tooltip: recordingModel.start
? 'Stop session recording'
@@ -1669,14 +1669,6 @@ class _RecordMenu extends StatelessWidget {
? _ToolbarTheme.hoverRedColor
: _ToolbarTheme.hoverBlueColor,
);
return ChangeNotifierProvider.value(
value: ffi.qualityMonitorModel,
child: Consumer<QualityMonitorModel>(
builder: (context, model, child) => Offstage(
// If already started, AV1->Hidden/Stop, Other->Start, same as actual
offstage: model.data.codecFormat == 'AV1',
child: menuButton,
)));
}
}

View File

@@ -763,7 +763,9 @@ void showOptions(
children.add(InkWell(
onTap: () {
if (i == cur) return;
bind.sessionSwitchDisplay(sessionId: gFFI.sessionId, value: Int32List.fromList([i]));
gFFI.recordingModel.onClose();
bind.sessionSwitchDisplay(
sessionId: gFFI.sessionId, value: Int32List.fromList([i]));
gFFI.dialogManager.dismissAll();
},
child: Ink(

View File

@@ -860,6 +860,8 @@ class FfiModel with ChangeNotifier {
// Directly switch to the new display without waiting for the response.
switchToNewDisplay(int display, SessionID sessionId, String peerId) {
// VideoHandler creation is upon when video frames are received, so either caching commands(don't know next width/height) or stopping recording when switching displays.
parent.target?.recordingModel.onClose();
// no need to wait for the response
pi.currentDisplay = display;
updateCurDisplay(sessionId);
@@ -868,7 +870,6 @@ class FfiModel with ChangeNotifier {
} catch (e) {
//
}
parent.target?.recordingModel.onSwitchDisplay();
}
updateBlockInputState(Map<String, dynamic> evt, String peerId) {
@@ -1850,57 +1851,67 @@ class RecordingModel with ChangeNotifier {
int? width = parent.target?.canvasModel.getDisplayWidth();
int? height = parent.target?.canvasModel.getDisplayHeight();
if (sessionId == null || width == null || height == null) return;
final currentDisplay = parent.target?.ffiModel.pi.currentDisplay;
if (currentDisplay != kAllDisplayValue) {
bind.sessionRecordScreen(
sessionId: sessionId,
start: true,
display: currentDisplay!,
width: width,
height: height);
}
final pi = parent.target?.ffiModel.pi;
if (pi == null) return;
final currentDisplay = pi.currentDisplay;
if (currentDisplay == kAllDisplayValue) return;
bind.sessionRecordScreen(
sessionId: sessionId,
start: true,
display: currentDisplay,
width: width,
height: height);
}
toggle() async {
if (isIOS) return;
final sessionId = parent.target?.sessionId;
if (sessionId == null) return;
final pi = parent.target?.ffiModel.pi;
if (pi == null) return;
final currentDisplay = pi.currentDisplay;
if (currentDisplay == kAllDisplayValue) return;
_start = !_start;
notifyListeners();
await bind.sessionRecordStatus(sessionId: sessionId, status: _start);
await _sendStatusMessage(sessionId, pi, _start);
if (_start) {
final pi = parent.target?.ffiModel.pi;
if (pi != null) {
sessionRefreshVideo(sessionId, pi);
sessionRefreshVideo(sessionId, pi);
if (versionCmp(pi.version, '1.2.4') >= 0) {
// will not receive SwitchDisplay since 1.2.4
onSwitchDisplay();
}
} else {
final currentDisplay = parent.target?.ffiModel.pi.currentDisplay;
if (currentDisplay != kAllDisplayValue) {
bind.sessionRecordScreen(
sessionId: sessionId,
start: false,
display: currentDisplay!,
width: 0,
height: 0);
}
}
}
onClose() {
if (isIOS) return;
final sessionId = parent.target?.sessionId;
if (sessionId == null) return;
_start = false;
final currentDisplay = parent.target?.ffiModel.pi.currentDisplay;
if (currentDisplay != kAllDisplayValue) {
bind.sessionRecordScreen(
sessionId: sessionId,
start: false,
display: currentDisplay!,
display: currentDisplay,
width: 0,
height: 0);
}
}
onClose() async {
if (isIOS) return;
final sessionId = parent.target?.sessionId;
if (sessionId == null) return;
if (!_start) return;
_start = false;
final pi = parent.target?.ffiModel.pi;
if (pi == null) return;
final currentDisplay = pi.currentDisplay;
if (currentDisplay == kAllDisplayValue) return;
await _sendStatusMessage(sessionId, pi, false);
bind.sessionRecordScreen(
sessionId: sessionId,
start: false,
display: currentDisplay,
width: 0,
height: 0);
}
_sendStatusMessage(SessionID sessionId, PeerInfo pi, bool status) async {
await bind.sessionRecordStatus(sessionId: sessionId, status: status);
}
}
class ElevationModel with ChangeNotifier {