smooth video splash screens using media_kit, native splash screens and video playback, media_kit uses native library of libmpv
Go to file
JohnE e735aa5a49 NEW: first working splash video alpha 2026-01-24 19:42:44 -08:00
example NEW: first working splash video alpha 2026-01-24 19:42:44 -08:00
lib NEW: first working splash video alpha 2026-01-24 19:42:44 -08:00
test NEW: first working splash video alpha 2026-01-24 19:42:44 -08:00
.gitignore NEW: init commit 2026-01-24 15:16:51 -08:00
.metadata NEW: init commit 2026-01-24 15:16:51 -08:00
CHANGELOG.md NEW: init commit 2026-01-24 15:16:51 -08:00
LICENSE NEW: init commit 2026-01-24 15:16:51 -08:00
README.md NEW: first working splash video alpha 2026-01-24 19:42:44 -08:00
analysis_options.yaml NEW: init commit 2026-01-24 15:16:51 -08:00
changelog.rst NEW: first working splash video alpha 2026-01-24 19:42:44 -08:00
implementation_complete.rst NEW: first working splash video alpha 2026-01-24 19:42:44 -08:00
implementation_plan.rst NEW: first working splash video alpha 2026-01-24 19:42:44 -08:00
pubspec.yaml NEW: first working splash video alpha 2026-01-24 19:42:44 -08:00
readme.rst NEW: first working splash video alpha 2026-01-24 19:42:44 -08:00
splash_video.iml NEW: init commit 2026-01-24 15:16:51 -08:00
troubleshooting.rst NEW: first working splash video alpha 2026-01-24 19:42:44 -08:00

README.md

splash_video

A Flutter package for creating smooth video splash screens using media_kit. Provides seamless transitions from native splash screens to video playback with flexible overlay support and manual controls.

Features

  • ✨ Smooth Transitions - Defer first frame pattern prevents jank between native and video splash
  • 🎬 Media Kit Integration - Cross-platform video playback with hardware acceleration
  • 🎮 Manual Controls - Full controller access for play, pause, skip operations
  • 🔄 Looping Support - Infinite video loops with user-controlled exit
  • 📱 Flexible Overlays - Title, footer, and custom overlay widgets
  • 🎯 Auto-Navigation - Automatic screen transitions or manual control
  • 🎨 Customizable - Aspect ratio, fullscreen, volume, and more

Installation

Add to your pubspec.yaml:

dependencies:
  splash_video: ^0.0.1
  media_kit: ^1.2.6
  media_kit_video: ^2.0.1
  video_player_media_kit: ^2.0.0
  
  # Platform-specific video libraries
  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

Quick Start

1. Initialize in main()

import 'package:flutter/material.dart';
import 'package:media_kit/media_kit.dart';
import 'package:splash_video/splash_video.dart';

void main() {
  WidgetsFlutterBinding.ensureInitialized();
  
  // Required: Initialize media_kit
  MediaKit.ensureInitialized();
  
  // Optional: Defer first frame for smooth transition
  SplashVideo.initialize();
  
  runApp(MyApp());
}

2. Basic Usage (Auto-Navigate)

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: SplashVideo(
        source: AssetSource('assets/videos/splash.mp4'),
        nextScreen: HomeScreen(),
        backgroundColor: Colors.black,
      ),
    );
  }
}

Usage Examples

Auto-Navigation

Video plays and automatically navigates to the next screen:

SplashVideo(
  source: AssetSource('assets/videos/splash.mp4'),
  nextScreen: HomeScreen(),
  backgroundColor: Colors.black,
)

Manual Control

Use a callback for custom logic after video completes:

SplashVideo(
  source: AssetSource('assets/videos/splash.mp4'),
  onVideoComplete: () {
    // Custom logic
    Navigator.pushReplacement(
      context,
      MaterialPageRoute(builder: (_) => HomeScreen()),
    );
  },
)

Looping Video with Controller

Create an infinite loop that the user can manually exit:

class MyScreen extends StatefulWidget {
  @override
  State<MyScreen> createState() => _MyScreenState();
}

class _MyScreenState extends State<MyScreen> {
  late final SplashVideoController controller;

  @override
  void initState() {
    super.initState();
    controller = SplashVideoController(loopVideo: true);
  }

  @override
  void dispose() {
    controller.dispose();
    super.dispose();
  }

  void _onSkip() {
    controller.skip();
    Navigator.pushReplacement(
      context,
      MaterialPageRoute(builder: (_) => HomeScreen()),
    );
  }

  @override
  Widget build(BuildContext context) {
    return SplashVideo(
      source: AssetSource('assets/videos/splash.mp4'),
      controller: controller,
      footerWidget: ElevatedButton(
        onPressed: _onSkip,
        child: Text('Skip'),
      ),
    );
  }
}

With Overlays

Add title, footer, and custom overlays:

SplashVideo(
  source: AssetSource('assets/videos/splash.mp4'),
  nextScreen: HomeScreen(),
  backgroundColor: Colors.black,
  
  // Title at top
  titleWidget: Padding(
    padding: EdgeInsets.all(20),
    child: Text(
      'Welcome',
      style: TextStyle(fontSize: 32, color: Colors.white),
    ),
  ),
  
  // Footer at bottom
  footerWidget: CircularProgressIndicator(),
  
  // Custom overlay with full control
  overlayBuilder: (context) => Positioned(
    right: 20,
    top: 100,
    child: Text('v1.0.0', style: TextStyle(color: Colors.white)),
  ),
)

Network Video

Load video from URL:

SplashVideo(
  source: NetworkFileSource('https://example.com/splash.mp4'),
  nextScreen: HomeScreen(),
)

Custom Configuration

SplashVideo(
  source: AssetSource('assets/videos/splash.mp4'),
  nextScreen: HomeScreen(),
  videoConfig: VideoConfig(
    playImmediately: true,
    videoVisibilityEnum: VisibilityEnum.useAspectRatio,
    useSafeArea: true,
    volume: 50.0,
    onPlayerInitialized: (player) {
      print('Player ready: ${player.state.duration}');
    },
  ),
)

API Reference

SplashVideo

Main widget for video splash screen.

Parameter Type Required Description
source Source ✅ Video source (Asset, Network, DeviceFile, Bytes)
controller SplashVideoController? ⚠️ Required when looping is enabled
videoConfig VideoConfig? ❌ Playback configuration
backgroundColor Color? ❌ Background color behind video
titleWidget Widget? ❌ Widget at top of screen
footerWidget Widget? ❌ Widget at bottom of screen
overlayBuilder Widget Function(BuildContext)? ❌ Custom overlay builder
nextScreen Widget? ❌ Screen to navigate to (auto-navigate)
onVideoComplete VoidCallback? ❌ Callback when video completes (manual control)
onSourceLoaded VoidCallback? ❌ Callback when video loads

Validation Rules:

  • Cannot use both nextScreen and onVideoComplete
  • Looping videos require controller and cannot use nextScreen or onVideoComplete

SplashVideoController

Controls video playback.

final controller = SplashVideoController(loopVideo: true);

// Access media_kit Player
controller.player.play();
controller.player.pause();
controller.player.seek(Duration(seconds: 5));

// Controller methods
controller.play();
controller.pause();
controller.skip(); // Complete immediately
controller.dispose();

VideoConfig

Configuration for video playback.

VideoConfig(
  playImmediately: true,                           // Auto-play on load
  videoVisibilityEnum: VisibilityEnum.useFullScreen, // Display mode
  useSafeArea: false,                              // Wrap in SafeArea
  volume: 100.0,                                   // Volume (0-100)
  onPlayerInitialized: (player) { },              // Player callback
)

Source Types

// Asset bundled with app
AssetSource('assets/videos/splash.mp4')

// Network URL
NetworkFileSource('https://example.com/video.mp4')

// Device file
DeviceFileSource('/path/to/video.mp4')

// Raw bytes
BytesSource(videoBytes)

VisibilityEnum

VisibilityEnum.useFullScreen   // Fill entire screen
VisibilityEnum.useAspectRatio  // Maintain aspect ratio
VisibilityEnum.none            // No special sizing

Lifecycle Methods

// Defer first frame (prevents jank)
SplashVideo.initialize();

// Resume Flutter rendering
SplashVideo.resume();

Platform Support

Platform Supported
Android ✅
iOS ✅
macOS ✅
Windows ✅
Linux ✅
Web ✅

License

MIT License - see LICENSE file for details.