this is auto generated from API :)
Go to file
JohnE ed67fdaff8 FIX: need to dispose of player and resources 2026-02-04 14:52:35 -08:00
.github NEW: copilot instructions added 2026-01-25 01:54:15 -08:00
docs MOD: added malloc lcc shiznit 2026-01-27 01:00:21 -08:00
example MOD: added malloc lcc shiznit 2026-01-27 01:00:21 -08:00
lib FIX: need to dispose of player and resources 2026-02-04 14:52:35 -08:00
test MOD: added malloc lcc shiznit 2026-01-27 01:00:21 -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
LICENSE NEW: init commit 2026-01-24 15:16:51 -08:00
README.md FIX: hwdec hardware decode setting now exposed, and windows uses auto 2026-01-26 22:45:54 -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
pubspec.yaml FIX: need to dispose of player and resources 2026-02-04 14:52:35 -08:00
splash_video.iml NEW: init commit 2026-01-24 15:16:51 -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.

Platform Support

Platform Supported
Android
iOS
macOS
Windows
Linux

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
  • 🎨 7 Scale Modes - Cover, contain, fill, fitWidth, fitHeight, scaleDown, none
  • 📐 Aspect Ratio Control - Full control over video sizing and scaling strategies
  • Hardware Acceleration - Smart platform defaults with 9 configurable decode modes

Installation

Add to your pubspec.yaml:

dependencies:
  splash_video: ^0.1.3

## Quick Start

### 1. Initialize in main()

```dart
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
  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(),
)

Video Scale Modes

Control how your video fills the screen with 7 different scale modes:

SplashVideo(
  source: AssetSource('assets/videos/splash.mp4'),
  nextScreen: HomeScreen(),
  videoConfig: VideoConfig(
    fitMode: VideoFitMode.cover, // Fill screen, may crop edges (best for splash)
  ),
)

Available Scale Modes:

  • VideoFitMode.cover - Fill screen, maintain aspect, may crop (recommended for splash screens)
  • VideoFitMode.contain - Fit inside, maintain aspect, may show letterboxing
  • VideoFitMode.fill - Stretch to fill (ignores aspect ratio, may distort)
  • VideoFitMode.fitWidth - Match width, maintain aspect
  • VideoFitMode.fitHeight - Match height, maintain aspect
  • VideoFitMode.scaleDown - Like contain but won't upscale beyond original size
  • VideoFitMode.none - Original size, centered

Quick Comparison:

Fit Mode Best For Maintains Aspect May Crop May Letterbox
cover Splash screens, hero sections
contain Viewing entire video
fill Exact fill (rare)
fitWidth Horizontal content Vertical Horizontal
fitHeight Vertical content Horizontal Vertical
scaleDown Small videos
none Pixel-perfect display

Custom Configuration

SplashVideo(
  source: AssetSource('assets/videos/splash.mp4'),
  nextScreen: HomeScreen(),
  videoConfig: VideoConfig(
    playImmediately: true,
    fitMode: VideoFitMode.cover,
    useSafeArea: true,
    volume: 50.0,
    enableAudio: true,
    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
  fitMode: VideoFitMode.cover,      // How video fills screen (7 modes)
  useSafeArea: false,               // Wrap in SafeArea
  volume: 80.0,                     // Volume (0-100), default 80
  enableAudio: true,                // Enable/disable audio track
  hwdec: HwdecMode.autoSafe,        // Hardware decode mode (9 modes)
  onPlayerInitialized: (player) { },// Player ready callback
)

Parameters:

  • playImmediately (bool) - Start playing immediately after load. Default: true
  • fitMode (VideoFitMode) - Video sizing strategy. Default: VideoFitMode.cover
  • useSafeArea (bool) - Avoid notches and system UI. Default: false
  • volume (double) - Initial volume 0-100. Default: 80.0
  • enableAudio (bool) - Enable audio track (more efficient than volume=0). Default: true
  • hwdec (HwdecMode?) - Hardware decode mode. Default: null (smart platform defaults)
  • onPlayerInitialized (Function?) - Callback when Player is ready

HwdecMode

Hardware decode modes for video playback. When null, smart platform defaults are used:

  • Windows: HwdecMode.autoSafe (avoids CUDA errors on non-NVIDIA systems)
  • Other platforms: HwdecMode.auto
// Let the package use smart defaults (recommended)
VideoConfig()  // hwdec: null

// Explicit safe mode (recommended for Windows)
VideoConfig(hwdec: HwdecMode.autoSafe)

// Force software decoding
VideoConfig(hwdec: HwdecMode.disabled)

// Platform-specific
VideoConfig(hwdec: HwdecMode.d3d11va)     // Windows DirectX 11
VideoConfig(hwdec: HwdecMode.videoToolbox) // macOS/iOS
VideoConfig(hwdec: HwdecMode.vaapi)        // Linux
VideoConfig(hwdec: HwdecMode.mediaCodec)   // Android

Available Modes:

Mode String Value Description
auto "auto" Try all methods (may log errors on Windows)
autoSafe "auto-safe" Safe methods only (Windows recommended)
autoCopy "auto-copy" Auto with memory copy
disabled "no" Software decoding only
d3d11va "d3d11va" DirectX 11 (Windows)
dxva2 "dxva2" DirectX 9 (Windows legacy)
videoToolbox "videotoolbox" VideoToolbox (macOS/iOS)
vaapi "vaapi" VA-API (Linux)
mediaCodec "mediacodec" MediaCodec (Android)

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)

Migration Guide

From v0.0.1 to v0.0.2+

The VideoAspectRatio enum has been replaced with VideoFitMode for better video sizing control:

Old API (Deprecated but still works):

VideoConfig(
  videoVisibilityEnum: VideoAspectRatio.useFullScreen,
)

New API (Recommended):

VideoConfig(
  fitMode: VideoFitMode.cover,
)

Migration Table:

Old API New API Notes
VideoAspectRatio.useFullScreen VideoFitMode.cover Now properly fills screen
VideoAspectRatio.useAspectRatio VideoFitMode.contain Same behavior
VideoAspectRatio.none VideoFitMode.none Same behavior
videoVisibilityEnum parameter fitMode parameter Renamed for clarity

The old API will be removed in v1.0.0. Update your code to use the new fitMode parameter.

Lifecycle Methods

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

// Resumes frame painting
SplashVideo(
  source: AssetSource(Assets.splashVideo),
  backgroundColor: Colors.black,
  onVideoComplete: () => _videoComplete(),
  videoConfig: const VideoConfig(
    scale: VideoScaleMode.fill,
    useSafeArea: true,
  )
);

License

MIT License - see LICENSE file for details.