还原参赛队伍列表页、详情页

This commit is contained in:
2026-07-28 15:46:23 +08:00
parent 9e72bc522e
commit 6793ca53af
5 changed files with 157 additions and 307 deletions
@@ -1,131 +0,0 @@
import 'package:apivideo_live_stream/apivideo_live_stream.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:recording_tool/features/scan_qrcode/utils/rtmp_stream_target.dart';
import 'package:recording_tool/shared/widgets/app_bar.dart';
import 'package:recording_tool/shared/widgets/app_toast.dart';
class PushSteamTestWidget extends StatefulWidget {
const PushSteamTestWidget({
super.key,
this.rtmpUrl =
'rtmp://192.168.1.245:19090/蔡依婷vs夏志豪_空中格斗赛_高中组/蔡依婷vs夏志豪_空中格斗赛_高中组',
});
final String rtmpUrl;
@override
State<PushSteamTestWidget> createState() => _PushSteamTestWidgetState();
}
class _PushSteamTestWidgetState extends State<PushSteamTestWidget>
with WidgetsBindingObserver {
late final ApiVideoLiveStreamController _controller;
bool _ready = false;
bool _isStreaming = false;
@override
void initState() {
super.initState();
WidgetsBinding.instance.addObserver(this);
_controller = ApiVideoLiveStreamController(
initialAudioConfig: AudioConfig(bitrate: 128000),
initialVideoConfig: VideoConfig.withDefaultBitrate(
resolution: Resolution.RESOLUTION_1080,
fps: 30,
),
onConnectionSuccess: () => {
debugPrint('推流成功'),
setState(() => _isStreaming = true),
},
onConnectionFailed: (reason) {
setState(() => _isStreaming = false);
debugPrint('推流失败: $reason');
},
onDisconnection: () => {
debugPrint('推流断开'),
setState(() => _isStreaming = false),
},
);
WidgetsBinding.instance.addPostFrameCallback((_) => _initialize());
}
Future<void> _initialize() async {
try {
await _controller.initialize();
await _controller.startPreview();
setState(() => _ready = true);
} catch (e) {
debugPrint('初始化失败: $e');
}
}
Future<void> _startPush() async {
try {
final target = RtmpStreamTarget.parse(widget.rtmpUrl);
await _controller.startStreaming(
streamKey: target.streamKey,
url: target.url,
);
} on FormatException catch (e) {
debugPrint('推流地址错误: ${e.message}');
AppToast.show(e.message);
} on PlatformException catch (e) {
final message = e.message ?? e.code;
debugPrint('推流失败: ${e.code} $message');
AppToast.show('推流失败: $message');
} catch (e) {
debugPrint('推流失败: $e');
AppToast.showError(e);
}
}
Future<void> _stopPush() => _controller.stopStreaming();
@override
void didChangeAppLifecycleState(AppLifecycleState state) {
if (state == AppLifecycleState.inactive) {
_controller.stop();
} else if (state == AppLifecycleState.resumed) {
_controller.startPreview();
}
}
@override
void dispose() {
WidgetsBinding.instance.removeObserver(this);
_controller.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: myAppBar(context: context),
body: Stack(
children: [
if (_ready)
ApiVideoCameraPreview(controller: _controller, fit: BoxFit.cover),
Positioned(
bottom: 32,
left: 0,
right: 0,
child: Center(
child: FloatingActionButton(
backgroundColor: _isStreaming ? Colors.red : Colors.green,
onPressed: _ready
? (_isStreaming ? _stopPush : _startPush)
: null,
child: Icon(_isStreaming ? Icons.stop : Icons.circle),
),
),
),
],
),
);
}
}