media_picker_guard 0.0.1-beta.1 copy "media_picker_guard: ^0.0.1-beta.1" to clipboard
media_picker_guard: ^0.0.1-beta.1 copied to clipboard

Validates media file size, duration, and format before upload with friendly error messages. Prevents server rejections and improves user experience.

Media Picker Guard ๐Ÿ›ก๏ธ #

pub package License: MIT

A comprehensive Flutter package that validates media files (images, videos, audio, documents) before upload with user-friendly error messages. Prevent server rejections and improve user experience by catching validation issues early.

๐ŸŒŸ Features #

  • ๐Ÿ“ Size Validation: Set minimum and maximum file size limits with friendly error messages
  • โฑ๏ธ Duration Validation: Validate video and audio duration constraints
  • ๐ŸŽฏ Format Validation: Restrict file extensions and MIME types
  • ๐Ÿš€ Performance Optimized: Quick validation checks and batch processing
  • ๐Ÿ’ฌ User-Friendly Errors: Customizable, localized error messages
  • ๐Ÿ”ง Flexible Configuration: Pre-built configs for common scenarios + custom options
  • ๐Ÿ“ฑ Cross-Platform: Works on iOS, Android, Web, and Desktop
  • ๐Ÿงช Well Tested: Comprehensive test coverage
  • ๐Ÿ“– Type Safe: Full TypeScript-like safety with Dart

๐Ÿš€ Getting Started #

Add to your pubspec.yaml:

dependencies:
  media_picker_guard: ^0.0.1

Then run:

flutter pub get

๐Ÿ“– Usage #

Quick Start #

import 'package:media_picker_guard/media_picker_guard.dart';
import 'dart:io';

// Validate an image file
final config = MediaPickerGuard.imageUploadConfig(
  maxSizeMB: 5,
  allowedExtensions: ['jpg', 'jpeg', 'png'],
);

final file = File('/path/to/image.jpg');
final result = await MediaPickerGuard.validateFile(file, config: config);

if (result.isValid) {
  print('โœ… File is ready for upload!');
} else {
  print('โŒ Validation failed: ${result.firstFriendlyErrorMessage}');
}

Pre-built Configurations #

Image Upload

final config = MediaPickerGuard.imageUploadConfig(
  maxSizeMB: 5,                    // Maximum 5MB
  allowedExtensions: ['jpg', 'png', 'gif'],
  customErrorMessages: {
    'fileSizeExceeded': 'Image too large! Max 5MB allowed.',
    'formatNotAllowed': 'Only JPG, PNG, and GIF images are supported.',
  },
);

Video Upload

final config = MediaPickerGuard.videoUploadConfig(
  maxSizeMB: 100,                  // Maximum 100MB
  maxDurationMinutes: 10,          // Maximum 10 minutes
  allowedExtensions: ['mp4', 'mov'],
  customErrorMessages: {
    'durationExceeded': 'Video too long! Maximum 10 minutes allowed.',
  },
);

Audio Upload

final config = MediaPickerGuard.audioUploadConfig(
  maxSizeMB: 20,                   // Maximum 20MB
  maxDurationMinutes: 30,          // Maximum 30 minutes
  allowedExtensions: ['mp3', 'wav', 'aac'],
);

Document Upload

final config = MediaPickerGuard.documentUploadConfig(
  maxSizeMB: 10,                   // Maximum 10MB
  allowedExtensions: ['pdf', 'doc', 'docx'],
);

Custom Configuration #

final config = MediaValidationConfig(
  maxSizeBytes: 5 * 1024 * 1024,   // 5MB
  minSizeBytes: 1024,              // 1KB minimum
  maxDuration: Duration(minutes: 5),
  allowedExtensions: ['jpg', 'png', 'mp4'],
  allowedMimeTypes: ['image/jpeg', 'image/png', 'video/mp4'],
  validateFileAccess: true,
  validateFileIntegrity: true,
  customErrorMessages: {
    'fileSizeExceeded': 'File is too large!',
    'formatNotAllowed': 'File format not supported!',
  },
);

Multiple File Validation #

final files = [
  File('/path/to/image1.jpg'),
  File('/path/to/image2.png'),
  File('/path/to/video.mp4'),
];

final results = await MediaPickerGuard.validateFiles(files, config: config);

for (final entry in results.entries) {
  final filePath = entry.key;
  final result = entry.value;
  
  if (result.isValid) {
    print('โœ… $filePath is valid');
  } else {
    print('โŒ $filePath: ${result.firstFriendlyErrorMessage}');
  }
}

Quick Validation (Performance Optimized) #

// For performance-critical scenarios
final isValid = await MediaPickerGuard.isFileValid(file, config: config);

if (isValid) {
  // Proceed with upload
} else {
  // Get detailed errors only if needed
  final result = await MediaPickerGuard.validateFile(file, config: config);
  showErrorToUser(result.firstFriendlyErrorMessage);
}

File Information #

final fileInfo = await MediaPickerGuard.getFileInfo(file);

if (fileInfo != null) {
  print('File: ${fileInfo['fileName']}');
  print('Size: ${fileInfo['fileSizeFormatted']}');
  print('Type: ${fileInfo['mimeType']}');
  print('Is Image: ${fileInfo['isImage']}');
}

๐ŸŽฏ Common Use Cases #

1. Profile Picture Upload #

final config = MediaPickerGuard.imageUploadConfig(
  maxSizeMB: 2,
  allowedExtensions: ['jpg', 'jpeg', 'png'],
  customErrorMessages: {
    'fileSizeExceeded': 'Profile picture must be under 2MB',
    'formatNotAllowed': 'Please select a JPG or PNG image',
  },
);

2. Social Media Video Upload #

final config = MediaPickerGuard.videoUploadConfig(
  maxSizeMB: 50,
  maxDurationMinutes: 5,
  allowedExtensions: ['mp4', 'mov'],
  customErrorMessages: {
    'durationExceeded': 'Videos must be 5 minutes or less',
    'fileSizeExceeded': 'Video file is too large (max 50MB)',
  },
);

3. Document Attachment #

final config = MediaPickerGuard.documentUploadConfig(
  maxSizeMB: 10,
  allowedExtensions: ['pdf', 'doc', 'docx', 'txt'],
  customErrorMessages: {
    'formatNotAllowed': 'Only PDF, Word, and text documents allowed',
  },
);

๐Ÿ”ง Advanced Features #

Error Handling Patterns #

// Pattern 1: Simple validation
final result = await MediaPickerGuard.validateFile(file, config: config);
if (!result.isValid) {
  showError(result.firstFriendlyErrorMessage);
  return;
}

// Pattern 2: Handle specific error types
for (final error in result.errors) {
  switch (error.type) {
    case ValidationErrorType.fileSizeExceeded:
      handleSizeError(error);
      break;
    case ValidationErrorType.formatNotAllowed:
      handleFormatError(error);
      break;
    default:
      handleGenericError(error);
  }
}

// Pattern 3: Batch validation with progress
final validFiles = <File>[];
for (int i = 0; i < files.length; i++) {
  final isValid = await MediaPickerGuard.isFileValid(files[i], config: config);
  if (isValid) validFiles.add(files[i]);
  updateProgress(i + 1, files.length);
}

Custom Validation Logic #

// Extend validation with custom logic
Future<bool> validateFileWithCustomRules(File file) async {
  // First, run standard validation
  final standardResult = await MediaPickerGuard.validateFile(file, config: config);
  if (!standardResult.isValid) return false;
  
  // Add custom business logic
  if (await isFileAlreadyUploaded(file)) {
    showError('This file has already been uploaded');
    return false;
  }
  
  if (await containsInappropriateContent(file)) {
    showError('File content not allowed');
    return false;
  }
  
  return true;
}

๐Ÿ“Š Validation Types #

Validation Type Supported Files Description
Size All files Min/max file size in bytes
Duration Video, Audio Min/max media duration
Extension All files Allowed file extensions
MIME Type All files Allowed MIME types
File Access All files File accessibility check
Integrity All files Basic corruption detection

๐ŸŽจ Error Types #

Error Type Description User-Friendly Message
fileSizeExceeded File too large "File is too large (2.5MB). Maximum size allowed is 2.0MB."
fileSizeTooSmall File too small "File is too small (5KB). Minimum size required is 10KB."
durationExceeded Media too long "Media is too long (12m 30s). Maximum duration allowed is 10m."
durationTooShort Media too short "Media is too short (5s). Minimum duration required is 10s."
formatNotAllowed Wrong file format "File format 'txt' is not supported. Supported formats: jpg, png."
fileNotAccessible Cannot access file "Unable to access the selected file. Please try a different file."
fileCorrupted File corrupted "File appears to be corrupted. Please try a different file."

๐Ÿ” API Reference #

MediaPickerGuard #

Main class for file validation.

Methods

  • validateFile(File file, {MediaValidationConfig? config}) โ†’ Future<MediaValidationResult>
  • validateFilePath(String filePath, {MediaValidationConfig? config}) โ†’ Future<MediaValidationResult>
  • validateFiles(List<File> files, {MediaValidationConfig? config}) โ†’ Future<Map<String, MediaValidationResult>>
  • isFileValid(File file, {MediaValidationConfig? config}) โ†’ Future<bool>
  • getFileInfo(File file) โ†’ Future<Map<String, dynamic>?>

Factory Methods

  • imageUploadConfig({...}) โ†’ MediaValidationConfig
  • videoUploadConfig({...}) โ†’ MediaValidationConfig
  • audioUploadConfig({...}) โ†’ MediaValidationConfig
  • documentUploadConfig({...}) โ†’ MediaValidationConfig

MediaValidationConfig #

Configuration class for validation rules.

Properties

  • maxSizeBytes โ†’ int? - Maximum file size in bytes
  • minSizeBytes โ†’ int? - Minimum file size in bytes
  • maxDuration โ†’ Duration? - Maximum media duration
  • minDuration โ†’ Duration? - Minimum media duration
  • allowedExtensions โ†’ List<String>? - Allowed file extensions
  • allowedMimeTypes โ†’ List<String>? - Allowed MIME types
  • mediaType โ†’ MediaType - Expected media type
  • customErrorMessages โ†’ Map<String, String>? - Custom error messages

MediaValidationResult #

Result of validation operation.

Properties

  • isValid โ†’ bool - Whether validation passed
  • errors โ†’ List<MediaValidationError> - List of validation errors
  • metadata โ†’ Map<String, dynamic>? - Additional file metadata
  • firstError โ†’ MediaValidationError? - First error (if any)
  • friendlyErrorMessages โ†’ List<String> - User-friendly error messages

๐Ÿค 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/AmazingFeature)
  3. Commit your changes (git commit -m 'Add some AmazingFeature')
  4. Push to the branch (git push origin feature/AmazingFeature)
  5. Open a Pull Request

๐Ÿ“ License #

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

๐Ÿ› Issues #

Found a bug or have a feature request? Please open an issue on GitHub.

๐Ÿ“š Interactive Example App #

We've created a complete Flutter example app that you can run to test all the features:

๐Ÿš€ Quick Start #

# Clone and run the example app
./run_example.sh

Or manually:

cd example_app
flutter pub get
flutter run

๐ŸŽฏ Example App Features #

  • ๐Ÿ“ฑ Beautiful UI: Material Design interface with intuitive controls
  • ๐ŸŽ›๏ธ Multiple Validation Types: Switch between Image, Video, Audio, Document, and Custom configurations
  • ๐Ÿ“ Multiple File Sources: Pick from gallery, camera, or file system
  • โšก Real-time Validation: Instant feedback with detailed results
  • ๐ŸŽจ Visual Results: Color-coded success/failure with detailed error messages
  • ๐Ÿ“Š File Information: Complete file analysis and metadata display

๐Ÿ–ผ๏ธ Screenshots #

The example app includes:

  • Validation type selector (Image, Video, Audio, Document, Custom)
  • Configuration display showing current validation rules
  • File selection buttons (Gallery, Camera, Files)
  • Real-time file information display
  • Color-coded validation results with detailed error messages

๐Ÿ“‹ Testing Scenarios #

The app is perfect for testing:

  • โœ… Valid files: Small images, short videos, supported formats
  • โŒ Invalid files: Large files, unsupported formats, long videos
  • ๐Ÿ”„ Edge cases: Empty files, corrupted files, permission issues

Check out the example_app directory for the complete source code and example for additional usage patterns.

๐Ÿ”ฎ Future Features #

  • โŒ Image dimension validation (width/height)
  • โŒ Video resolution validation
  • โŒ Audio quality/bitrate validation
  • โŒ Cloud storage integration
  • โŒ Batch processing with progress callbacks
  • โŒ Advanced file type detection
  • โŒ Content-based validation (AI/ML integration)

Made with โค๏ธ by the Flutter community

1
likes
150
points
2
downloads

Publisher

verified publishermuz.satech.dev

Weekly Downloads

Validates media file size, duration, and format before upload with friendly error messages. Prevents server rejections and improves user experience.

Repository (GitHub)
View/report issues

Documentation

API reference

License

MIT (license)

Dependencies

flutter, mime, path

More

Packages that depend on media_picker_guard