==================================== Splash Video Implementation Plan ==================================== :Date: January 24, 2026 :Version: 0.0.1 :Author: Development Team Overview ======== This document outlines the implementation plan for the ``splash_video`` Flutter package, a video splash screen library using ``media_kit`` for video playback. The design follows patterns from ``splash_master`` but focuses exclusively on video playback functionality. Design Principles ================= 1. **Single Responsibility**: Only video splash functionality (no Lottie, Rive, or CLI tools) 2. **Media Kit Integration**: Use ``media_kit`` + ``video_player_media_kit`` for cross-platform video playback 3. **Defer First Frame Pattern**: Smooth transition from native splash to video splash 4. **Manual Control**: Provide controller for advanced use cases 5. **Flexible Overlays**: Support custom UI elements over video Architecture ============ Two-Widget Pattern ------------------ The package uses a two-widget architecture: 1. **SplashVideo**: Main public widget handling lifecycle, navigation, and timing 2. **VideoSplash**: Internal widget focused on video playback using media_kit Core Components =============== 1. SplashVideoController ------------------------ **Purpose**: Provides control over video playback and configuration **Properties**: - ``loopVideo: bool`` - Enable infinite looping - ``player: Player`` - Access to media_kit Player instance **Methods**: - ``play()`` - Start video playback - ``pause()`` - Pause video playback - ``skip()`` - Complete video immediately and trigger navigation - ``dispose()`` - Clean up resources **Configuration Rules**: - If ``loopVideo == true``: Controller is **required** - Looping videos cannot use ``onVideoComplete`` or ``nextScreen`` 2. SplashVideo Widget --------------------- **Purpose**: Main entry point for video splash functionality **Parameters**: Required: - ``source: Source`` - Video source (Asset, Network, DeviceFile, Bytes) Optional Configuration: - ``controller: SplashVideoController?`` - Required if looping - ``videoConfig: VideoConfig?`` - Playback configuration - ``backgroundColor: Color?`` - Background color behind video Overlay Widgets: - ``titleWidget: Widget?`` - Widget positioned at top - ``footerWidget: Widget?`` - Widget positioned at bottom - ``overlayBuilder: Widget Function(BuildContext)?`` - Custom overlay with full control Navigation/Completion: - ``nextScreen: Widget?`` - Auto-navigate on completion - ``onVideoComplete: VoidCallback?`` - Manual control callback (priority over nextScreen) Lifecycle: - ``onSourceLoaded: VoidCallback?`` - Called when video loads (defaults to resume()) 3. VideoConfig Class -------------------- **Purpose**: Configuration options for video playback **Properties**: - ``playImmediately: bool`` (default: true) - Auto-play on load - ``videoVisibilityEnum: VisibilityEnum`` (default: useFullScreen) - Display mode - ``useSafeArea: bool`` (default: false) - Wrap in SafeArea - ``volume: double`` (default: 100.0) - Initial volume (0.0-100.0) - ``onPlayerInitialized: Function(Player)?`` - Callback with Player access **Note**: ``loopVideo`` removed (now in controller) 4. Source Types --------------- Sealed class hierarchy for video sources: - ``AssetSource(String path)`` - Bundled asset - ``NetworkFileSource(String path)`` - Remote URL - ``DeviceFileSource(String path)`` - Local file system - ``BytesSource(Uint8List bytes)`` - In-memory bytes 5. VisibilityEnum ----------------- Controls video display behavior: - ``useFullScreen`` - Fill entire screen - ``useAspectRatio`` - Maintain video aspect ratio - ``none`` - No special sizing Validation Rules ================ The widget enforces these rules at runtime: Looping Videos -------------- When ``controller.loopVideo == true``: - ✅ Controller MUST be provided - ❌ Cannot set ``onVideoComplete`` - ❌ Cannot set ``nextScreen`` - ✅ User must call ``controller.skip()`` to end Non-Looping Videos ------------------ When not looping: - ✅ Can set ``nextScreen`` (auto-navigate) - ✅ Can set ``onVideoComplete`` (manual control) - ❌ Cannot set BOTH ``nextScreen`` AND ``onVideoComplete`` (throws error) Overlay Rendering Order ======================== Stack layers (bottom to top): 1. **Video** - Base layer 2. **titleWidget** - Positioned at top of screen 3. **footerWidget** - Positioned at bottom of screen 4. **overlayBuilder** - Full custom overlay (rendered last) All overlays are optional and can be combined. Lifecycle Flow ============== Initialization Flow ------------------- 1. ``SplashVideo.initialize()`` called in ``main()`` - Defers Flutter's first frame - Native splash remains visible 2. ``SplashVideo`` widget mounts - Creates/receives controller - Validates configuration - Initializes ``VideoSplash`` 3. Video loads - ``onSourceLoaded`` callback fires - Defaults to ``SplashVideo.resume()`` - Flutter frames begin rendering - Smooth transition from native to video 4. Video plays - Overlays render on top - User can interact via controller Completion Flow (Non-Looping) ------------------------------ 1. Video reaches end 2. Check for completion handlers: - If ``onVideoComplete`` set → call it - Else if ``nextScreen`` set → auto-navigate - Else → do nothing Completion Flow (Looping) -------------------------- 1. Video loops infinitely 2. User must call ``controller.skip()`` or ``controller.pause()`` 3. No automatic completion Implementation Checklist ========================= Phase 1: Core Implementation ----------------------------- 1. ✅ Create ``SplashVideoController`` class 2. ✅ Update ``VideoConfig`` (remove loopVideo) 3. ✅ Update ``VideoSplash`` widget for media_kit integration 4. ✅ Create main ``SplashVideo`` widget with: - Validation logic - Overlay support - Navigation handling - Lifecycle management 5. ✅ Update ``lib/splash_video.dart`` exports 6. ✅ Create example application 7. ✅ Update README.md with usage examples Phase 2: Future Enhancements ----------------------------- - 🔜 Boomerang loop support - 🔜 Additional overlay positioning options - 🔜 Advanced playback controls - 🔜 Analytics/telemetry hooks Example Usage ============= Non-Looping with Auto-Navigation --------------------------------- .. code-block:: dart void main() { WidgetsFlutterBinding.ensureInitialized(); SplashVideo.initialize(); runApp(MyApp()); } class MyApp extends StatelessWidget { @override Widget build(BuildContext context) { return MaterialApp( home: SplashVideo( source: AssetSource('assets/videos/splash.mp4'), nextScreen: HomeScreen(), backgroundColor: Colors.black, ), ); } } Looping with Manual Control ---------------------------- .. code-block:: dart class MyApp extends StatefulWidget { @override State createState() => _MyAppState(); } class _MyAppState extends State { late SplashVideoController controller; @override void initState() { super.initState(); controller = SplashVideoController(loopVideo: true); } @override void dispose() { controller.dispose(); super.dispose(); } @override Widget build(BuildContext context) { return MaterialApp( home: SplashVideo( source: AssetSource('assets/videos/splash.mp4'), controller: controller, titleWidget: Text( 'Welcome', style: TextStyle(fontSize: 32, color: Colors.white), ), footerWidget: ElevatedButton( onPressed: () => controller.skip(), child: Text('Skip'), ), ), ); } } Manual Completion Control -------------------------- .. code-block:: dart SplashVideo( source: AssetSource('assets/videos/splash.mp4'), onVideoComplete: () { // Custom logic Navigator.pushReplacement( context, MaterialPageRoute(builder: (_) => HomeScreen()), ); }, titleWidget: Text('Loading...'), ) Custom Overlay -------------- .. code-block:: dart SplashVideo( source: NetworkFileSource('https://example.com/splash.mp4'), overlayBuilder: (context) => Stack( children: [ Positioned( top: 50, left: 0, right: 0, child: Center(child: Text('Custom UI')), ), Positioned( bottom: 20, right: 20, child: CircularProgressIndicator(), ), ], ), ) Dependencies ============ Required packages in ``pubspec.yaml``: .. code-block:: yaml dependencies: flutter: sdk: flutter media_kit: ^1.2.6 media_kit_video: ^2.0.1 video_player_media_kit: ^2.0.0 # Platform-specific libs media_kit_libs_android_video: any media_kit_libs_ios_video: any media_kit_libs_macos_video: any media_kit_libs_windows_video: any media_kit_libs_linux: any Testing Strategy ================ Unit Tests ---------- - Source type validation - Controller state management - Configuration validation - Overlay composition Widget Tests ------------ - Video playback initialization - Navigation behavior - Overlay rendering - Lifecycle management Integration Tests ----------------- - End-to-end splash flow - Platform-specific video playback - Performance benchmarks Notes ===== - All file and class names follow lowercase conventions - Follows Flutter/Dart style guide - Media kit requires initialization in main() - Defer pattern prevents frame jank during transition - Controller pattern provides maximum flexibility Document Status =============== :Status: Approved for Implementation :Next Review: After Phase 1 completion