This commit is contained in:
2025-06-24 02:21:06 +02:00
parent 0d42fad708
commit 39fadc009f
7 changed files with 494 additions and 365 deletions

View File

@ -16,6 +16,7 @@ class VideoWidget extends StatefulWidget {
final bool isActive;
final bool fullScreen;
final VoidCallback? onInitialized;
final Duration? initialPosition;
const VideoWidget({
super.key,
@ -23,21 +24,18 @@ class VideoWidget extends StatefulWidget {
required this.isActive,
this.fullScreen = false,
this.onInitialized,
this.initialPosition,
});
@override
State<VideoWidget> createState() => _VideoWidgetState();
State<VideoWidget> createState() => VideoWidgetState();
}
class _VideoWidgetState extends State<VideoWidget> {
class VideoWidgetState extends State<VideoWidget> {
final MediaController mediaController = Get.find<MediaController>();
final SettingsController settingsController = Get.find<SettingsController>();
late CachedVideoPlayerPlusController videoController;
late Worker _muteWorker;
late Worker _timerResetWorker;
late Worker _hideControlsWorker;
bool _showControls = false;
Timer? _hideControlsTimer;
@override
void initState() {
@ -48,22 +46,6 @@ class _VideoWidgetState extends State<VideoWidget> {
videoController.setVolume(muted ? 0.0 : 1.0);
}
});
_timerResetWorker = ever(settingsController.videoControlsTimerNotifier, (
_,
) {
if (widget.isActive && mounted) {
if (!_showControls) {
setState(() => _showControls = true);
}
_startHideControlsTimer();
}
});
_hideControlsWorker = ever(settingsController.hideControlsNotifier, (_) {
if (mounted && _showControls) {
setState(() => _showControls = false);
_hideControlsTimer?.cancel();
}
});
}
Future<void> _initController() async {
@ -72,8 +54,14 @@ class _VideoWidgetState extends State<VideoWidget> {
videoPlayerOptions: VideoPlayerOptions(mixWithOthers: true),
);
await videoController.initialize();
widget.onInitialized?.call();
if (!mounted) return;
setState(() {});
if (widget.initialPosition != null) {
await videoController.seekTo(widget.initialPosition!);
}
widget.onInitialized?.call();
videoController.setLooping(true);
videoController.setVolume(settingsController.muted.value ? 0.0 : 1.0);
@ -93,10 +81,12 @@ class _VideoWidgetState extends State<VideoWidget> {
}
if (widget.isActive != oldWidget.isActive) {
if (widget.isActive) {
videoController.play();
} else {
videoController.pause();
if (videoController.value.isInitialized) {
if (widget.isActive) {
videoController.play();
} else {
videoController.pause();
}
}
}
}
@ -104,41 +94,12 @@ class _VideoWidgetState extends State<VideoWidget> {
@override
void dispose() {
_muteWorker.dispose();
_timerResetWorker.dispose();
_hideControlsWorker.dispose();
videoController.dispose();
_hideControlsTimer?.cancel();
super.dispose();
}
void _startHideControlsTimer() {
_hideControlsTimer?.cancel();
_hideControlsTimer = Timer(const Duration(seconds: 3), () {
if (mounted) {
setState(() => _showControls = false);
}
});
}
void _onTap({bool ctrlButton = false}) {
if (ctrlButton) {
_startHideControlsTimer();
return;
}
final bool newShowState = !_showControls;
setState(() => _showControls = newShowState);
if (newShowState) {
_startHideControlsTimer();
} else {
_hideControlsTimer?.cancel();
}
}
@override
Widget build(BuildContext context) {
final bool muted = settingsController.muted.value;
bool isAudio = widget.details.mime.startsWith('audio');
Widget mediaContent;
@ -165,26 +126,13 @@ class _VideoWidgetState extends State<VideoWidget> {
child: Stack(
alignment: Alignment.center,
children: [
GestureDetector(onTap: _onTap, child: mediaContent),
mediaContent,
AnimatedBuilder(
animation: videoController,
builder: (context, child) {
if (videoController.value.isInitialized && _showControls) {
if (videoController.value.isInitialized) {
return Positioned.fill(
child: GestureDetector(
onTap: _onTap,
child: Container(
color: Colors.black.withValues(alpha: 0.5),
child: VideoControlsOverlay(
controller: videoController,
onOverlayTap: () => _onTap(ctrlButton: true),
muted: muted,
onMuteToggle: () {
settingsController.toggleMuted();
},
),
),
),
child: VideoControlsOverlay(controller: videoController),
);
}
return const SizedBox.shrink();