feat: 增加分辨率修改
This commit is contained in:
@@ -131,6 +131,11 @@ class RemoteController {
|
||||
_webRtc?.sendControlCommand(command);
|
||||
}
|
||||
|
||||
/// 请求被控端切换屏幕采集分辨率。
|
||||
void sendResolutionChange(int width, int height, int fps) {
|
||||
_webRtc?.sendResolutionChange(width, height, fps);
|
||||
}
|
||||
|
||||
/// 断开连接并释放资源。
|
||||
Future<void> disconnect() async {
|
||||
_statsTimer?.cancel();
|
||||
|
||||
@@ -47,6 +47,16 @@ class _ControllerHomeState extends State<ControllerHome> {
|
||||
String _stats = '';
|
||||
double _videoAspect = 16 / 9;
|
||||
|
||||
/// 分辨率预设:width 为长边像素;0 表示被控端原生分辨率;
|
||||
/// height 传 0(由被控端按屏幕宽高比计算),fps 传 0(沿用当前帧率)。
|
||||
int _selectedResolution = 0;
|
||||
final List<Map<String, Object>> _resolutionOptions = const [
|
||||
{'label': '原始', 'width': 0, 'height': 0, 'fps': 0},
|
||||
{'label': '1080P', 'width': 1920, 'height': 0, 'fps': 0},
|
||||
{'label': '720P', 'width': 1280, 'height': 0, 'fps': 0},
|
||||
{'label': '480P', 'width': 854, 'height': 0, 'fps': 0},
|
||||
];
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
@@ -320,6 +330,29 @@ class _ControllerHomeState extends State<ControllerHome> {
|
||||
),
|
||||
),
|
||||
),
|
||||
Positioned(
|
||||
bottom: 16,
|
||||
left: 16,
|
||||
child: CupertinoSegmentedControl<int>(
|
||||
groupValue: _selectedResolution,
|
||||
children: <int, Widget>{
|
||||
for (int i = 0; i < _resolutionOptions.length; i++)
|
||||
i: Padding(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 10, vertical: 6),
|
||||
child: Text(_resolutionOptions[i]['label'] as String),
|
||||
),
|
||||
},
|
||||
onValueChanged: (int idx) {
|
||||
setState(() => _selectedResolution = idx);
|
||||
final o = _resolutionOptions[idx];
|
||||
_controller?.sendResolutionChange(
|
||||
o['width'] as int,
|
||||
o['height'] as int,
|
||||
o['fps'] as int,
|
||||
);
|
||||
},
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
|
||||
@@ -36,6 +36,9 @@ class ControlMessage extends $pb.GeneratedMessage {
|
||||
$core.int? keyCode,
|
||||
$core.int? keyAction,
|
||||
$core.int? motionAction,
|
||||
$core.int? width,
|
||||
$core.int? height,
|
||||
$core.int? fps,
|
||||
}) {
|
||||
final result = create();
|
||||
if (action != null) result.action = action;
|
||||
@@ -49,6 +52,9 @@ class ControlMessage extends $pb.GeneratedMessage {
|
||||
if (keyCode != null) result.keyCode = keyCode;
|
||||
if (keyAction != null) result.keyAction = keyAction;
|
||||
if (motionAction != null) result.motionAction = motionAction;
|
||||
if (width != null) result.width = width;
|
||||
if (height != null) result.height = height;
|
||||
if (fps != null) result.fps = fps;
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -77,6 +83,9 @@ class ControlMessage extends $pb.GeneratedMessage {
|
||||
..aI(9, _omitFieldNames ? '' : 'keyCode')
|
||||
..aI(10, _omitFieldNames ? '' : 'keyAction')
|
||||
..aI(11, _omitFieldNames ? '' : 'motionAction')
|
||||
..aI(12, _omitFieldNames ? '' : 'width')
|
||||
..aI(13, _omitFieldNames ? '' : 'height')
|
||||
..aI(14, _omitFieldNames ? '' : 'fps')
|
||||
..hasRequiredFields = false;
|
||||
|
||||
@$core.Deprecated('See https://github.com/google/protobuf.dart/issues/998.')
|
||||
@@ -201,6 +210,36 @@ class ControlMessage extends $pb.GeneratedMessage {
|
||||
$core.bool hasMotionAction() => $_has(10);
|
||||
@$pb.TagNumber(11)
|
||||
void clearMotionAction() => $_clearField(11);
|
||||
|
||||
/// 分辨率切换(SET_RESOLUTION):目标宽度/长边(<=0 表示原生分辨率)
|
||||
@$pb.TagNumber(12)
|
||||
$core.int get width => $_getIZ(11);
|
||||
@$pb.TagNumber(12)
|
||||
set width($core.int value) => $_setSignedInt32(11, value);
|
||||
@$pb.TagNumber(12)
|
||||
$core.bool hasWidth() => $_has(11);
|
||||
@$pb.TagNumber(12)
|
||||
void clearWidth() => $_clearField(12);
|
||||
|
||||
/// 分辨率切换(SET_RESOLUTION):目标高度(<=0 时按屏幕宽高比基于 width 计算)
|
||||
@$pb.TagNumber(13)
|
||||
$core.int get height => $_getIZ(12);
|
||||
@$pb.TagNumber(13)
|
||||
set height($core.int value) => $_setSignedInt32(12, value);
|
||||
@$pb.TagNumber(13)
|
||||
$core.bool hasHeight() => $_has(12);
|
||||
@$pb.TagNumber(13)
|
||||
void clearHeight() => $_clearField(13);
|
||||
|
||||
/// 分辨率切换(SET_RESOLUTION):目标帧率(<=0 表示沿用当前帧率)
|
||||
@$pb.TagNumber(14)
|
||||
$core.int get fps => $_getIZ(13);
|
||||
@$pb.TagNumber(14)
|
||||
set fps($core.int value) => $_setSignedInt32(13, value);
|
||||
@$pb.TagNumber(14)
|
||||
$core.bool hasFps() => $_has(13);
|
||||
@$pb.TagNumber(14)
|
||||
void clearFps() => $_clearField(14);
|
||||
}
|
||||
|
||||
const $core.bool _omitFieldNames =
|
||||
|
||||
@@ -25,6 +25,10 @@ class Action extends $pb.ProtobufEnum {
|
||||
Action._(4, _omitEnumNames ? '' : 'LONG_PRESS');
|
||||
static const Action MOTION_EVENT =
|
||||
Action._(5, _omitEnumNames ? '' : 'MOTION_EVENT');
|
||||
static const Action SET_RESOLUTION =
|
||||
Action._(6, _omitEnumNames ? '' : 'SET_RESOLUTION');
|
||||
static const Action REPORT_RESOLUTION =
|
||||
Action._(7, _omitEnumNames ? '' : 'REPORT_RESOLUTION');
|
||||
|
||||
static const $core.List<Action> values = <Action>[
|
||||
ACTION_UNKNOWN,
|
||||
@@ -33,10 +37,12 @@ class Action extends $pb.ProtobufEnum {
|
||||
KEY,
|
||||
LONG_PRESS,
|
||||
MOTION_EVENT,
|
||||
SET_RESOLUTION,
|
||||
REPORT_RESOLUTION,
|
||||
];
|
||||
|
||||
static final $core.List<Action?> _byValue =
|
||||
$pb.ProtobufEnum.$_initByValueList(values, 5);
|
||||
$pb.ProtobufEnum.$_initByValueList(values, 7);
|
||||
static Action? valueOf($core.int value) =>
|
||||
value < 0 || value >= _byValue.length ? null : _byValue[value];
|
||||
|
||||
|
||||
@@ -56,4 +56,16 @@ class ControlCommands {
|
||||
x: x,
|
||||
y: y,
|
||||
);
|
||||
|
||||
/// 分辨率切换指令。
|
||||
/// [width] 目标长边/宽度(<=0 表示被控端原生分辨率);
|
||||
/// [height] 目标高度(<=0 时由被控端按屏幕宽高比计算);
|
||||
/// [fps] 目标帧率(<=0 表示沿用当前帧率)。
|
||||
static ControlMessage setResolution(int width, int height, int fps) =>
|
||||
ControlMessage(
|
||||
action: Action.SET_RESOLUTION,
|
||||
width: width,
|
||||
height: height,
|
||||
fps: fps,
|
||||
);
|
||||
}
|
||||
|
||||
@@ -5,6 +5,7 @@ import '../config/ice_servers.dart';
|
||||
import '../models/signal_message.dart';
|
||||
import '../proto/control_message.pb.dart';
|
||||
import '../signaling/signaling_client.dart';
|
||||
import '../utils/control_commands.dart';
|
||||
|
||||
/// 封装 WebRTC 连接逻辑(对应 Android 端 WebRtcClient)。
|
||||
///
|
||||
@@ -192,6 +193,11 @@ class WebRtcController {
|
||||
}
|
||||
}
|
||||
|
||||
/// 请求被控端切换屏幕采集分辨率(SET_RESOLUTION 指令)。
|
||||
void sendResolutionChange(int width, int height, int fps) {
|
||||
sendControlCommand(ControlCommands.setResolution(width, height, fps));
|
||||
}
|
||||
|
||||
/// 上一次统计采样的字节数与时间戳,用于计算每秒网速。
|
||||
int _prevBytesReceived = 0;
|
||||
int _prevBytesSent = 0;
|
||||
|
||||
@@ -13,6 +13,8 @@ enum Action {
|
||||
KEY = 3;
|
||||
LONG_PRESS = 4;
|
||||
MOTION_EVENT = 5;
|
||||
SET_RESOLUTION = 6; // 控制端请求被控端切换屏幕采集分辨率
|
||||
REPORT_RESOLUTION = 7; // 被控端上报当前实际采集分辨率(含连接建立后的初始值)
|
||||
}
|
||||
|
||||
// 通过 RTCDataChannel 传输的控制指令(protobuf 二进制)。
|
||||
@@ -38,4 +40,12 @@ message ControlMessage {
|
||||
|
||||
// 原始动作(MOTION_EVENT):对应 Android MotionEvent ACTION_*(0=DOWN 1=UP 2=MOVE)
|
||||
int32 motion_action = 11;
|
||||
|
||||
// 分辨率切换(SET_RESOLUTION):
|
||||
// width 为目标长边/宽度;<=0 表示使用被控端原始(native)分辨率。
|
||||
// height 为目标高度;<=0 时按被控端屏幕宽高比基于 width 计算(保留原始比例)。
|
||||
// fps 为目标帧率;<=0 表示沿用当前帧率。
|
||||
int32 width = 12;
|
||||
int32 height = 13;
|
||||
int32 fps = 14;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user