flutter_video_caching 0.3.5 copy "flutter_video_caching: ^0.3.5" to clipboard
flutter_video_caching: ^0.3.5 copied to clipboard

Video caching, can use with video_player package. It supports formats like m3u8 and mp4, play and cache videos simultaneously, precache the video before playing.

flutter_video_caching #

Pub Version Pub Points GitHub

flutter_video_caching is a powerful Flutter plugin for efficient video caching. It supports integration with the video_player package and works with popular formats like m3u8 (HLS) and MP4. The plugin enables simultaneous playback and caching, as well as pre-caching for smoother user experiences.

Features #

  • Multi-format support: Works with m3u8 (HLS), MP4, and other common video formats.
  • Memory & file cache: LRU-based memory cache combined with local file cache to minimize network requests.
  • Pre-caching: Download video segments in advance to ensure seamless playback.
  • Background downloading: Uses Isolates for multi-task parallel downloads without blocking the UI.
  • Priority scheduling: Supports setting download task priorities for optimized resource allocation.
  • Custom headers & cache file names: Allows custom HTTP headers and cache file naming.
  • Download resume: Supports automatic resumption of interrupted downloads.

Support plugin #

Installation #

Add the dependency in your pubspec.yaml:

dependencies:
  flutter_video_caching: ^newest_version

Then run:

flutter pub get

Quick Start #

1. Initialize the video proxy #

import 'package:flutter_video_caching/flutter_video_caching.dart';

void main() {
  WidgetsFlutterBinding.ensureInitialized();
  VideoProxy.init();
  runApp(const HomeApp());
}

2. Use with video_player #

playControl = VideoPlayerController.networkUrl(url.toLocalUri());

3. Pre-cache a video #

VideoCaching.precache(url);

4. Preload in PageView scenarios #

PageView.builder(
  controller: pageController,
  itemCount: urls.length,
  itemBuilder: (context, index) {
    return VideoPlayerWidget(url: urls[index]);
  },
  onPageChanged: (index) {
    if (index + 1 < urls.length) {
      VideoCaching.precache(urls[index + 1], downloadNow: false);
    }
  },
);

5. Fallback to original URL if proxy fails #

Future initPlayControl(Uri uri) async {
  playControl = VideoPlayerController.networkUrl(uri.toLocalUri())..setLooping(true);
  playControl.addListener(playListener);
}

void playListener() {
  if (playControl.value.hasError) {
    if (playControl.value.errorDescription?.contains("Source error") ?? false) {
      initPlayControl(uri);
    }
  }
}

6. Delete cache #

// Remove cache for a single file or the entire directory
LruCacheSingleton().removeCacheByUrl(String url, {bool singleFile = false});

7. Custom request headers & cache file names #

// Custom header for playback
_controller = VideoPlayerController.networkUrl(uri, httpHeaders: {'Token': 'xxxxxxx'});

// Custom header for pre-caching
VideoCaching.precache(url, headers: {'Token': 'xxxxxxx'});

// Custom cache file name using CUSTOM-CACHE-ID
_controller = VideoPlayerController.networkUrl(uri, httpHeaders: {'CUSTOM-CACHE-ID': 'xxxxxxx'});
VideoCaching.precache(url, headers: {'CUSTOM-CACHE-ID': 'xxxxxxx'});

8. Custom URL matching #

class UrlMatcherDefault extends UrlMatcher {
  @override
  bool matchM3u8(Uri uri) => uri.path.toLowerCase().endsWith('.m3u8');

  @override
  bool matchM3u8Key(Uri uri) => uri.path.toLowerCase().endsWith('.key');

  @override
  bool matchM3u8Segment(Uri uri) => uri.path.toLowerCase().endsWith('.ts');

  @override
  bool matchMp4(Uri uri) => uri.path.toLowerCase().endsWith('.mp4');

  @override
  Uri matchCacheKey(Uri uri) {
    final params = Map<String, String>.from(uri.queryParameters)
      ..removeWhere((key, _) => key != 'startRange' && key != 'endRange');
    return uri.replace(queryParameters: params.isEmpty ? null : params);
  }
}
  • Use UrlMatcher to distinguish video types.
  • Caching logic:
    • m3u8: Each segment is cached as a separate file.
    • mp4/others: The file is split into 2MB segments for caching.

Api #

1.VideoProxy.init: #

  /// Initializes the video proxy server and related components.
  ///
  /// [ip]: Optional IP address for the proxy server to bind.<br>
  /// [port]: Optional port number for the proxy server to listen on.<br>
  /// [maxMemoryCacheSize]: Maximum memory cache size in MB (default: 100).<br>
  /// [maxStorageCacheSize]: Maximum storage cache size in MB (default: 1024).<br>
  /// [logPrint]: Enables or disables logging output (default: false).<br>
  /// [segmentSize]: Size of each video segment in MB (default: 2).<br>
  /// [maxConcurrentDownloads]: Maximum number of concurrent downloads (default: 8).<br>
  /// [urlMatcher]: Optional custom URL matcher for video URL filtering.<br>
  static Future<void> init({
    String? ip,
    int? port,
    int maxMemoryCacheSize = 100,
    int maxStorageCacheSize = 1024,
    bool logPrint = false,
    int segmentSize = 2,
    int maxConcurrentDownloads = 8,
    UrlMatcher? urlMatcher,
  })

2.VideoCaching.precache: #

  /// Pre-caches the video at the specified [url].
  ///
  /// [url]: The video URL to be pre-cached.
  /// [headers]: Optional HTTP headers for the request.
  /// [cacheSegments]: Number of segments to cache (default: 2).
  /// [downloadNow]: If true, downloads segments immediately; if false, pushes to the queue (default: true).
  /// [progressListen]: If true, returns a [StreamController] with progress updates (default: false).
  ///
  /// Returns a [StreamController] emitting progress/status updates, or `null` if not listening.
  static Future<StreamController<Map>?> precache(
    String url, {
    Map<String, Object>? headers,
    int cacheSegments = 2,
    bool downloadNow = true,
    bool progressListen = false,
  })

FAQ #

1. How to set the maximum cache limit? #

Set maxMemoryCacheSize and maxStorageCacheSize in VideoProxy.init.

2. How to track download progress? #

VideoProxy.downloadManager.stream.listen((Map map) {
});

For .m3u8:

{
  'progress': 0.0,                // Download progress (0.0 ~ 1.0)
  'segment_url': url,             // Current segment URL being downloaded
  'parent_url': url,              // Main m3u8 playlist URL
  'file_name': '',                // Name of the segment file
  'hls_key': '',                  // The HLS key (generated from the URI) for the download, used to generate the cache directory,
                                  // so that the segments of the same video can be cached in the same directory.
  'total_segments': 0,            // Total number of segments
  'current_segment_index': 0,     // Index of the current segment being downloaded
}

For .mp4:

{
  'progress': 0,                  // Download progress (0 ~ 100)
  'url': url,                     // MP4 file URL
  'startRange': 0,                // Start byte of the current download range
  'endRange': 0,                  // End byte of the current download range
}

3. Does the library support download resume? #

Yes. Downloaded segments are loaded from local cache, and unfinished segments will resume downloading when playback restarts.

Contributing #

Contributions are welcome! Please submit issues and pull requests.

License #

This project is licensed under the MIT License.


For more detailed API documentation, please refer to the source code here.

31
likes
0
points
1.16k
downloads

Publisher

unverified uploader

Weekly Downloads

Video caching, can use with video_player package. It supports formats like m3u8 and mp4, play and cache videos simultaneously, precache the video before playing.

Repository (GitHub)
View/report issues

License

unknown (license)

Dependencies

crypto, flutter, flutter_hls_parser, http, logger, path, path_provider, synchronized

More

Packages that depend on flutter_video_caching