tss_video_glimpse 0.1.3
tss_video_glimpse: ^0.1.3 copied to clipboard
Cross-platform Flutter package for video previews from network, assets, and Firebase Storage with smart caching.
TSS Video Glimpse 🎬 #
A powerful, elegant, and highly efficient cross-platform Flutter package for generating stunning video previews and thumbnails from multiple sources. Built with TSS (Thumbnail Snapshot Service) technology, this package provides seamless integration with network URLs, local assets, and Firebase Storage paths.
🌟 Why TSS Video Glimpse? #
TSS Video Glimpse stands out from other video preview packages with its:
- 🚀 Lightning-fast performance with intelligent caching
- 🎨 Beautiful, customizable UI components
- 🌐 True cross-platform support (Android, iOS, Web, Linux, macOS, Windows)
- 🔥 Firebase Storage integration out of the box
- 📦 Smart memory management to prevent leaks
- 🎯 Simple, intuitive API that just works
- 🛡️ Production-ready with comprehensive error handling
✨ Features #
📹 Multi-Source Support #
- Network URLs (HTTP/HTTPS) - Stream from any web source
- Local Assets - Bundle videos with your app
- Firebase Storage - Direct integration with Firebase Storage paths
- YouTube - Play YouTube videos directly via URL
🎯 Cross-Platform Excellence #
- ✅ Android (API 21+)
- ✅ iOS (iOS 12+)
- ✅ Web (All modern browsers)
- ✅ Linux
- ✅ macOS
- ✅ Windows
🚀 Performance Features #
- Smart Caching - Automatic caching for network videos
- Memory Optimization - Efficient memory management
- Lazy Loading - Load previews only when needed
- Configurable Cache Duration - Control cache lifetime
🎨 Customization Options #
- Custom placeholder widgets
- Custom error handling widgets
- Loading indicators
- Aspect ratio control
- Quality settings (Low, Medium, High)
- BoxFit options for perfect layouts
📦 Installation #
Add this to your package's pubspec.yaml file:
dependencies:
tss_video_glimpse: ^0.1.3
Then run:
flutter pub get
🚀 Quick Start #
Basic Usage #
The simplest way to display a video preview:
import 'package:tss_video_glimpse/tss_video_glimpse.dart';
// Network URL
TssVideoGlimpse(
videoUrl: 'https://example.com/video.mp4',
width: 200,
height: 150,
)
Asset Video #
Display a preview from a local asset:
TssVideoGlimpse.asset(
assetPath: 'assets/videos/sample.mp4',
width: 200,
height: 150,
)
Firebase Storage #
Load video directly from Firebase Storage:
TssVideoGlimpse.firebase(
firebasePath: 'videos/sample.mp4',
width: 200,
height: 150,
)
YouTube Video #
Display a YouTube video preview and player:
TssVideoGlimpse(
youtubeUrl: 'https://www.youtube.com/watch?v=dQw4w9WgXcQ',
width: 200,
height: 150,
)
📚 Detailed Usage Examples #
Example 1: Network Video with Custom Styling #
TssVideoGlimpse(
videoUrl: 'https://example.com/video.mp4',
width: 300,
height: 200,
fit: BoxFit.cover,
quality: TssVideoQuality.high,
placeholder: Container(
decoration: BoxDecoration(
gradient: LinearGradient(
colors: [Colors.blue.shade300, Colors.purple.shade300],
),
borderRadius: BorderRadius.circular(12),
),
child: const Center(
child: CircularProgressIndicator(color: Colors.white),
),
),
errorWidget: Container(
decoration: BoxDecoration(
color: Colors.red.shade50,
borderRadius: BorderRadius.circular(12),
),
child: const Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Icon(Icons.error_outline, size: 48, color: Colors.red),
SizedBox(height: 8),
Text('Failed to load video', style: TextStyle(color: Colors.red)),
],
),
),
onError: (error) {
print('Video loading error: $error');
// Handle error (e.g., show snackbar, log to analytics)
},
)
Example 2: Grid of Video Previews #
Perfect for video galleries or content browsing:
GridView.builder(
gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 2,
crossAxisSpacing: 12,
mainAxisSpacing: 12,
childAspectRatio: 16 / 9,
),
itemCount: videoUrls.length,
itemBuilder: (context, index) {
return ClipRRect(
borderRadius: BorderRadius.circular(12),
child: TssVideoGlimpse(
videoUrl: videoUrls[index],
width: double.infinity,
height: double.infinity,
fit: BoxFit.cover,
quality: TssVideoQuality.medium,
),
);
},
)
Example 3: Using the Controller for Advanced Control #
For scenarios where you need more control over the video preview:
class VideoPreviewPage extends StatefulWidget {
@override
_VideoPreviewPageState createState() => _VideoPreviewPageState();
}
class _VideoPreviewPageState extends State<VideoPreviewPage> {
late TssVideoGlimpseController _controller;
@override
void initState() {
super.initState();
_controller = TssVideoGlimpseController(
videoUrl: 'https://example.com/video.mp4',
quality: TssVideoQuality.high,
);
_initializeController();
}
Future<void> _initializeController() async {
final success = await _controller.initialize();
if (!success) {
// Handle initialization failure
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(content: Text('Failed to load video: ${_controller.error}')),
);
}
}
@override
void dispose() {
_controller.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: const Text('Video Preview')),
body: Column(
children: [
TssVideoGlimpse.controller(
controller: _controller,
width: double.infinity,
height: 300,
),
const SizedBox(height: 16),
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
ElevatedButton.icon(
onPressed: () => _controller.play(),
icon: const Icon(Icons.play_arrow),
label: const Text('Play'),
),
const SizedBox(width: 16),
ElevatedButton.icon(
onPressed: () => _controller.pause(),
icon: const Icon(Icons.pause),
label: const Text('Pause'),
),
],
),
],
),
);
}
}
Example 4: Firebase Storage with Authentication #
import 'package:firebase_core/firebase_core.dart';
import 'package:tss_video_glimpse/tss_video_glimpse.dart';
class FirebaseVideoGallery extends StatelessWidget {
final List<String> firebasePaths = [
'videos/intro.mp4',
'videos/tutorial.mp4',
'videos/demo.mp4',
];
@override
Widget build(BuildContext context) {
return ListView.builder(
padding: const EdgeInsets.all(16),
itemCount: firebasePaths.length,
itemBuilder: (context, index) {
return Card(
margin: const EdgeInsets.only(bottom: 16),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
TssVideoGlimpse.firebase(
firebasePath: firebasePaths[index],
width: double.infinity,
height: 200,
fit: BoxFit.cover,
quality: TssVideoQuality.high,
),
Padding(
padding: const EdgeInsets.all(12),
child: Text(
'Video ${index + 1}',
style: const TextStyle(
fontSize: 18,
fontWeight: FontWeight.bold,
),
),
),
],
),
);
},
);
}
}
Example 5: YouTube Video with Preview Only #
Show only the thumbnail without the play button overlay:
TssVideoGlimpse(
youtubeUrl: 'https://www.youtube.com/watch?v=dQw4w9WgXcQ',
width: 300,
height: 200,
showPreviewOnly: true, // Only shows thumbnail
fit: BoxFit.cover,
)
Example 6: Responsive Video Preview #
Adapts to different screen sizes:
class ResponsiveVideoPreview extends StatelessWidget {
final String videoUrl;
const ResponsiveVideoPreview({required this.videoUrl});
@override
Widget build(BuildContext context) {
return LayoutBuilder(
builder: (context, constraints) {
final width = constraints.maxWidth;
final height = width * 9 / 16; // 16:9 aspect ratio
return TssVideoGlimpse(
videoUrl: videoUrl,
width: width,
height: height,
fit: BoxFit.cover,
quality: width > 600
? TssVideoQuality.high
: TssVideoQuality.medium,
);
},
);
}
}
⚙️ Configuration Options #
| Parameter | Type | Default | Description |
|---|---|---|---|
videoUrl |
String? |
null |
Network URL of the video |
assetPath |
String? |
null |
Local asset path |
firebasePath |
String? |
null |
Firebase Storage path |
youtubeUrl |
String? |
null |
YouTube video URL |
width |
double |
200 |
Preview width in pixels |
height |
double |
150 |
Preview height in pixels |
fit |
BoxFit |
BoxFit.cover |
How the preview fits in the box |
placeholder |
Widget? |
null |
Widget shown while loading |
errorWidget |
Widget? |
null |
Widget shown on error |
onError |
Function(dynamic)? |
null |
Error callback function |
cacheMaxAge |
Duration |
7 days |
Maximum cache duration |
quality |
TssVideoQuality |
medium |
Preview quality level |
Quality Levels #
TssVideoQuality.low- Faster loading, lower memory usage (recommended for lists)TssVideoQuality.medium- Balanced performance and quality (default)TssVideoQuality.high- Best quality, higher memory usage (recommended for detail views)
🔥 Firebase Setup #
To use Firebase Storage paths, initialize Firebase in your app:
1. Add Firebase to your project #
Follow the FlutterFire documentation to add Firebase to your Flutter app.
2. Initialize Firebase #
import 'package:firebase_core/firebase_core.dart';
import 'firebase_options.dart';
void main() async {
WidgetsFlutterBinding.ensureInitialized();
await Firebase.initializeApp(
options: DefaultFirebaseOptions.currentPlatform,
);
runApp(MyApp());
}
3. Use Firebase Storage paths #
TssVideoGlimpse.firebase(
firebasePath: 'videos/my-video.mp4',
width: 300,
height: 200,
)
🛠️ Platform-Specific Setup #
Android #
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"/>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
<application
android:usesCleartextTraffic="true">
<!-- Your app configuration -->
</application>
</manifest>
iOS #
Add to ios/Runner/Info.plist:
<key>NSAppTransportSecurity</key>
<dict>
<key>NSAllowsArbitraryLoads</key>
<true/>
</dict>
<key>io.flutter.embedded_views_preview</key>
<true/>
Web #
No additional setup required! Works out of the box.
Desktop (Linux, macOS, Windows) #
No additional setup required! Works out of the box.
🎯 Best Practices #
1. Use Appropriate Quality Settings #
// For lists and grids
TssVideoGlimpse(
videoUrl: url,
quality: TssVideoQuality.low, // Faster, less memory
)
// For detail views
TssVideoGlimpse(
videoUrl: url,
quality: TssVideoQuality.high, // Better quality
)
2. Handle Errors Gracefully #
TssVideoGlimpse(
videoUrl: url,
onError: (error) {
// Log to analytics
FirebaseAnalytics.instance.logEvent(
name: 'video_load_error',
parameters: {'error': error.toString()},
);
// Show user-friendly message
ScaffoldMessenger.of(context).showSnackBar(
const SnackBar(content: Text('Unable to load video preview')),
);
},
)
3. Dispose Controllers Properly #
@override
void dispose() {
_controller.dispose(); // Always dispose controllers
super.dispose();
}
4. Use Const Constructors When Possible #
const TssVideoGlimpse(
videoUrl: 'https://example.com/video.mp4',
width: 200,
height: 150,
)
🔧 Advanced Features #
Cache Management #
import 'package:tss_video_glimpse/tss_video_glimpse.dart';
// Clear all cached videos
await TssVideoLoaderService().clearCache();
// Remove specific video from cache
await TssVideoLoaderService().removeFromCache(videoUrl);
Custom Cache Duration #
TssVideoGlimpse(
videoUrl: url,
cacheMaxAge: const Duration(days: 30), // Cache for 30 days
)
📱 Complete Example App #
Check out the example directory for a complete sample app demonstrating:
- Network video previews
- Asset video previews
- Firebase Storage integration
- Grid layouts
- Custom styling
- Error handling
- Controller usage
- Responsive design
🐛 Troubleshooting #
Videos not loading on Android #
Make sure you have internet permission in AndroidManifest.xml:
<uses-permission android:name="android.permission.INTERNET"/>
Videos not loading on iOS #
Check that NSAppTransportSecurity is configured in Info.plist.
Firebase videos not loading #
Ensure Firebase is properly initialized and you have the correct storage rules.
🤝 Contributing #
Contributions are welcome! Please read our contributing guidelines before submitting PRs.
How to Contribute #
- Fork the repository
- Create your feature branch (
git checkout -b feature/amazing-feature) - Commit your changes (
git commit -m 'Add some amazing feature') - Push to the branch (
git push origin feature/amazing-feature) - Open a Pull Request
📄 License #
This project is licensed under the MIT License - see the LICENSE file for details.
💖 Support #
If you find this package helpful, please:
- ⭐ Star the repository on GitHub
- 👍 Like it on pub.dev
- 🐛 Report issues on our issue tracker
- 💬 Share your feedback and suggestions
🙏 Acknowledgments #
Built with ❤️ using:
- omni_video_player - Powerful video player
- firebase_storage - Firebase integration
- flutter_cache_manager - Smart caching
Made with 💙 by the TSS Team