omni_video_player

All-in-one Flutter video player โ€“ stream from YouTube, Vimeo, network, assets files

pub version pub points pub popularity

Introduction

omni_video_player is a Flutter video player built on top of Flutterโ€™s official video_player plugin. It supports YouTube (via youtube_explode_dart), Vimeo videos (using flutter_inappwebview), as well as network and asset videos. A single unified controller is provided to manage playback across all supported video types seamlessly.

๐ŸŽจ Highly customizable โ€” tweak UI, show/hide controls, and easily integrate your own widgets.
๐ŸŽฎ The controller gives full control over video state and callbacks for smooth video management on mobile and web.

๐ŸŽฏ Long-term goal: to create a universal, flexible, and feature-rich video player that works flawlessly across all platforms and video sources, empowering developers with maximum control and customization options.


Supported Platforms & Status

Video Source Type Android iOS Web Status
YouTube โœ… โœ… โŒ โœ… Supported
Vimeo โœ… โœ… โŒ โœ… Supported
Network โœ… โœ… โœ… โœ… Supported
Asset โœ… โœ… โœ… โœ… Supported
Twitch - - - ๐Ÿ”œ Planned
TikTok - - - ๐Ÿ”œ Planned
Dailymotion - - - ๐Ÿ”œ Planned

โœจ Features

  • โœ… Play videos from:
    • YouTube (support for live and regular videos)
    • Vimeo (public)
    • Network video URLs
    • Flutter app assets
  • ๐ŸŽ› Customizable player UI (controls, theme, overlays, labels)
  • ๐Ÿ” Autoplay, replay, mute/unmute, volume control
  • โช Seek bar & scrubbing
  • ๐Ÿ–ผ Thumbnail support (custom or auto-generated for YouTube and Vimeo)
  • ๐Ÿ”Š Global playback & mute sync across players
  • โ›ถ Fullscreen player
  • โš™๏ธ Custom error and loading widgets

๐Ÿงช Demo

๐Ÿš€ Getting Started

Installation

Check the latest version on: Pub Version

dependencies:
  omni_video_player: <latest_version>

๐Ÿ› ๏ธ Android Setup

In your Flutter project, open:

android/app/src/main/AndroidManifest.xml
<!-- Add inside <manifest> -->
<uses-permission android:name="android.permission.INTERNET"/>

<!-- Add inside <application> -->
<application
    android:usesCleartextTraffic="true"
    ... >
</application>

โœ… The INTERNET permission is required for streaming videos.

โš ๏ธ The usesCleartextTraffic="true" is only needed if you're using HTTP (not HTTPS) URLs.


๐ŸŽ iOS Setup

To allow video streaming over HTTP (especially for development or non-HTTPS sources), add the following to your Info.plist file:

<!-- ios/Runner/Info.plist -->
<key>NSAppTransportSecurity</key>
<dict>
  <key>NSAllowsArbitraryLoads</key>
  <true/>
</dict>

๐Ÿ“ฆ Usage Examples

Network

VideoSourceConfiguration.network(
  videoUrl: Uri.parse('https://example.com/video.mp4'),
);

YouTube

VideoSourceConfiguration.youtube(
  videoUrl: Uri.parse('https://youtu.be/xyz'),
  preferredQualities: [720, 480],
);

Vimeo

VideoSourceConfiguration.vimeo(
  videoId: '123456789',
  preferredQualities: [1080],
);

Asset

VideoSourceConfiguration.asset(
  videoDataSource: 'assets/video.mp4'),
);

๐Ÿ“ฑ Example App

Explore the example/ folder for working demos:

  • Full demo using different video sources: main.dart
  • Minimal setup with controller and play/pause logic: example.dart

๐Ÿ’ก Great starting points to understand how to integrate and customize the player.


๐ŸŽฏ Sync UI with AnimatedBuilder

When using OmniPlaybackController, the controller itself is a Listenable, meaning it notifies listeners when playback state changes (e.g. play, pause, fullscreen).

To build dynamic UI that reacts to those changes (like updating a play/pause button), wrap your widgets with AnimatedBuilder:

OmniVideoPlayer(
  options: VideoPlayerConfiguration.youtube(
    videoUrl: Uri.parse('https://www.youtube.com/watch?v=cuqZPx0H7a0'),
  ),
  callbacks: VideoPlayerCallbacks(
    onControllerCreated: (controller) {
      _controller = controller;
      setState(() {}); // Enables the button below
    },
  ),
),
AnimatedBuilder(
  animation: Listenable.merge([controller]),
  builder: (context, _) {
    if (controller == null) return const CircularProgressIndicator();

    final isPlaying = controller.isPlaying;

    return ElevatedButton.icon(
      onPressed: () =>
          isPlaying ? controller.pause() : controller.play(),
      icon: Icon(isPlaying ? Icons.pause : Icons.play_arrow),
      label: Text(isPlaying ? 'Pause' : 'Play'),
    );
  },
);

โœ… Why it's needed

Flutter widgets donโ€™t rebuild on Listenable changes by default. AnimatedBuilder lets your UI stay in sync without manually calling setState() on every controller update โ€” making your code more efficient and reactive.

โ„น๏ธ Recommended for any UI that depends on the controller (playback state, fullscreen, etc.). It ensures consistent behavior and avoids state mismatch.


๐Ÿ”ฎ Future Developments

Feature Description
๐Ÿ“ƒ Playlist Support YouTube playlist playback and custom video URL lists
โฉ Double Tap Seek Skip forward/backward by configurable duration
๐Ÿ“š Side Command Bars Left and right customizable sidebars for placing user-defined widgets or controls.
๐Ÿงญ Header Bar Custom header with title, channel info, and actions
๐Ÿ–ผ Picture-in-Picture (PiP) Play video in floating overlay while multitasking
๐Ÿ“ถ Quality Selection Switch between 360p, 720p, 1080p, etc. during playback
โฑ Playback Speed Control Adjust speed: 0.5x, 1.5x, 2x, etc.
๐Ÿ” Looping / Repeat Loop a single video or an entire playlist
โ™ฟ Accessibility Screen reader support, keyboard nav, captions, ARIA, high contrast, etc.
โฌ‡๏ธ Download / Offline Mode Save videos temporarily for offline playback
๐Ÿ“บ Chromecast & AirPlay Stream to external devices like TVs or smart displays
๐Ÿ”’ Parental Controls Restrict age-inappropriate or sensitive content
โš™๏ธ Settings Button Easily access and configure playback preferences

๐Ÿ“„ License

BSD 3-Clause License โ€“ see LICENSE