FIX: need to dispose of player and resources

This commit is contained in:
JohnE 2026-02-04 14:52:35 -08:00
parent a7bab3d8be
commit ed67fdaff8
2 changed files with 56 additions and 4 deletions

View File

@ -32,7 +32,9 @@ class SplashVideoController {
/// [loopVideo] - When true, video will loop infinitely until manually stopped
SplashVideoController({
this.loopVideo = false,
});
}) {
_activeControllers.add(this);
}
/// Whether the video should loop infinitely
///
@ -45,6 +47,37 @@ class SplashVideoController {
Player? _player;
bool _isDisposed = false;
// Track all active controllers for cleanup during hot restart
static final Set<SplashVideoController> _activeControllers = {};
/// Disposes all active SplashVideoController instances
///
/// Call this before hot restart to prevent "Callback invoked after it has
/// been deleted" crashes. This stops all MPV callback activity before the
/// Dart isolate is destroyed.
///
/// Usage in main.dart:
/// ```dart
/// // In a StatefulWidget wrapping your app:
/// @override
/// void reassemble() {
/// SplashVideoController.disposeAll();
/// super.reassemble();
/// }
/// ```
static Future<void> disposeAll() async {
final controllers = Set<SplashVideoController>.from(_activeControllers);
for (final controller in controllers) {
controller.dispose();
}
_activeControllers.clear();
}
/// Returns the number of active (non-disposed) controllers
///
/// Useful for debugging resource leaks
static int get activeControllerCount => _activeControllers.length;
/// Access to the underlying media_kit Player instance
///
/// Provides full control over video playback including:
@ -103,11 +136,30 @@ class SplashVideoController {
/// Disposes the controller and releases resources
///
/// Should be called when the splash screen is no longer needed
/// This method pauses the player first to stop MPV callback activity,
/// then disposes after a short delay. This helps prevent crashes during
/// hot restart when the Dart isolate is destroyed while MPV's native
/// thread is still running.
///
/// Should be called when the splash screen is no longer needed.
void dispose() {
if (_isDisposed) return;
_isDisposed = true;
_player?.dispose();
_activeControllers.remove(this);
final player = _player;
if (player != null) {
// Pause first to stop callback activity before disposing
player.pause().then((_) {
// Small delay to let MPV thread settle before disposal
Future.delayed(const Duration(milliseconds: 50), () {
player.dispose();
});
}).catchError((_) {
// If pause fails, dispose anyway
player.dispose();
});
}
_player = null;
}

View File

@ -1,6 +1,6 @@
name: splash_video
description: "Simple video splash screen for Flutter applications."
version: 0.1.3
version: 0.1.6
homepage: malloc.io
environment: