universal_video_controls

Overview

The universal_video_controls package provides a comprehensive solution for video controls that can be universally applied to various video players. This package is a port and generalization of the media_kit controls, designed to create an abstraction that allows these controls to work with any video player backend, provided that the backend's interface is compatible with the AbstractPlayer class.

Images

Desktop Mobile
Desktop with Controls Mobile with Controls

Examples

Examples can be found at:

Getting Started

This section will guide you through the steps to get started with the universal_video_controls package.

Installation

Add the following dependencies to your pubspec.yaml file:

dependencies:
  universal_video_controls: ^1.0.10
  universal_video_controls_video_player: ^1.0.1
  video_player: ^2.2.5

Then run flutter pub get to install the packages.

Usage

To use the universal_video_controls package, you need to integrate it with a video player backend that implements the AbstractPlayer interface. Here is a minimal example demonstrating how to set up and use the universal_video_controls with the video_player package.

Example: Single Player Single Video

import 'package:flutter/material.dart';
import 'package:universal_video_controls/universal_video_controls.dart';
import 'package:universal_video_controls_video_player/universal_video_controls_video_player.dart';
import 'package:video_player/video_player.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: SinglePlayerSingleVideoScreen(),
    );
  }
}

class SinglePlayerSingleVideoScreen extends StatefulWidget {
  @override
  State<SinglePlayerSingleVideoScreen> createState() => _SinglePlayerSingleVideoScreenState();
}

class _SinglePlayerSingleVideoScreenState extends State<SinglePlayerSingleVideoScreen> {
  late VideoPlayerController _controller;
  bool _isInitialized = false;

  @override
  void initState() {
    super.initState();
    _initializeVideoPlayer('https://www.example.com/video.mp4');
  }

  void _initializeVideoPlayer(String source) async {
    _controller = VideoPlayerController.network(source);
    await _controller.initialize();
    setState(() {
      _isInitialized = true;
    });
    _controller.play();
    _controller.addListener(() {
      if (_controller.value.hasError) {
        debugPrint(_controller.value.errorDescription);
      }
    });
  }

  @override
  void dispose() {
    _controller.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('Video Player'),
      ),
      body: Center(
        child: _isInitialized
            ? AspectRatio(
                aspectRatio: _controller.value.aspectRatio,
                child: VideoControls(
                  player: VideoPlayerControlsWrapper(_controller),
                ),
              )
            : const CircularProgressIndicator(),
      ),
    );
  }
}

Select existing video controls

Modify the controls argument. For advanced theming of existing video controls, see theming & modifying video controls section.

Scaffold(
  body: VideoControls(
    controller: controller,
    // Select [MaterialVideoControls].
    controls: MaterialVideoControls,
  ),
);
Scaffold(
  body: VideoControls(
    controller: controller,
    // Select [CupertinoVideoControls].
    controls: CupertinoVideoControls,
  ),
);

Build custom video controls

Pass custom builder Widget Function(BuildContext, VideoController) as controls argument.

Scaffold(
  body: VideoControls(
    controller: controller,
    // Provide custom builder for controls.
    controls: (state) {
      return Center(
        child: IconButton(
          onPressed: () {
            state.widget.controller.player.playOrPause();
          },
          icon: StreamBuilder(
            stream: state.widget.controller.player.stream.playing,
            builder: (context, playing) => Icon(
              playing.data == true ? Icons.pause : Icons.play_arrow,
            ),
          ),
          // It's not necessary to use [StreamBuilder] or to use [Player] & [VideoController] from [state].
          // [StreamSubscription]s can be made inside [initState] of this widget.
        ),
      );
    },
  ),
);

Use & modify video controls

AdaptiveVideoControls
MaterialVideoControls
  • Material Design video controls.
  • Theming:
    • Use MaterialVideoControlsTheme widget.
    • VideoControls widget(s) in the child tree will follow the specified theme:
// Wrap [VideoControls] widget with [MaterialVideoControlsTheme].
MaterialVideoControlsTheme(
  normal: MaterialVideoControlsThemeData(
    // Modify theme options:
    buttonBarButtonSize: 24.0,
    buttonBarButtonColor: Colors.white,
    // Modify top button bar:
    topButtonBar: [
      const Spacer(),
      MaterialDesktopCustomButton(
        onPressed: () {
          debugPrint('Custom "Settings" button pressed.');
        },
        icon: const Icon(Icons.settings),
      ),
    ],
  ),
  fullscreen: const MaterialVideoControlsThemeData(
    // Modify theme options:
    displaySeekBar: false,
  ),
  child: Scaffold(
    body: VideoControls(
      controller: controller,
    ),
  ),
);
  • Related widgets (may be used in primaryButtonBar, topButtonBar & bottomButtonBar):
    • MaterialPlayOrPauseButton
    • MaterialSkipNextButton
    • MaterialSkipPreviousButton
    • MaterialFullscreenButton
    • MaterialCustomButton
    • MaterialPositionIndicator
MaterialDesktopVideoControls
  • Material Design video controls for desktop.
  • Theming:
    • Use MaterialDesktopVideoControlsTheme widget.
    • VideoControls widget(s) in the child tree will follow the specified theme:
// Wrap [VideoControls] widget with [MaterialDesktopVideoControlsTheme].
MaterialDesktopVideoControlsTheme(
  normal: MaterialDesktopVideoControlsThemeData(
    // Modify theme options:
    seekBarThumbColor: Colors.blue,
    seekBarPositionColor: Colors.blue,
    toggleFullscreenOnDoublePress: false,
    // Modify top button bar:
    topButtonBar: [
      const Spacer(),
      MaterialDesktopCustomButton(
        onPressed: () {
          debugPrint('Custom "Settings" button pressed.');
        },
        icon: const Icon(Icons.settings),
      ),
    ],
    // Modify bottom button bar:
    bottomButtonBar: const [
      Spacer(),
      MaterialDesktopPlayOrPauseButton(),
      Spacer(),
    ],
  ),
  fullscreen: const MaterialDesktopVideoControlsThemeData(),
  child: Scaffold(
    body: VideoControls(
      controller: controller,
    ),
  ),
);
  • Related widgets (may be used in primaryButtonBar, topButtonBar & bottomButtonBar):
    • MaterialDesktopPlayOrPauseButton
    • MaterialDesktopFullscreenButton
    • MaterialDesktopCustomButton
    • MaterialDesktopVolumeButton
    • MaterialDesktopPositionIndicator
  • Keyboard shortcuts may be modified using keyboardShortcuts argument. Default ones are listed below:
Shortcut Action
Media Play Button Play
Media Pause Button Pause
Media Play/Pause Button Play/Pause
Space Play/Pause
J Seek 10s Behind
I Seek 10s Ahead
Arrow Left Seek 5s Behind
Arrow Right Seek 5s Ahead
Arrow Up Increase Volume 5%
Arrow Down Decrease Volume 5%
F Enter/Exit Fullscreen
Escape Exit Fullscreen
CupertinoVideoControls
  • iOS-style video controls.
  • Theming:
    • Use CupertinoVideoControlsTheme widget.
    • VideoControls widget(s) in the child tree will follow the specified theme:
// Wrap [VideoControls] widget with [CupertinoVideoControlsTheme].
CupertinoVideoControlsTheme(
  normal: const CupertinoVideoControlsThemeData(
    // W.I.P.
  ),
  fullscreen: const CupertinoVideoControlsThemeData(
    // W.I.P.
  ),
  child: Scaffold(
    body: VideoControls(
      controller: controller,
    ),
  ),
);
NoVideoControls
  • Disable video controls i.e. only render video output.
  • Theming:
    • No theming applicable.

Contributing

We welcome contributions to the universal_video_controls project! If you have ideas, suggestions, or improvements, please feel free to submit a pull request or open an issue.

License

This project is licensed under the MIT License. See the LICENSE file for more details.

Thank you for using universal_video_controls!

Libraries

universal_players/abstract
universal_video_controls
This file is a part of media_kit (https://github.com/media-kit/media-kit).
universal_video_controls/src/controls/adaptive
This file is a part of media_kit (https://github.com/media-kit/media-kit).
universal_video_controls/src/controls/cupertino
This file is a part of media_kit (https://github.com/media-kit/media-kit).
universal_video_controls/src/controls/extensions/duration
This file is a part of media_kit (https://github.com/media-kit/media-kit).
universal_video_controls/src/controls/material
This file is a part of media_kit (https://github.com/media-kit/media-kit).
universal_video_controls/src/controls/material_desktop
This file is a part of media_kit (https://github.com/media-kit/media-kit).
universal_video_controls/src/controls/methods/full_screen_utils/full_screen_utils
universal_video_controls/src/controls/methods/full_screen_utils/full_screen_utils_native
universal_video_controls/src/controls/methods/full_screen_utils/full_screen_utils_web
universal_video_controls/src/controls/methods/fullscreen
This file is a part of media_kit (https://github.com/media-kit/media-kit).
universal_video_controls/src/controls/methods/video_state
This file is a part of media_kit (https://github.com/media-kit/media-kit).
universal_video_controls/src/controls/no
This file is a part of media_kit (https://github.com/media-kit/media-kit).
universal_video_controls/src/controls/widgets/fullscreen_inherited_widget
This file is a part of media_kit (https://github.com/media-kit/media-kit).
universal_video_controls/src/controls/widgets/video_controls_theme_data_injector
This file is a part of media_kit (https://github.com/media-kit/media-kit).
universal_video_controls/src/controls/widgets/video_state_inherited_widget
This file is a part of media_kit (https://github.com/media-kit/media-kit).
universal_video_controls_method_channel
universal_video_controls_platform_interface
universal_video_controls_web