medias_viewer 0.6.1 copy "medias_viewer: ^0.6.1" to clipboard
medias_viewer: ^0.6.1 copied to clipboard

A powerful and customizable Flutter media viewer for images and videos with zoom, swipe navigation, and video controls.

Medias Viewer #

pub package License: MIT

A powerful and customizable Flutter media viewer for images, videos, YouTube and Vimeo videos with zoom, swipe navigation, and video controls.

Features #

✨ Image Support

  • Zoom with pinch-to-zoom and double-tap
  • Pan and navigate zoomed images
  • Support for network, local files, and assets
  • High-resolution image support with caching
  • Hero animations

🎬 Video Support

  • Auto-pause when swiping away
  • Full playback controls (play, pause, seek)
  • Fullscreen support
  • Support for network, local files, and assets
  • Custom video player with Chewie
  • SafeArea-aware controls (notch-friendly)
  • Smart navigation arrows (auto-hide during video playback)
  • Configurable back button positioning

πŸ“Ί YouTube Support

  • Play YouTube videos directly in the viewer
  • Auto-detection of YouTube URLs (youtube.com, youtu.be)
  • Integrated player without external browser
  • Full support for autoPlay, controls, and fullscreen
  • Optimized for Android and iOS with excellent mobile performance
  • Seamless navigation with other media types
  • Simple and fluid integration with better mobile compatibility

πŸŽ₯ Vimeo Support

  • Play Vimeo videos directly in the viewer
  • Auto-detection of Vimeo URLs (vimeo.com, player.vimeo.com)
  • Integrated player without external browser
  • High-quality video streaming
  • Seamless navigation with other media types
  • Simple integration with mobile-optimized playback

🎨 Customization

  • Custom background colors
  • Configurable page indicator (position, style, colors)
  • Navigation arrows (left/right) with customizable position
  • Back/Close button
  • Enable/disable zoom
  • Enable/disable loop navigation
  • Auto-play videos option
  • Custom indicator styles
  • Swipe down to dismiss

⚑ Performance

  • Optimized memory management
  • Efficient video controller disposal
  • Smooth page transitions
  • Network image caching
  • Improved swipe detection (horizontal vs vertical)

🎯 User Experience

  • SafeArea support for all controls (notch-friendly)
  • Swipe down gesture to close viewer
  • Optional navigation arrows for manual control
  • Configurable swipe sensitivity
  • Smooth transitions between zoomed images

πŸ“± Platform Support

  • βœ… Android
  • βœ… iOS
  • βœ… Desktop (macOS)

Installation #

Add this to your package's pubspec.yaml file:

dependencies:
  medias_viewer: ^0.4.0

Then run:

flutter pub get

Usage #

Basic Example #

import 'package:flutter/material.dart';
import 'package:medias_viewer/medias_viewer.dart';

class MyGallery extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MediaViewer(
      items: [
        MediaItem.imageUrl('https://example.com/image1.jpg'),
        MediaItem.imageUrl('https://example.com/image2.jpg'),
        MediaItem.videoUrl('https://example.com/video.mp4'),
      ],
      onDismissed: () => Navigator.pop(context),
    );
  }
}

Example with Auto-Detection #

import 'package:flutter/material.dart';
import 'package:medias_viewer/medias_viewer.dart';

class MyGallery extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MediaViewer(
      items: [
        // Type is automatically detected from file extension
        MediaItem.url('https://example.com/photo1.jpg'),
        MediaItem.url('https://example.com/photo2.png'),
        MediaItem.url('https://example.com/video.mp4'),
        MediaItem.url('https://example.com/clip.mov'),
      ],
      config: MediaViewerConfig(
        enableAutoDetectMediaType: true,  // Enable auto-detection
      ),
      onDismissed: () => Navigator.pop(context),
    );
  }
}

Advanced Example #

MediaViewer(
  items: [
    MediaItem.imageUrl('https://example.com/image1.jpg', tag: 'hero1'),
    MediaItem.videoUrl('https://example.com/video.mp4'),
    MediaItem.youtubeUrl('https://www.youtube.com/watch?v=dQw4w9WgXcQ'),
    MediaItem.vimeoUrl('https://vimeo.com/76979871'),
    MediaItem.imagePath('/path/to/local/image.jpg'),
    MediaItem.imageAsset('assets/images/photo.png'),
  ],
  initialIndex: 0,
  config: MediaViewerConfig(
    backgroundColor: Colors.black,
    showIndicator: true,
    indicatorPosition: IndicatorPosition.topCenter,
    indicatorStyle: IndicatorStyle(
      textStyle: TextStyle(
        color: Colors.white,
        fontSize: 18,
        fontWeight: FontWeight.bold,
      ),
      backgroundColor: Colors.black54,
      borderRadius: 16,
    ),
    enableLoop: false,
    enableImageZoom: true,
    enableDoubleTapZoom: true,
    minScale: 1.0,
    maxScale: 3.0,
    autoPlayVideo: true,
    showVideoControls: true,
    allowFullScreen: true,
    onPageChanged: (index) => print('Page changed to $index'),
  ),
  onDismissed: () => Navigator.pop(context),
);

YouTube Video Example #

import 'package:flutter/material.dart';
import 'package:medias_viewer/medias_viewer.dart';

class YouTubeGallery extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MediaViewer(
      items: [
        MediaItem.youtubeUrl('https://www.youtube.com/watch?v=dQw4w9WgXcQ'),
        MediaItem.imageUrl('https://example.com/photo.jpg'),
        MediaItem.youtubeUrl('https://youtu.be/9bZkp7q19f0'),
      ],
      config: MediaViewerConfig(
        autoPlayVideo: true,
        allowFullScreen: true,
        showBackButton: true,
        enableDismissOnSwipeDown: true,
      ),
      onDismissed: () => Navigator.pop(context),
    );
  }
}

Vimeo Video Example #

import 'package:flutter/material.dart';
import 'package:medias_viewer/medias_viewer.dart';

class VimeoGallery extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MediaViewer(
      items: [
        MediaItem.vimeoUrl('https://vimeo.com/76979871'),
        MediaItem.imageUrl('https://example.com/photo.jpg'),
        MediaItem.vimeoUrl('https://player.vimeo.com/video/148751763'),
      ],
      config: MediaViewerConfig(
        autoPlayVideo: true,
        allowFullScreen: true,
        showBackButton: true,
        enableDismissOnSwipeDown: true,
      ),
      onDismissed: () => Navigator.pop(context),
    );
  }
}

New Features Examples #

Video UX Optimizations

The package now includes several video-specific UX improvements:

MediaViewer(
  items: [
    MediaItem.videoUrl('https://example.com/video.mp4'),
    // ... other items
  ],
  config: MediaViewerConfig(
    // Automatically hide navigation arrows when video is playing
    hideArrowsWhenVideoPlays: true,  // Default: true

    // Adjust back button position to avoid overlap with fullscreen button
    backButtonPadding: EdgeInsets.only(top: 16, left: 8),  // Default

    // Video controls automatically respect SafeArea (notch-friendly)
    showVideoControls: true,
  ),
);

What's improved:

  • βœ… Video controls respect device SafeArea (no more controls hidden behind notches)
  • βœ… Navigation arrows automatically fade out during video playback for unobstructed viewing
  • βœ… Back button position is configurable to prevent overlap with Chewie's fullscreen button
  • βœ… Smooth fade animations (300ms) for better user experience

With Navigation Arrows

MediaViewer(
  items: [...],
  config: MediaViewerConfig(
    showNavigationArrows: true,
    navigationArrowsPosition: NavigationArrowsPosition.centerVertical,
    arrowsColor: Colors.white,
    arrowsSize: 40,
  ),
);

With Back Button

MediaViewer(
  items: [...],
  config: MediaViewerConfig(
    showBackButton: true,
    backButtonColor: Colors.white,
  ),
  onDismissed: () => Navigator.pop(context),
);

Swipe Down to Dismiss

MediaViewer(
  items: [...],
  config: MediaViewerConfig(
    enableDismissOnSwipeDown: true,
  ),
  onDismissed: () => Navigator.pop(context),
);
MediaViewer(
  items: [...],
  config: MediaViewerConfig(
    // Navigation controls
    showNavigationArrows: true,
    navigationArrowsPosition: NavigationArrowsPosition.centerVertical,
    showBackButton: true,

    // Dismiss gesture
    enableDismissOnSwipeDown: true,

    // Indicator
    showIndicator: true,
    indicatorPosition: IndicatorPosition.topCenter,
    indicatorStyle: IndicatorStyle(
      backgroundColor: Colors.black54,
      borderRadius: 16,
    ),

    // Behavior
    autoPlayVideo: true,
    enableLoop: false,
  ),
  onDismissed: () => Navigator.pop(context),
);

Creating Media Items #

The simplest way to create media items is to use automatic type detection based on file extensions:

// Automatic detection from URL
MediaItem.url('https://example.com/photo.jpg')      // Detected as image
MediaItem.url('https://example.com/video.mp4')      // Detected as video

// Automatic detection from local path
MediaItem.path('/storage/photos/image.png')         // Detected as image
MediaItem.path('/storage/videos/clip.mov')          // Detected as video

// Automatic detection from asset
MediaItem.asset('assets/images/photo.jpg')          // Detected as image
MediaItem.asset('assets/videos/intro.mp4')          // Detected as video

Supported Extensions:

  • Images: jpg, jpeg, png, gif, webp, bmp, svg
  • Videos: mp4, mov, avi, mkv, webm, flv, m4v, wmv

Note: If the extension is not recognized, an UnsupportedError will be thrown with a helpful message listing all supported formats. For future versions, we plan to add HTTP Content-Type detection for even better reliability with network URLs.

Manual Type Specification

You can also explicitly specify the media type (useful when auto-detection isn't suitable):

Images

// Network image
MediaItem.imageUrl('https://example.com/image.jpg')

// Network image with hero tag
MediaItem.imageUrl('https://example.com/image.jpg', tag: 'hero_tag')

// Local file
MediaItem.imagePath('/path/to/image.jpg')

// Asset
MediaItem.imageAsset('assets/images/photo.png')

Videos

// Network video
MediaItem.videoUrl('https://example.com/video.mp4')

// Local file video
MediaItem.videoPath('/path/to/video.mp4')

// Asset video
MediaItem.videoAsset('assets/videos/intro.mp4')

YouTube Videos

// YouTube video from standard URL
MediaItem.youtubeUrl('https://www.youtube.com/watch?v=dQw4w9WgXcQ')

// YouTube video from short URL
MediaItem.youtubeUrl('https://youtu.be/dQw4w9WgXcQ')

// YouTube video with auto-detection
MediaItem.url('https://www.youtube.com/watch?v=dQw4w9WgXcQ')

// YouTube video starting at a specific time (90 seconds = 1min30s)
MediaItem.youtubeUrl('https://www.youtube.com/watch?v=dQw4w9WgXcQ&t=90')

// Short URL with start time (30 seconds)
MediaItem.youtubeUrl('https://youtu.be/dQw4w9WgXcQ?t=30')

Supported YouTube URL formats:

  • https://www.youtube.com/watch?v=VIDEO_ID
  • https://youtube.com/watch?v=VIDEO_ID
  • https://m.youtube.com/watch?v=VIDEO_ID
  • https://youtu.be/VIDEO_ID
  • youtube.com/watch?v=VIDEO_ID (without protocol)

Note: Make sure to add youtube_player_flutter to your dependencies. The package is compatible with Android and iOS platforms, with excellent mobile performance.

Vimeo Videos

// Vimeo video from standard URL
MediaItem.vimeoUrl('https://vimeo.com/76979871')

// Vimeo video from player URL
MediaItem.vimeoUrl('https://player.vimeo.com/video/148751763')

// Vimeo video with auto-detection
MediaItem.url('https://vimeo.com/76979871')

Supported Vimeo URL formats:

  • https://vimeo.com/VIDEO_ID
  • https://www.vimeo.com/VIDEO_ID
  • https://player.vimeo.com/video/VIDEO_ID
  • vimeo.com/VIDEO_ID (without protocol)

Note: Make sure to add vimeo_video_player to your dependencies. The package provides high-quality video streaming for mobile platforms.

Configuration Options #

Property Type Default Description
backgroundColor Color Colors.black Background color of the viewer
showIndicator bool true Show page indicator (e.g., "1 of 5")
indicatorPosition IndicatorPosition topCenter Position of the indicator
indicatorStyle IndicatorStyle? null Custom style for the indicator
enableLoop bool false Enable infinite loop navigation
enableImageZoom bool true Enable zoom for images
enableDoubleTapZoom bool true Enable double-tap to zoom
minScale double 1.0 Minimum zoom scale
maxScale double 3.0 Maximum zoom scale
autoPlayVideo bool false Auto-play videos when displayed
showVideoControls bool true Show video playback controls
allowFullScreen bool true Allow fullscreen video
pageSnapping bool true Enable page snapping
onPageChanged Function(int)? null Callback when page changes
showNavigationArrows bool false Show left/right navigation arrows
navigationArrowsPosition NavigationArrowsPosition centerVertical Position of navigation arrows
arrowsColor Color Colors.white Color of navigation arrows
arrowsSize double 40 Size of navigation arrows
showBackButton bool false Show back/close button
backButtonColor Color Colors.white Color of back button
backButtonPadding EdgeInsets EdgeInsets.only(top: 16, left: 8) Padding for back button positioning
enableDismissOnSwipeDown bool false Enable swipe down to dismiss
swipeToPageThreshold double 0.6 Swipe sensitivity (0.0 to 1.0)
enableAutoDetectMediaType bool false Enable automatic media type detection from file extensions
hideArrowsWhenVideoPlays bool true Automatically hide navigation arrows during video playback
enableAutoDetectMediaType bool true Automatically detect the media type

Indicator Positions #

  • IndicatorPosition.topLeft
  • IndicatorPosition.topCenter
  • IndicatorPosition.topRight
  • IndicatorPosition.bottomLeft
  • IndicatorPosition.bottomCenter
  • IndicatorPosition.bottomRight
  • NavigationArrowsPosition.centerVertical
  • NavigationArrowsPosition.top
  • NavigationArrowsPosition.bottom

Example App #

Check out the example directory for a complete demo app with various use cases:

  • Basic image gallery
  • Mixed media (images and videos)
  • Custom configurations
  • Gallery with zoom disabled
  • Video gallery with autoplay
  • Grid gallery with hero animations
  • Gallery with navigation arrows
  • Gallery with back button
  • Swipe down to dismiss gallery
  • Full featured gallery (all options enabled)

To run the example:

cd example
flutter pub get
flutter run

API Reference #

MediaViewer #

The main widget for displaying media.

Constructor Parameters:

  • items (required): List of MediaItem objects to display
  • initialIndex: Starting index (default: 0)
  • config: Configuration object for customization
  • onDismissed: Callback when viewer is dismissed

MediaItem #

Represents a media item (image or video).

Constructors:

  • MediaItem.imageUrl(String url, {String? tag})
  • MediaItem.imagePath(String path, {String? tag})
  • MediaItem.imageAsset(String assetPath, {String? tag})
  • MediaItem.videoUrl(String url)
  • MediaItem.videoPath(String path)
  • MediaItem.videoAsset(String assetPath)
  • MediaItem.youtubeUrl(String url) - NEW in v0.4.0
  • MediaItem.url(String url, {String? tag}) - Auto-detection (includes YouTube support)
  • MediaItem.path(String path, {String? tag}) - Auto-detection for local files
  • MediaItem.asset(String assetPath, {String? tag}) - Auto-detection for assets

MediaViewerConfig #

Configuration for the media viewer.

See the Configuration Options table above for all available properties.

IndicatorStyle #

Style configuration for the page indicator.

Properties:

  • textStyle: Text style for the indicator
  • padding: Padding around the indicator
  • backgroundColor: Optional background color
  • borderRadius: Border radius for the background

Performance Tips #

  1. Image Caching: Network images are automatically cached using cached_network_image
  2. Video Memory: Video controllers are properly disposed when swiping away
  3. Large Galleries: The package efficiently handles large numbers of media items
  4. Lazy Loading: Media items are loaded on-demand as you swipe

Requirements #

  • Flutter >= 3.24.0
  • Dart >= 3.9.2

Dependencies #

  • photo_view: ^0.15.0 - Image zoom and pan
  • video_player: ^2.9.2 - Video playback
  • chewie: ^1.8.5 - Custom video player with controls
  • youtube_player_flutter: 9.1.3 - YouTube video playback (optimized for mobile)
  • cached_network_image: ^3.4.1 - Network image caching

Contributing #

Contributions are welcome! Please feel free to submit a Pull Request.

  1. Fork the repository
  2. Create your feature branch (git checkout -b feature/amazing-feature)
  3. Commit your changes (git commit -m 'Add some amazing feature')
  4. Push to the branch (git push origin feature/amazing-feature)
  5. Open a Pull Request

Issues #

If you encounter any issues or have feature requests, please file them in the issue tracker.

License #

This project is licensed under the MIT License - see the LICENSE file for details.

Author #

BRIX - GitHub

Changelog #

See CHANGELOG.md for a list of changes in each version.

Acknowledgments #

0
likes
160
points
76
downloads

Publisher

unverified uploader

Weekly Downloads

A powerful and customizable Flutter media viewer for images and videos with zoom, swipe navigation, and video controls.

Repository (GitHub)
View/report issues
Contributing

Documentation

API reference

License

MIT (license)

Dependencies

cached_network_image, chewie, flutter, photo_view, video_player, vimeo_video_player, youtube_player_flutter

More

Packages that depend on medias_viewer