feat(streaming): 添加自编码串流模式切换功能
This commit is contained in:
@@ -8,6 +8,7 @@ import 'config/ice_servers.dart';
|
||||
import 'controller/remote_controller.dart';
|
||||
import 'utils/control_commands.dart';
|
||||
import 'utils/device_utils.dart';
|
||||
import 'webrtc/self_codec_decoder.dart';
|
||||
import 'widgets/remote_touch_view.dart';
|
||||
|
||||
void main() {
|
||||
@@ -55,6 +56,12 @@ class _ControllerHomeState extends State<ControllerHome> {
|
||||
String _stats = '';
|
||||
double _videoAspect = 16 / 9;
|
||||
|
||||
/// 当前串流模式:0=WebRTC 全托管;1=自编码(自建 MediaCodec 解码)。
|
||||
int _streamMode = SelfCodecDecoder.streamModeWebRtc;
|
||||
int? _selfCodecTextureId;
|
||||
bool _selfCodecReady = false;
|
||||
bool _selfCodecSupported = true;
|
||||
|
||||
/// 分辨率预设:width 为长边像素;0 表示被控端原生分辨率;
|
||||
/// height 传 0(由被控端按屏幕宽高比计算),fps 传 0(沿用当前帧率)。
|
||||
int _selectedResolution = 0;
|
||||
@@ -217,6 +224,28 @@ class _ControllerHomeState extends State<ControllerHome> {
|
||||
renderer.addListener(_onRendererUpdate);
|
||||
};
|
||||
_controller!.onStats = (stats) => setState(() => _stats = stats);
|
||||
_controller!.onSelfCodecReady = (textureId) {
|
||||
if (mounted) {
|
||||
setState(() {
|
||||
_selfCodecTextureId = textureId;
|
||||
_selfCodecReady = true;
|
||||
});
|
||||
}
|
||||
};
|
||||
_controller!.onStreamModeReport = (mode) {
|
||||
if (mounted) setState(() => _streamMode = mode);
|
||||
};
|
||||
_controller!.onResolutionReported = (w, h) {
|
||||
if (w > 0 && h > 0 && mounted) {
|
||||
final aspect = w / h;
|
||||
setState(() => _videoAspect = aspect);
|
||||
_resizeWindowToAspect(aspect);
|
||||
}
|
||||
};
|
||||
_controller!.onSelfCodecNotSupported = () {
|
||||
if (mounted) setState(() => _selfCodecSupported = false);
|
||||
_showAlert('当前平台不支持自编码硬解,已回退到 WebRTC 媒体流。');
|
||||
};
|
||||
|
||||
_controller!.connect(authType: authType, authValue: authValue);
|
||||
}
|
||||
@@ -300,6 +329,19 @@ class _ControllerHomeState extends State<ControllerHome> {
|
||||
);
|
||||
}
|
||||
|
||||
/// 切换串流模式:WebRTC 全托管 <-> 自编码(自建 MediaCodec 解码)。
|
||||
void _toggleStreamMode() {
|
||||
if (!_selfCodecSupported) {
|
||||
_showAlert('当前平台不支持自编码硬解。');
|
||||
return;
|
||||
}
|
||||
final next = _streamMode == SelfCodecDecoder.streamModeSelfCodec
|
||||
? SelfCodecDecoder.streamModeWebRtc
|
||||
: SelfCodecDecoder.streamModeSelfCodec;
|
||||
setState(() => _streamMode = next);
|
||||
_controller?.sendStreamMode(next);
|
||||
}
|
||||
|
||||
Future<void> _disconnect() async {
|
||||
await _controller?.disconnect();
|
||||
_controller = null;
|
||||
@@ -310,6 +352,10 @@ class _ControllerHomeState extends State<ControllerHome> {
|
||||
_renderer = null;
|
||||
_status = '状态: 已停止';
|
||||
_stats = '';
|
||||
_streamMode = SelfCodecDecoder.streamModeWebRtc;
|
||||
_selfCodecTextureId = null;
|
||||
_selfCodecReady = false;
|
||||
_selfCodecSupported = true;
|
||||
});
|
||||
}
|
||||
|
||||
@@ -412,6 +458,33 @@ class _ControllerHomeState extends State<ControllerHome> {
|
||||
],
|
||||
),
|
||||
),
|
||||
// 自编码串流开关:仅 Android 等支持原生硬解的平台可用。
|
||||
CupertinoButton(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 10),
|
||||
onPressed: _selfCodecSupported ? _toggleStreamMode : null,
|
||||
child: Row(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
Text(
|
||||
'自编码',
|
||||
style: TextStyle(
|
||||
color: _selfCodecSupported
|
||||
? CupertinoColors.white
|
||||
: CupertinoColors.white.withValues(alpha: 0.4),
|
||||
fontSize: 14,
|
||||
),
|
||||
),
|
||||
const SizedBox(width: 6),
|
||||
CupertinoSwitch(
|
||||
value: _streamMode == SelfCodecDecoder.streamModeSelfCodec,
|
||||
onChanged: _selfCodecSupported
|
||||
? (_) => _toggleStreamMode()
|
||||
: null,
|
||||
activeTrackColor: CupertinoColors.activeBlue,
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
// 分隔线
|
||||
Container(
|
||||
width: 1,
|
||||
@@ -444,7 +517,31 @@ class _ControllerHomeState extends State<ControllerHome> {
|
||||
child: Stack(
|
||||
children: [
|
||||
Container(color: Colors.black),
|
||||
if (_renderer != null)
|
||||
if (_streamMode == SelfCodecDecoder.streamModeSelfCodec &&
|
||||
_selfCodecReady &&
|
||||
_selfCodecTextureId != null)
|
||||
Center(
|
||||
child: AspectRatio(
|
||||
aspectRatio: _videoAspect,
|
||||
child: Stack(
|
||||
fit: StackFit.expand,
|
||||
children: [
|
||||
Texture(textureId: _selfCodecTextureId!),
|
||||
RemoteTouchView(
|
||||
onTouch: (x, y) {},
|
||||
onSwipe: (x1, y1, x2, y2, d) {},
|
||||
onLongPress: (x, y) {},
|
||||
onKey: (k, a) =>
|
||||
_controller?.sendControlCommand(ControlCommands.key(k, a)),
|
||||
onMotionEvent: (a, x, y) => _controller?.sendControlCommand(
|
||||
ControlCommands.motionEvent(a, x, y),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
)
|
||||
else if (_renderer != null)
|
||||
Center(
|
||||
child: AspectRatio(
|
||||
aspectRatio: _videoAspect,
|
||||
|
||||
Reference in New Issue
Block a user