83 lines
2.3 KiB
Dart
83 lines
2.3 KiB
Dart
import 'package:flutter/material.dart';
|
|
import 'package:video_player/video_player.dart';
|
|
|
|
class PlayerPage extends StatefulWidget {
|
|
final String title;
|
|
final String rtmpUrl;
|
|
|
|
const PlayerPage({Key? key, required this.title, required this.rtmpUrl}) : super(key: key);
|
|
|
|
@override
|
|
_PlayerPageState createState() => _PlayerPageState();
|
|
}
|
|
|
|
class _PlayerPageState extends State<PlayerPage> {
|
|
late VideoPlayerController _controller;
|
|
bool _isError = false;
|
|
String? _errorMessage;
|
|
|
|
@override
|
|
void initState() {
|
|
super.initState();
|
|
_initializePlayer();
|
|
}
|
|
|
|
void _initializePlayer() async {
|
|
print("[INFO] Playing stream: ${widget.rtmpUrl}");
|
|
_controller = VideoPlayerController.networkUrl(Uri.parse(widget.rtmpUrl));
|
|
|
|
try {
|
|
await _controller.initialize();
|
|
_controller.play();
|
|
setState(() {}); // 更新状态以渲染画面
|
|
} catch (e) {
|
|
print("[ERROR] Player initialization failed: $e");
|
|
setState(() {
|
|
_isError = true;
|
|
_errorMessage = e.toString();
|
|
});
|
|
}
|
|
}
|
|
|
|
@override
|
|
void dispose() {
|
|
_controller.dispose();
|
|
super.dispose();
|
|
}
|
|
|
|
@override
|
|
Widget build(BuildContext context) {
|
|
return Scaffold(
|
|
backgroundColor: Colors.black,
|
|
appBar: AppBar(
|
|
title: Text(widget.title),
|
|
backgroundColor: Colors.transparent,
|
|
foregroundColor: Colors.white,
|
|
),
|
|
body: Center(
|
|
child: _isError
|
|
? Column(
|
|
mainAxisAlignment: MainAxisAlignment.center,
|
|
children: [
|
|
Icon(Icons.error_outline, color: Colors.red, size: 60),
|
|
SizedBox(height: 16),
|
|
Text(
|
|
"Failed to load stream.",
|
|
style: TextStyle(color: Colors.white, fontSize: 18),
|
|
),
|
|
SizedBox(height: 8),
|
|
Text(_errorMessage ?? "Unknown error", style: TextStyle(color: Colors.grey)),
|
|
TextButton(onPressed: () => Navigator.pop(context), child: Text("Go Back")),
|
|
],
|
|
)
|
|
: _controller.value.isInitialized
|
|
? AspectRatio(
|
|
aspectRatio: _controller.value.aspectRatio,
|
|
child: VideoPlayer(_controller),
|
|
)
|
|
: CircularProgressIndicator(color: Colors.white),
|
|
),
|
|
);
|
|
}
|
|
}
|