av_player 0.2.1 copy "av_player: ^0.2.1" to clipboard
av_player: ^0.2.1 copied to clipboard

A powerful Flutter video player with native Picture-in-Picture support, gesture controls, media notifications, and playlist management. Zero external dependencies.

AV Player #

License: BSD-3-Clause Pub Version Flutter

A powerful Flutter video player with native Picture-in-Picture, gesture controls, media notifications, playlist management, and theming — all with zero external dependencies. Uses native platform players directly (ExoPlayer, AVPlayer, GStreamer, HTML5 Video).

Built by FlutterPlaza.

Home Screen


Features #

  • Native PIP on Android, iOS, macOS, and Web
  • In-app PIP overlay on all platforms (draggable, corner-snapping)
  • Video playback from network URL, HLS/DASH stream, asset, or file
  • Gesture controls — double-tap skip, swipe volume/brightness, long-press speed, horizontal swipe seek
  • Media notifications — lock screen and notification bar controls
  • Playlist management — queue, shuffle, repeat (none / one / all)
  • Content-type presets.video(), .music(), .live(), .short()
  • Theming — full color customization via AVPlayerTheme
  • Playback speed — 0.25x to 3.0x
  • Background audio playback
  • System volume & brightness control
  • Wakelock support
  • Zero external dependencies — uses native platform players directly

Platform Support #

Feature Android iOS macOS Linux Windows Web
Video Playback Yes Yes Yes Yes Stub Yes
Native PIP Yes Yes Yes Yes
In-App PIP Yes Yes Yes Yes Yes Yes
Media Notifications Yes Yes Yes Yes
System Volume Yes Read-only Yes Yes Per-element
Brightness Yes Yes Built-in only sysfs
Wakelock Yes Yes Yes Yes Yes

Installation #

dependencies:
  av_player: ^0.2.1
import 'package:av_player/av_player.dart';

iOS & macOS — Swift Package Manager #

This plugin supports both CocoaPods and Swift Package Manager (SPM) for iOS and macOS.

CocoaPods (default) #

No extra setup is required. flutter build uses CocoaPods automatically.

Swift Package Manager #

Flutter 3.24.5+ can resolve iOS and macOS dependencies through SPM instead of CocoaPods. To enable it:

flutter config --enable-swift-package-manager

Then build as usual:

cd example
flutter build ios        # or: flutter build macos

Flutter detects the Package.swift files in ios/av_player/ and macos/av_player/ and resolves the plugin through SPM. No Podfile changes are needed — if SPM is enabled, Flutter prefers it; otherwise it falls back to CocoaPods.

To disable SPM and return to CocoaPods:

flutter config --no-enable-swift-package-manager

Quick Start #

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

  @override
  State<MyPlayer> createState() => _MyPlayerState();
}

class _MyPlayerState extends State<MyPlayer> {
  late final AVPlayerController _controller;

  @override
  void initState() {
    super.initState();
    _controller = AVPlayerController(
      const AVVideoSource.network('https://example.com/video.mp4'),
    )..initialize();
  }

  @override
  Widget build(BuildContext context) {
    return ValueListenableBuilder<AVPlayerState>(
      valueListenable: _controller,
      builder: (context, state, _) {
        return AspectRatio(
          aspectRatio: state.aspectRatio,
          child: AVVideoPlayer.video(_controller, title: 'My Video'),
        );
      },
    );
  }

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

Content-Type Presets #

AV Player provides four presets that configure controls and gestures for different content types.

Video Player — .video() #

Full controls with all features enabled: play/pause, seek bar, skip forward/backward, speed selector, loop toggle, PIP button, fullscreen button, and gesture controls.

Video Player

AVVideoPlayer.video(
  controller,
  title: 'My Video',
  onFullscreen: () => enterFullscreen(),
)

Shorts — .short() #

Minimal UI for vertical short-form content (TikTok/Reels/Shorts style). Only play/pause center button with double-tap and long-press gestures. Set looping for continuous replay.

Shorts

// Enable looping after initialization
controller.setLooping(true);
controller.play();

AVVideoPlayer.short(controller)

Music Player — .music() #

Audio-focused controls with skip next/previous, speed, and loop. Disables PIP and fullscreen since the video surface is used for album art or visualizer.

Music Player

AVVideoPlayer.music(
  controller,
  title: 'Song Name',
  onNext: () => playlist.next(),
  onPrevious: () => playlist.previous(),
)

Live Stream — .live() #

Live content preset. Disables seek bar, skip buttons, and speed control since live streams cannot be seeked. Only play/pause, PIP, and fullscreen remain.

Live Stream

AVVideoPlayer.live(controller, title: 'LIVE')

Picture-in-Picture #

Native PIP #

Uses the OS-level picture-in-picture window. Supported on Android, iOS, macOS, and Web.

Native PIP

// Enter native PIP
await controller.enterPip();

// Exit native PIP
await controller.exitPip();

// Check availability
final available = await controller.isPipAvailable();

In-App PIP Overlay #

A draggable, corner-snapping mini-player overlay that works on all platforms. Place it in your app's top-level Stack.

In-App PIP

Stack(
  children: [
    // Your app content
    Navigator(...),

    // Floating PIP overlay
    if (showPip)
      AVPipOverlay(
        controller: controller,
        initialSize: AVPipSize.medium,       // small, medium, large
        initialCorner: AVPipCorner.bottomRight,
        onClose: () => setState(() => showPip = false),
        onExpand: () => navigateToFullPlayer(),
      ),
  ],
)

Gesture Controls #

Gesture controls are enabled automatically with the .video() and .short() presets. You can also configure them manually.

Gesture Controls

Gesture Action
Tap Show/hide controls overlay
Double-tap right Skip forward 10s
Double-tap left Skip backward 10s
Long press Play at 2x speed while held
Swipe up/down (right side) Adjust volume
Swipe up/down (left side) Adjust brightness
Horizontal swipe Seek through video
AVVideoPlayer(
  controller,
  showControls: true,
  gestureConfig: const AVGestureConfig(
    doubleTapToSeek: true,
    seekDuration: Duration(seconds: 10),
    longPressSpeed: true,
    longPressSpeedMultiplier: 2.0,
    swipeToVolume: true,
    swipeToBrightness: true,
    horizontalSwipeToSeek: false,
  ),
)

Playlist Management #

AVPlaylistController manages a queue of video sources with navigation, repeat modes, and shuffle.

Playlist

final playlist = AVPlaylistController(
  sources: [
    const AVVideoSource.network('https://example.com/track1.mp4'),
    const AVVideoSource.network('https://example.com/track2.mp4'),
    const AVVideoSource.network('https://example.com/track3.mp4'),
  ],
  onSourceChanged: (source) async {
    // Reinitialize the player with the new source
    controller.dispose();
    controller = AVPlayerController(source);
    await controller.initialize();
    await controller.play();
  },
);

// Navigation
playlist.next();
playlist.previous();
playlist.jumpTo(2);

// Repeat modes: none, one, all
playlist.setRepeatMode(AVRepeatMode.all);

// Shuffle
playlist.setShuffle(true);

// Queue management
playlist.add(const AVVideoSource.network('https://example.com/track4.mp4'));
playlist.removeAt(1);
playlist.reorder(0, 2);

// Auto-advance on completion
controller.addListener(() {
  if (controller.value.isCompleted) {
    playlist.onTrackCompleted();
  }
});

Theming #

Customize the player's appearance with AVPlayerTheme. All controls, gestures, and PIP overlay respect the theme.

Theming

AVPlayerTheme(
  data: const AVPlayerThemeData(
    accentColor: Colors.deepOrange,
    iconColor: Colors.white,
    overlayColor: Color(0x61000000),
    sliderActiveColor: Colors.deepOrange,
    sliderThumbColor: Colors.deepOrange,
    sliderBufferColor: Color(0x62FFFFFF),
    sliderInactiveColor: Color(0x3DFFFFFF),
    progressBarColor: Colors.deepOrange,
  ),
  child: AVVideoPlayer.video(controller),
)

Replay #

When a video completes, the controls automatically show a replay icon. Tapping play (or the replay icon) seeks to the beginning and restarts playback.

Replay Icon


Media Notifications #

Display playback info on the lock screen and notification bar with media command support.

// Set metadata
await controller.setMediaMetadata(const AVMediaMetadata(
  title: 'Video Title',
  artist: 'Artist Name',
  album: 'Album Name',
));

// Enable/disable notification
await controller.setNotificationEnabled(true);

// Handle media commands (next, previous, seek)
final controller = AVPlayerController(
  source,
  onMediaCommand: (command, {seekPosition}) {
    switch (command) {
      case AVMediaCommand.next:
        playlist.next();
      case AVMediaCommand.previous:
        playlist.previous();
      default:
        break;
    }
  },
);

Custom Controls #

Replace the built-in controls with your own widget using controlsBuilder.

AVVideoPlayer(
  controller,
  showControls: true,
  controlsBuilder: (context, controller) {
    return ValueListenableBuilder<AVPlayerState>(
      valueListenable: controller,
      builder: (context, state, _) {
        return Center(
          child: IconButton(
            iconSize: 64,
            icon: Icon(state.isPlaying ? Icons.pause : Icons.play_arrow),
            onPressed: () {
              state.isPlaying ? controller.pause() : controller.play();
            },
          ),
        );
      },
    );
  },
)

API Reference #

AVPlayerController #

Method Description
initialize() Create the native player and start listening for events
play() Start or resume playback (seeks to start if completed)
pause() Pause playback
seekTo(Duration) Seek to position
setPlaybackSpeed(double) Set speed (0.25–3.0)
setLooping(bool) Enable/disable looping
setVolume(double) Set player volume (0.0–1.0)
enterPip() Enter native Picture-in-Picture
exitPip() Exit native Picture-in-Picture
isPipAvailable() Check if PIP is supported
setMediaMetadata(AVMediaMetadata) Set notification metadata
setNotificationEnabled(bool) Toggle media notification
setSystemVolume(double) Set system volume (0.0–1.0)
getSystemVolume() Get current system volume
setScreenBrightness(double) Set screen brightness (0.0–1.0)
getScreenBrightness() Get current brightness
setWakelock(bool) Prevent screen from sleeping
dispose() Release native resources

AVPlayerState #

Property Type Description
position Duration Current playback position
duration Duration Total video duration
buffered Duration Amount buffered
isPlaying bool Whether currently playing
isBuffering bool Whether buffering
isLooping bool Whether looping is enabled
isInitialized bool Whether the player is ready
isInPipMode bool Whether in native PIP
isCompleted bool Whether playback has finished
playbackSpeed double Current speed multiplier
volume double Player volume
aspectRatio double Video aspect ratio
errorDescription String? Error message if failed

Example App #

The example app includes 8 dedicated screens showcasing each feature. Run it with:

cd example
flutter run

See example/lib/main.dart for the full source.


Linux Build Dependencies #

sudo apt-get install libgstreamer1.0-dev libgstreamer-plugins-base1.0-dev libpulse-dev libgtk-3-dev

Contributing #

Contributions are welcome! Please read our contributing guidelines before submitting a PR.

License #

This project is licensed under the BSD 3-Clause License — see the LICENSE file for details.

1
likes
160
points
--
downloads

Publisher

verified publisherflutterplaza.com

A powerful Flutter video player with native Picture-in-Picture support, gesture controls, media notifications, and playlist management. Zero external dependencies.

Repository (GitHub)
View/report issues

Topics

#video-player #picture-in-picture #media #pip #player

Documentation

API reference

License

BSD-3-Clause (license)

Dependencies

flutter, flutter_web_plugins, plugin_platform_interface, web

More

Packages that depend on av_player

Packages that implement av_player