brighton_video_player 1.0.2
brighton_video_player: ^1.0.2 copied to clipboard
Flutter video player widget with caching support, pre-cache helpers, and customizable UI delegates.
import 'package:flutter/material.dart';
import 'package:brighton_video_player/brighton_video_player.dart';
Future<void> main() async {
WidgetsFlutterBinding.ensureInitialized();
await BrightonVideoBootstrap.ensureInitialized();
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Brighton Video Demo',
theme: ThemeData.dark(),
home: const DemoPage(),
);
}
}
class DemoPage extends StatefulWidget {
const DemoPage({super.key});
@override
State<DemoPage> createState() => _DemoPageState();
}
class _DemoPageState extends State<DemoPage> {
static const _videoUrl =
'https://commondatastorage.googleapis.com/gtv-videos-bucket/sample/BigBuckBunny.mp4';
static const _posterUrl =
'https://commondatastorage.googleapis.com/gtv-videos-bucket/sample/images/BigBuckBunny.jpg';
late final BrightonVideoController controller;
bool _busy = false;
@override
void initState() {
super.initState();
controller = BrightonVideoController(
sourceUrl: _videoUrl,
autoPlay: true,
enableBackgroundCaching: true,
loop: false,
playbackStrategy: BrightonPlaybackStrategy.auto,
);
}
@override
void dispose() {
controller.dispose();
super.dispose();
}
Future<void> _runCacheAction(Future<void> Function() action) async {
setState(() => _busy = true);
try {
await action();
await controller.refreshCacheState();
} finally {
if (mounted) {
setState(() => _busy = false);
}
}
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('Brighton Video Player'),
),
body: AnimatedBuilder(
animation: controller,
builder: (context, _) {
return ListView(
padding: const EdgeInsets.all(16),
children: [
AspectRatio(
aspectRatio: 16 / 9,
child: ClipRRect(
borderRadius: BorderRadius.circular(16),
child: BrightonVideoPlayer(
controller: controller,
posterUrl: _posterUrl,
fit: BoxFit.cover,
autoRotate: true,
showDebugInfo: true,
),
),
),
const SizedBox(height: 16),
Wrap(
spacing: 12,
runSpacing: 12,
children: [
FilledButton(
onPressed: _busy
? null
: () => _runCacheAction(
() => controller.preCache(downloadNow: true),
),
child: const Text('Pre-cache'),
),
FilledButton.tonal(
onPressed: _busy
? null
: () => _runCacheAction(
controller.downloadInBackground,
),
child: const Text('Full download'),
),
OutlinedButton(
onPressed: _busy
? null
: () => _runCacheAction(controller.removeCache),
child: const Text('Remove cache'),
),
],
),
const SizedBox(height: 16),
Card(
child: Padding(
padding: const EdgeInsets.all(16),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
'Playback',
style: Theme.of(context).textTheme.titleMedium,
),
const SizedBox(height: 8),
Text('Initialized: ${controller.isInitialized}'),
Text('Playing: ${controller.isPlaying}'),
Text('Fullscreen: ${controller.isFullscreen}'),
Text(
'Route: ${controller.isUsingLocalProxy ? "proxy" : "direct"}',
),
Text('Cache state: ${controller.cacheStateText}'),
if (controller.cacheStateError != null)
Text('Cache error: ${controller.cacheStateError}'),
if (controller.hasError)
Text('Error: ${controller.technicalErrorMessage}'),
],
),
),
),
],
);
},
),
);
}
}