smart_video_thumbnail 0.6.0 copy "smart_video_thumbnail: ^0.6.0" to clipboard
smart_video_thumbnail: ^0.6.0 copied to clipboard

High-performance Flutter plugin for extracting video thumbnails using native FFmpeg engine. Supports all video formats (MP4, AVI, MKV, FLV, etc.) with CPU-only decoding.

smart_video_thumbnail #

pub package Platform License: MIT

A powerful Flutter plugin for generating video thumbnails using native FFmpeg engine. Fast, reliable, and supports all major video formats.


πŸ“Έ Screenshot #

Example App

Example app showing video thumbnails in a grid layout


✨ Features #

  • 🎬 Native FFmpeg - Uses CPU-only decoding for maximum compatibility
  • πŸ“¦ All Formats - Supports MP4, AVI, MKV, FLV, WMV and other FFmpeg formats
  • πŸš€ Fast - Optimized frame extraction with minimal overhead
  • πŸ’Ύ Caching - Automatic thumbnail caching for better performance (v0.2.0)
  • πŸ“Š Progress - Real-time progress callbacks during generation (v0.2.0)
  • 🎯 Flexible - Multiple seek strategies (normal, keyframe, firstFrame)
  • πŸ”§ Independent - No dependency on MediaMetadataRetriever or system APIs
  • πŸ’ͺ Reliable - Works with corrupted or unusual video files
  • πŸ“± Optimized - ARM-only builds for smaller APK size (v0.2.0)

πŸ“¦ Installation #

Add this to your package's pubspec.yaml file:

dependencies:
  smart_video_thumbnail: ^0.2.0

Then run:

flutter pub get

Android Setup #

No additional setup required! The plugin automatically downloads the native FFmpeg library from JitPack.

Note: The first build may take a bit longer as Gradle downloads the native library (~8MB).

iOS Setup #

No additional setup required! The plugin uses native AVFoundation framework for video processing.

Note: Make sure your app has the necessary permissions in Info.plist:

<key>NSPhotoLibraryUsageDescription</key>
<string>This app needs access to your photo library to select videos.</string>

Implementation Note: iOS version uses AVFoundation instead of FFmpeg for better system integration and smaller binary size.

macOS Setup #

No additional setup required! The plugin uses native AVFoundation framework for video processing.

Note: Make sure your app has the necessary entitlements for file access:

  • com.apple.security.files.user-selected.read-only
  • com.apple.security.files.user-selected.read-write

These are required for accessing video files selected by the user.

Implementation Note: macOS version uses AVFoundation instead of FFmpeg for better system integration and smaller binary size.


πŸš€ Usage #

Basic Example #

import 'package:smart_video_thumbnail/smart_video_thumbnail.dart';

// Extract thumbnail at 1 second
final thumbnail = await SmartVideoThumbnail.getThumbnail(
  videoPath: '/path/to/video.mp4',
  timeMs: 1000,
  width: 320,
  height: 180,
);

if (thumbnail != null) {
  // thumbnail is Uint8List with RGBA8888 data
  // Size: width * height * 4 bytes
  print('Thumbnail extracted: ${thumbnail.length} bytes');
}

Display with Image Widget #

import 'dart:ui' as ui;
import 'dart:async';
import 'package:flutter/material.dart';

Future<ui.Image?> createImageFromRGBA(
  Uint8List rgba,
  int width,
  int height,
) async {
  final completer = Completer<ui.Image>();

  ui.decodeImageFromPixels(
    rgba,
    width,
    height,
    ui.PixelFormat.rgba8888,
    (ui.Image image) {
      completer.complete(image);
    },
  );

  return completer.future;
}

// In your widget
final thumbnail = await SmartVideoThumbnail.getThumbnail(
  videoPath: videoPath,
  width: 320,
  height: 180,
);

if (thumbnail != null) {
  final image = await createImageFromRGBA(thumbnail, 320, 180);
  return RawImage(image: image);
}

Extraction Strategies #

// Normal seek (default)
final thumbnail1 = await SmartVideoThumbnail.getThumbnail(
  videoPath: videoPath,
  strategy: ThumbnailStrategy.normal,
);

// Keyframe-focused seek (for AVI/FLV)
final thumbnail2 = await SmartVideoThumbnail.getThumbnail(
  videoPath: videoPath,
  strategy: ThumbnailStrategy.keyframe,
);

// First available frame (fastest)
final thumbnail3 = await SmartVideoThumbnail.getThumbnail(
  videoPath: videoPath,
  strategy: ThumbnailStrategy.firstFrame,
);

πŸ“– API Reference #

getThumbnail #

Extracts a thumbnail from a video file.

Parameters:

Parameter Type Required Default Description
videoPath String βœ… Yes - Path to the video file
timeMs int ❌ No 1000 Target position in milliseconds
width int ❌ No size Thumbnail width in pixels
height int ❌ No size * 9/16 Thumbnail height in pixels
size int ❌ No 720 Alternative way to set dimensions
strategy ThumbnailStrategy ❌ No normal Frame extraction strategy

Returns: Future<Uint8List?> - RGBA8888 pixel data or null on error

Data Format #

The plugin returns Uint8List with RGBA8888 format:

  • 4 bytes per pixel (Red, Green, Blue, Alpha)
  • Data size: width * height * 4 bytes
  • Pixel order: left to right, top to bottom

πŸ“± Platform Support #

Platform Status Architectures Backend
Android βœ… Supported arm64-v8a, armeabi-v7a FFmpeg 4.4.2
iOS βœ… Supported arm64, armv7 AVFoundation
macOS βœ… Supported x86_64, arm64 AVFoundation
Windows βœ… Supported x64 Media Foundation
Web βœ… Supported All browsers HTML5 Video

Supported Video Formats by Platform #

πŸ€– Android (FFmpeg)

Supports all FFmpeg-compatible formats:

  • βœ… Container formats: MP4, AVI, MKV, FLV, WMV, MOV, 3GP, WebM, OGG, and more
  • βœ… Video codecs: H.264, H.265/HEVC, MPEG-4, VP8, VP9, Theora, WMV, DivX, Xvid, and more
  • βœ… Audio codecs: AAC, MP3, Vorbis, Opus, WMA, FLAC, and more

Note: FFmpeg provides the most comprehensive format support across all platforms.

🍎 iOS (AVFoundation)

Supports system-native formats:

  • βœ… Container formats: MP4, MOV, M4V, 3GP
  • βœ… Video codecs: H.264, H.265/HEVC, MPEG-4
  • βœ… Audio codecs: AAC, MP3, Apple Lossless

Limitations:

  • ❌ AVI, MKV, FLV, WMV - not supported (requires FFmpeg)
  • ⚠️ Smaller binary size (~2MB vs ~8MB on Android)
  • ⚠️ Better battery efficiency due to hardware acceleration

πŸ–₯️ macOS (AVFoundation)

Supports system-native formats:

  • βœ… Container formats: MP4, MOV, M4V, 3GP
  • βœ… Video codecs: H.264, H.265/HEVC, MPEG-4, ProRes
  • βœ… Audio codecs: AAC, MP3, Apple Lossless, FLAC

Limitations:

  • ❌ AVI, MKV, FLV, WMV - not supported (requires FFmpeg)
  • ⚠️ Smaller binary size compared to FFmpeg
  • ⚠️ Better performance due to hardware acceleration

πŸͺŸ Windows (Media Foundation)

Supports Windows-native formats:

  • βœ… Container formats: MP4, AVI, WMV, ASF
  • βœ… Video codecs: H.264, H.265/HEVC, MPEG-4, WMV
  • βœ… Audio codecs: AAC, MP3, WMA

Limitations:

  • ❌ MKV, FLV - limited support
  • ⚠️ Format support depends on installed codecs

🌐 Web (HTML5 Video)

Supports browser-native formats only:

  • βœ… MP4 (H.264/AAC) - Best compatibility, supported by all modern browsers
  • βœ… WebM (VP8/VP9/Vorbis/Opus) - Good support in Chrome, Firefox, Edge
  • βœ… Ogg (Theora/Vorbis) - Supported in Firefox, Chrome

Limitations:

  • ❌ AVI, WMV, FLV, MKV - NOT supported (no browser codecs)
  • ⚠️ Format support varies by browser
  • ⚠️ Requires video file to be loaded into memory
  • πŸ’‘ Recommendation: Use MP4 (H.264) for maximum compatibility

Browser Compatibility:

Format Chrome Firefox Safari Edge
MP4 βœ… βœ… βœ… βœ…
WebM βœ… βœ… ❌ βœ…
Ogg βœ… βœ… ❌ ❌
AVI ❌ ❌ ❌ ❌
WMV ❌ ❌ ❌ ❌

Format Recommendations #

For maximum cross-platform compatibility:

  • 🎯 Primary: MP4 (H.264 video + AAC audio)
  • 🎯 Alternative: WebM (VP9 video + Opus audio) for web

For Android-only apps:

  • 🎯 Use any format - FFmpeg supports everything

For iOS/macOS apps:

  • 🎯 Stick to MP4, MOV, M4V formats
  • 🎯 Use H.264 or H.265 codecs

For web apps:

  • 🎯 Must use: MP4 (H.264) - only reliable option
  • ⚠️ Convert AVI/WMV/FLV to MP4 before using

πŸ”§ Working with Unsupported Formats #

If you need to work with formats not natively supported on your platform (e.g., AVI on iOS, WMV on Web), you have several options:

Using FFmpeg CLI:

ffmpeg -i input.avi -c:v libx264 -c:a aac output.mp4

Using ffmpeg_kit_flutter in your app:

import 'package:ffmpeg_kit_flutter/ffmpeg_kit.dart';

Future<String?> convertToMp4(String inputPath) async {
  final outputPath = inputPath.replaceAll(RegExp(r'\.\w+$'), '.mp4');
  await FFmpegKit.execute('-i "$inputPath" -c:v libx264 -c:a aac "$outputPath"');
  return outputPath;
}

// Then use the converted file
final mp4Path = await convertToMp4('/path/to/video.avi');
if (mp4Path != null) {
  final thumbnail = await SmartVideoThumbnail.getThumbnail(
    videoPath: mp4Path,
  );
}

Option 2: Future FFmpeg Extension (Coming Soon) #

We're planning an optional smart_video_thumbnail_ffmpeg package that will add support for all formats on iOS/macOS:

dependencies:
  smart_video_thumbnail: ^0.4.0
  smart_video_thumbnail_ffmpeg: ^1.0.0 # Optional, adds +20MB

Note: This will increase app size by ~20-30 MB but provide full format support.

Option 3: Server-Side Conversion (For Web) #

For web applications, consider converting videos on your server before sending to clients.

πŸ“š For detailed solutions and recommendations, see UNSUPPORTED_FORMATS_SOLUTION.md


πŸ“‹ Requirements #

Android #

  • minSdk: 26 (Android 8.0+)
  • targetSdk: 34
  • NDK: r21 or higher
  • CMake: 3.18.1 or higher
  • FFmpeg: Included in plugin (v4.4.2)

iOS #

  • Deployment Target: iOS 12.0 or higher
  • Xcode: 12.0 or higher
  • Video Processing: Native AVFoundation framework

macOS #

  • Deployment Target: 10.14 or higher
  • Xcode: 12.0 or higher
  • Video Processing: Native AVFoundation framework

πŸ—οΈ Architecture #

The plugin consists of three layers:

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚      Flutter App (Dart)         β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
             β”‚ MethodChannel
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β–Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚  SmartVideoThumbnailPlugin (Kt) β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
             β”‚ JNI
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β–Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚   SmartFfmpegBridge (C/C++)     β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
             β”‚
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β–Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚  FFmpeg Libraries (v4.4.2)      β”‚
β”‚  β€’ libavformat β€’ libavcodec     β”‚
β”‚  β€’ libswscale  β€’ libavutil      β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Layers:

  1. Dart API - Flutter interface (smart_video_thumbnail.dart)
  2. Kotlin Bridge - JNI bridge (SmartVideoThumbnailPlugin.kt)
  3. Native Library - FFmpeg decoding (smart-ffmpeg-android)

⚑ Performance #

Typical frame extraction times:

Format Codec Time
MP4 H.264 50-150ms
AVI MPEG-4 100-200ms
MKV H.265 150-300ms
FLV - 100-250ms

Performance factors:

  • Video format and codec
  • Output image size
  • Frame position in video
  • Device performance

πŸ› Debugging #

Enable Android logging:

adb logcat | grep -E "SmartVideoThumbnail|SmartFfmpegBridge"

Example logs:

I/SmartVideoThumbnail: 🎬 getThumbnail: path=/path/to/video.mp4, targetMs=1000, size=320x180
I/SmartFfmpegBridge: Extracting thumbnail from: /path/to/video.mp4 at 1000 ms
I/SmartFfmpegBridge: Successfully extracted thumbnail: 230400 bytes
I/SmartVideoThumbnail: βœ… getThumbnail: Thumbnail extracted successfully (230400 bytes)

🀝 Contributing #

Contributions are welcome! Please feel free to submit a Pull Request.

πŸ“„ License #

This project is licensed under the MIT License - see the LICENSE file for details.


πŸ‘¨β€πŸ’» Author #

PathCreator Team

If you find this plugin helpful, please give it a ⭐ on GitHub!

1
likes
140
points
94
downloads
screenshot

Documentation

Documentation
API reference

Publisher

unverified uploader

Weekly Downloads

High-performance Flutter plugin for extracting video thumbnails using native FFmpeg engine. Supports all video formats (MP4, AVI, MKV, FLV, etc.) with CPU-only decoding.

Repository (GitHub)
View/report issues

Topics

#video #thumbnail #ffmpeg #video-processing #media

License

MIT (license)

Dependencies

crypto, flutter, flutter_web_plugins, path, path_provider, uuid

More

Packages that depend on smart_video_thumbnail

Packages that implement smart_video_thumbnail