还原参赛队伍列表页、详情页
This commit is contained in:
@@ -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),
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user