🎬 flutter_cached_video
The Ultimate Video Player with Intelligent Caching for Flutter
A supercharged version of the official video_player plugin with smart video caching built right in. Say goodbye to buffering, data wastage, and poor offline experiences!
⚡ Why Choose flutter_cached_video?
🚀 Blazing Fast Performance
- Videos load instantly on repeat views - no re-downloading
- Powered by ExoPlayer's battle-tested caching on Android
- Seamless fallback to native players on iOS/macOS (AVPlayer)
💾 Smart Cache Management
- 512 MB intelligent cache that auto-manages itself
- Oldest videos automatically removed when cache is full
- Zero configuration needed - it just works!
📱 Perfect for Real-World Apps
- Social media feeds with video content
- Educational apps with course videos
- News apps with video articles
- Entertainment and streaming apps
- Any app where users rewatch content
🎯 Drop-in Replacement
Uses the exact same API as the official video_player - just change the import and enjoy caching!
📦 Installation
Add to your pubspec.yaml:
dependencies:
flutter_cached_video: ^1.1.1
Then run:
flutter pub get
🎨 Quick Start
Before (Standard video_player):
import 'package:video_player/video_player.dart'; // ❌ No caching
final controller = VideoPlayerController.networkUrl(
Uri.parse('https://example.com/video.mp4')
);
After (With caching superpowers):
import 'package:flutter_cached_video/flutter_cached_video.dart'; // ✅ Auto-caching!
final controller = VideoPlayerController.networkUrl(
Uri.parse('https://example.com/video.mp4')
);
// That's it! Videos now cache automatically on Android 🎉
📖 Complete Example
import 'package:flutter/material.dart';
import 'package:flutter_cached_video/flutter_cached_video.dart';
void main() => runApp(const VideoApp());
class VideoApp extends StatefulWidget {
const VideoApp({super.key});
@override
_VideoAppState createState() => _VideoAppState();
}
class _VideoAppState extends State<VideoApp> {
late VideoPlayerController _controller;
@override
void initState() {
super.initState();
_controller = VideoPlayerController.networkUrl(
Uri.parse('https://commondatastorage.googleapis.com/gtv-videos-bucket/sample/BigBuckBunny.mp4')
)..initialize().then((_) {
setState(() {}); // Refresh when video is ready
});
}
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Cached Video Demo',
home: Scaffold(
appBar: AppBar(
title: const Text('🎬 Cached Video Player'),
),
body: Center(
child: _controller.value.isInitialized
? AspectRatio(
aspectRatio: _controller.value.aspectRatio,
child: VideoPlayer(_controller),
)
: const CircularProgressIndicator(),
),
floatingActionButton: FloatingActionButton(
onPressed: () {
setState(() {
_controller.value.isPlaying
? _controller.pause()
: _controller.play();
});
},
child: Icon(
_controller.value.isPlaying ? Icons.pause : Icons.play_arrow,
),
),
),
);
}
@override
void dispose() {
_controller.dispose();
super.dispose();
}
}
🌟 Key Features
| Feature | Description |
|---|---|
| 🎯 Zero Config Caching | Works out of the box - no setup required |
| 💨 Instant Playback | Cached videos start playing immediately |
| 📦 512 MB Cache | Plenty of space for your video content |
| 🔄 Auto Cleanup | Smart LRU cache removes old videos automatically |
| 🌐 Multi-Platform | Android (caching) + iOS/macOS/Web (standard playback) |
| 🔌 Same API | Drop-in replacement for official video_player |
| ⚡ ExoPlayer Powered | Built on Google's robust ExoPlayer (Media3) |
📱 Platform Setup
Android Configuration
1. Internet Permission
Add to android/app/src/main/AndroidManifest.xml:
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
<uses-permission android:name="android.permission.INTERNET"/>
<!-- ... -->
</manifest>
2. Network Security Configuration (Required for Caching)
Since flutter_cached_video uses ExoPlayer's caching mechanism with a local cache proxy, you need to allow cleartext traffic to localhost.
Step 1: Create android/app/src/main/res/xml/network_security_config.xml:
<?xml version="1.0" encoding="utf-8"?>
<network-security-config>
<!-- Allow cleartext traffic to localhost for video caching -->
<domain-config cleartextTrafficPermitted="true">
<domain includeSubdomains="false">localhost</domain>
<domain includeSubdomains="false">127.0.0.1</domain>
</domain-config>
<!-- For production: Use HTTPS for external resources -->
<base-config cleartextTrafficPermitted="false" />
</network-security-config>
Step 2: Reference it in android/app/src/main/AndroidManifest.xml:
<application
android:networkSecurityConfig="@xml/network_security_config"
...>
<!-- ... -->
</application>
💡 Why is this needed? The caching system uses a local proxy server to intercept and cache video data efficiently. This configuration only allows cleartext traffic to localhost (your device), while keeping external connections secure.
iOS
For HTTP (non-HTTPS) videos, configure ios/Runner/Info.plist:
<key>NSAppTransportSecurity</key>
<dict>
<key>NSAllowsArbitraryLoads</key>
<true/>
</dict>
⚠️ Security Note: For production apps, use HTTPS URLs or configure specific domains instead of allowing all arbitrary loads.
Web
- The web platform does not support
dart:io - Avoid using
VideoPlayerController.file()constructor on web - Check package:video_player_web for browser-specific capabilities
🎥 Supported Video Formats
Android (with ExoPlayer Media3 1.5.0)
| Format Type | Supported Formats | Container Support |
|---|---|---|
| Progressive | MP4, M4A, FMP4, WebM, Matroska (MKV), MP3, Ogg, WAV, MPEG-TS, MPEG-PS, FLV, ADTS (AAC) | ✅ Full support |
| Adaptive Streaming | DASH, HLS, SmoothStreaming | ✅ Full support |
| Real-time | RTSP | ✅ Supported |
| Video Codecs | H.264 (AVC), H.265 (HEVC), VP8, VP9, AV1 | ✅ Device dependent |
| Audio Codecs | AAC, MP3, Opus, Vorbis, FLAC, PCM | ✅ Full support |
📌 Note: Codec support depends on Android device capabilities. H.264 and AAC are universally supported.
iOS/macOS (with AVPlayer)
| Format Type | Supported Formats |
|---|---|
| Video Formats | MP4, M4V, MOV, M4A |
| Streaming | HLS (HTTP Live Streaming) |
| Video Codecs | H.264, HEVC (H.265), ProRes |
| Audio Codecs | AAC, MP3, Apple Lossless |
📌 Reference: Apple AVURLAsset Documentation
Web (Browser-dependent)
| Browser | MP4 (H.264) | WebM (VP8/VP9) | Ogg Theora | HLS |
|---|---|---|---|---|
| Chrome | ✅ | ✅ | ❌ | ⚠️ Via MSE |
| Firefox | ✅ | ✅ | ✅ | ⚠️ Via MSE |
| Safari | ✅ | ❌ | ❌ | ✅ Native |
| Edge | ✅ | ✅ | ❌ | ⚠️ Via MSE |
📌 Best Practice: Use MP4 with H.264 codec for maximum compatibility across all platforms.
This combination works seamlessly across Android, iOS, macOS, and Web!
💡 Use Cases
🎓 Education Apps
Students can watch course videos offline after first load - perfect for commutes!
📰 News & Media
Reduce bandwidth costs by caching trending video content automatically.
🎮 Social Media
Users scroll back to see videos instantly - no rebuffering on repeated views.
🏋️ Fitness Apps
Workout videos load instantly for smooth exercise experiences.
🔧 Advanced Configuration
The cache is automatically managed with these defaults:
- Cache Size: 512 MB
- Cache Strategy: LRU (Least Recently Used)
- Location: App cache directory
- Cleanup: Automatic when limit reached
Want custom cache settings? Check out flutter_cached_video_android for advanced configuration options.
🆚 Comparison
| Feature | flutter_cached_video | video_player | cached_video_player |
|---|---|---|---|
| Video Caching | ✅ Built-in | ❌ None | ✅ Manual setup |
| Auto Cache Management | ✅ Yes | ❌ N/A | ⚠️ Basic |
| Same API as video_player | ✅ 100% | ✅ Official | ❌ Different |
| Android Optimization | ✅ ExoPlayer | ✅ ExoPlayer | ⚠️ Varies |
| Maintenance | ✅ Active | ✅ Official | ⚠️ Limited |
| Setup Complexity | 🟢 Zero config | 🟢 Simple | 🟡 Moderate |
🐛 Troubleshooting
Videos not caching?
- Ensure you're on Android (iOS/Web use native players without caching)
- Check internet permissions in AndroidManifest.xml
- Verify the video URL is accessible
App size increased?
- ExoPlayer adds ~2-3 MB to Android APK
- Cache is stored in app cache directory (not in APK)
🤝 Contributing
Contributions are welcome! Please feel free to submit a Pull Request.
- Fork the repository
- Create your feature branch (
git checkout -b feature/AmazingFeature) - Commit your changes (
git commit -m 'Add some AmazingFeature') - Push to the branch (
git push origin feature/AmazingFeature) - Open a Pull Request
📄 License
This package is based on the Flutter video_player package, licensed under the BSD 3-Clause License.
Original Copyright: Flutter Authors
Modifications: © 2025 Raghav Garg (MIT License)
See LICENSE for details.
🙏 Credits
- Built on top of video_player by the Flutter team
- Android caching powered by ExoPlayer (Media3)
- Maintained with ❤️ by Raghav Garg
📞 Support
- 📧 Issues: GitHub Issues
- 💬 Discussions: GitHub Discussions
- ⭐ Star us on GitHub
Made with ❤️ for the Flutter community