Flutter Video Cache

pub package likes pub points

A Flutter plugin that works alongside the video_player package to enable video caching and offline playback across platforms. This package provides an easy way to download videos for offline viewing, track download progress, and access cached videos.

Flutter Video Cache Demo

Features

  • 📱 Video caching across platforms (Android implementation complete, iOS coming soon)
  • 🚀 Automatic playback from cache when available
  • 📊 Real-time download progress tracking
  • 🔄 Background downloads that continue when app is in background
  • 📦 Support for various video formats including HLS and DASH
  • 🎮 Ready-to-use UI components for download controls
  • 🎨 Highly customizable UI elements

Getting Started

Installation

dependencies:
  flutter_video_cache: ^0.1.0
  video_player: ^2.7.0

Basic Usage

Playing videos with caching

import 'package:flutter/material.dart';
import 'package:video_player/video_player.dart';
import 'package:flutter_video_cache/flutter_video_cache.dart';

// Create a controller that will play from cache if available
final controller = await VideoCacheController.networkWithCaching(
  'https://example.com/video.mp4'
);

// Use the controller as you would with any VideoPlayerController
await controller.initialize();
await controller.play();

Downloading videos for offline playback

import 'package:flutter_video_cache/flutter_video_cache.dart';

final videoCache = VideoCache();

// Start downloading a video
await videoCache.startDownload('https://example.com/video.mp4');

// Check download progress
final progress = await videoCache.getDownloadProgress('https://example.com/video.mp4');
print('Progress: ${progress * 100}%');

// Listen to download progress updates
videoCache.getDownloadProgressStream('https://example.com/video.mp4')
  .listen((progress) {
    print('Download progress: ${progress * 100}%');
  });

// Cancel a download
await videoCache.cancelDownload('https://example.com/video.mp4');

// Remove a downloaded video
await videoCache.removeDownload('https://example.com/video.mp4');

// Check if a video is cached
final isCached = await videoCache.isVideoCached('https://example.com/video.mp4');

// Get the local file path for a cached video
final cachedPath = await videoCache.getCachedVideoPath('https://example.com/video.mp4');

Using the CacheControlButton Widget

Video Cache includes a ready-to-use CacheControlButton widget that provides download, cancel, delete, and play functionality.

Default Usage

CacheControlButton(
  videoUrl: 'https://example.com/video.mp4',
  showPlayButton: true,
  onPlayPressed: () {
    // Handle play button press
  },
  onDownloadStarted: () {
    // Handle download started
  },
  onDownloadCompleted: () {
    // Handle download completed
  },
)

Customized Button

CacheControlButton(
  videoUrl: 'https://example.com/video.mp4',
  showPlayButton: true,
  size: 42,
  color: Colors.blue,
  backgroundColor: Colors.grey[200],
  
  // Custom widgets
  downloadWidget: Icon(Icons.cloud_download, color: Colors.indigo),
  cancelWidget: Icon(Icons.cancel_rounded, color: Colors.red),
  deleteWidget: Icon(Icons.delete_forever, color: Colors.orange),
  playWidget: Icon(Icons.play_circle, color: Colors.green),
  
  // Labels
  downloadLabel: "Save",
  cancelLabel: "Stop",
  deleteLabel: "Remove",
  playLabel: "Play",
  
  // Label position and style
  labelPosition: LabelPosition.below,
  labelStyle: TextStyle(fontWeight: FontWeight.bold, fontSize: 10),
  labelSpacing: 4,
  
  // Callbacks
  onPlayPressed: _playVideo,
  onDownloadStarted: () {
    // Handle download started
  },
  onDownloadCompleted: () {
    // Handle download completed
  },
)

Troubleshooting

Android

  • Ensure that compileSdkVersion is at least 33 in your app's build.gradle
  • Add internet permissions to your AndroidManifest.xml
  • If using HLS or DASH, make sure proguard isn't stripping Media3 libraries

IOS

  • Ensure that platform:ios is at least 15.0 in your app's Info.plist

Contribution

Contributions are welcome! If you find a bug or want a feature, please:

  1. Check existing issues and pull requests
  2. Create an issue to discuss the problem
  3. Submit a PR with your solution

License

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