video_maestro 0.0.1 copy "video_maestro: ^0.0.1" to clipboard
video_maestro: ^0.0.1 copied to clipboard

Video Maestro

example/lib/main.dart

import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:video_maestro/video_maestro.dart';
import 'package:file_picker/file_picker.dart';

final ValueNotifier<ThemeMode> themeModeNotifier = ValueNotifier(ThemeMode.light);

const List<DeviceOrientation> appPreferredOrientations = [
  DeviceOrientation.portraitUp,
  DeviceOrientation.portraitDown,
];

void main() async {
  WidgetsFlutterBinding.ensureInitialized();
  await SystemChrome.setPreferredOrientations(appPreferredOrientations);

  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    return ValueListenableBuilder<ThemeMode>(
      valueListenable: themeModeNotifier,
      builder: (context, currentMode, child) {
        return MaterialApp(
          title: 'Video Maestro Demo',
          themeMode: currentMode,
          theme: ThemeData(
            colorScheme: ColorScheme.fromSeed(
              seedColor: Colors.deepPurple,
              brightness: Brightness.light,
            ),
            elevatedButtonTheme: ElevatedButtonThemeData(
              style: ElevatedButton.styleFrom(
                backgroundColor: Colors.deepPurple,
                foregroundColor: Colors.white,
              ),
            ),
            extensions: const [
              // Set your white theme if needed
              VideoMaestroTheme(
                appPreferredOrientations: appPreferredOrientations,
              ),
            ],
          ),
          darkTheme: ThemeData(
            colorScheme: ColorScheme.fromSeed(
              seedColor: Colors.deepPurple,
              brightness: Brightness.dark,
            ),
            elevatedButtonTheme: ElevatedButtonThemeData(
              style: ElevatedButton.styleFrom(
                backgroundColor: Colors.black,
                foregroundColor: Colors.white,
              ),
            ),
            extensions: const [
              // Set your dark theme if needed
              VideoMaestroTheme(
                iconColor: Colors.white,
                sliderThemeData: SliderThemeData(
                  trackHeight: 4,
                  overlayColor: Colors.transparent,
                  padding: EdgeInsets.zero,
                  thumbShape: FlatThumbShape(thumbRadius: 8),
                  inactiveTrackColor: Colors.white24,
                  thumbColor: Colors.orange,
                  activeTrackColor: Colors.orange,
                ),
                appPreferredOrientations: appPreferredOrientations,
              ),
            ],
          ),
          home: const MaestroExampleScreen(),
        );
      },
    );
  }
}

class MaestroExampleScreen extends StatefulWidget {
  const MaestroExampleScreen({super.key});

  @override
  State<MaestroExampleScreen> createState() => _MaestroExampleScreenState();
}

class _MaestroExampleScreenState extends State<MaestroExampleScreen> {
  MaestroController? _maestroController;
  final String _networkUrl =
      'https://ia801903.us.archive.org/32/items/BigBuckBunny_328/BigBuckBunny_512kb.mp4';
  final String _assetUrl = 'assets/sample.mp4';

  @override
  void dispose() {
    _maestroController?.dispose();
    super.dispose();
  }

  Future<void> _loadVideo(String url) async {
    await _maestroController?.dispose();
    _maestroController = null;

    setState(() {});

    _maestroController = MaestroController(
      url: url,
    );

    await _maestroController!.initialize();

    _maestroController!.play();
    setState(() {});
  }

  Future<void> _pickFileVideo() async {
    FilePickerResult? result = await FilePicker.platform.pickFiles(
      type: FileType.video,
    );

    final path = result?.files.single.path;

    if (path != null) {
      _loadVideo(path);
    }
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('Video Maestro Demo'),
        backgroundColor: Theme.of(context).colorScheme.inversePrimary,
        actions: [
          IconButton(
            icon: Icon(
              Theme.of(context).brightness == Brightness.light
                  ? Icons.dark_mode
                  : Icons.light_mode,
            ),
            onPressed: () {
              themeModeNotifier.value =
                  Theme.of(context).brightness == Brightness.light
                      ? ThemeMode.dark
                      : ThemeMode.light;
            },
          ),
        ],
      ),
      body: SingleChildScrollView(
        child: Padding(
          padding: const EdgeInsets.all(16.0),
          child: Column(
            crossAxisAlignment: CrossAxisAlignment.stretch,
            children: [
              const Text(
                'Select a source to load the video:',
                style: TextStyle(fontSize: 18, fontWeight: FontWeight.bold),
              ),

              const SizedBox(height: 16),

              Wrap(
                spacing: 8.0,
                runSpacing: 8.0,
                alignment: WrapAlignment.center,
                children: [
                  ElevatedButton.icon(
                    onPressed: () => _loadVideo(_networkUrl),
                    icon: const Icon(Icons.cloud),
                    label: const Text('Network Video'),
                  ),
                  ElevatedButton.icon(
                    onPressed: () => _loadVideo(_assetUrl),
                    icon: const Icon(Icons.perm_media),
                    label: const Text('Asset Video'),
                  ),
                  ElevatedButton.icon(
                    onPressed: _pickFileVideo,
                    icon: const Icon(Icons.folder),
                    label: const Text('File Video (Pick)'),
                  ),
                ],
              ),

              const SizedBox(height: 32),

              if (_maestroController != null)
                SizedBox(
                  height: 208,
                  child: VideoMaestro(
                    controller: _maestroController!,
                    config: VideoMaestroConfig(
                        captions: [
                          CaptionData(name: "Arabic", path: "assets/captions_ar.vtt"),
                          CaptionData(name: "English", path: "https://gist.githubusercontent.com/samdutton/ca37f3adaf4e23679957b8083e061177/raw/e19399fbccbc069a2af4266e5120ae6bad62699a/sample.vtt"),
                        ]
                    ),
                  ),
                )
              else
                const SizedBox(
                  height: 250,
                  child: Center(child: Text('No video loaded.')),
                ),
            ],
          ),
        ),
      ),
    );
  }
}