lum_splash_video/lib/splash_video_controller.dart

117 lines
3.5 KiB
Dart

/*
* Copyright (c) 2025
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
import 'package:media_kit/media_kit.dart';
/// Controller for managing video splash screen playback
///
/// Provides control over video playback and access to the underlying
/// media_kit Player instance.
class SplashVideoController {
/// Creates a SplashVideoController
///
/// [loopVideo] - When true, video will loop infinitely until manually stopped
SplashVideoController({
this.loopVideo = false,
});
/// Whether the video should loop infinitely
///
/// When true:
/// - Video will restart automatically when it ends
/// - User must call [skip] or [pause] to stop playback
/// - Cannot use onVideoComplete or nextScreen callbacks
final bool loopVideo;
Player? _player;
bool _isDisposed = false;
/// Access to the underlying media_kit Player instance
///
/// Provides full control over video playback including:
/// - Position seeking
/// - Volume control
/// - Playback rate
/// - Stream listeners for state changes
///
/// Throws [StateError] if accessed before initialization
Player get player {
if (_player == null) {
throw StateError(
'Player not initialized. Controller must be attached to SplashVideo widget.',
);
}
return _player!;
}
/// Internal method to attach the Player instance
void attach(Player player) {
if (_isDisposed) {
throw StateError('Cannot attach player to disposed controller');
}
_player = player;
}
/// Starts or resumes video playback
Future<void> play() async {
if (_isDisposed) return;
await player.play();
}
/// Pauses video playback
Future<void> pause() async {
if (_isDisposed) return;
await player.pause();
}
/// Completes the video splash immediately
///
/// This will:
/// - Stop video playback
/// - Trigger navigation or completion callbacks
/// - Clean up resources
Future<void> skip() async {
if (_isDisposed) return;
await player.pause();
// The SplashVideo widget will handle navigation
_skipRequested = true;
}
bool _skipRequested = false;
/// Whether skip was requested by the user
bool get skipRequested => _skipRequested;
/// Disposes the controller and releases resources
///
/// Should be called when the splash screen is no longer needed
void dispose() {
if (_isDisposed) return;
_isDisposed = true;
_player?.dispose();
_player = null;
}
/// Whether the controller has been disposed
bool get isDisposed => _isDisposed;
}