flutter_media_picker_pro 1.0.1 copy "flutter_media_picker_pro: ^1.0.1" to clipboard
flutter_media_picker_pro: ^1.0.1 copied to clipboard

A versatile Flutter package for picking and handling images, videos, and audio, with compression, timestamps, and recording features.

example/lib/main.dart

import 'dart:io';
import 'package:audioplayers/audioplayers.dart';
import 'package:example/custom_recording_button.dart';
import 'package:example/custom_recording_wave_widget.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:flutter_image_compress/flutter_image_compress.dart';
import 'package:flutter_media_picker_pro/flutter_media_picker_pro.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:flutter_speed_dial/flutter_speed_dial.dart';
import 'package:image/image.dart';
import 'package:image_picker/image_picker.dart';
import 'package:image/image.dart' as img;
import 'package:permission_handler/permission_handler.dart';

Future<void> main() async {
  WidgetsFlutterBinding.ensureInitialized();
  runApp(const ProviderScope(child: MyApp()));
}

class MyApp extends ConsumerWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context, WidgetRef ref) {
    return  const MaterialApp(
      debugShowCheckedModeBanner: false,
      home: PictureScreen(),
    );
  }
}

class PictureScreen extends ConsumerStatefulWidget {
  const PictureScreen({super.key});

  @override
  _PictureScreenState createState() => _PictureScreenState();
}

class _PictureScreenState extends ConsumerState<PictureScreen> {
  final FlutterMediaPickerPro mediaPicker = FlutterMediaPickerPro();
  XFile? _mediaFile;
  bool _isProcessing = false;
  bool _isStartRecording = false;
  final AudioPlayer _audioPlayer = AudioPlayer();
  bool _isPlaying = false;
  bool isPlayAudio = true;
  String? audioPath;
  XFile? randomFile;

  @override
  void initState() {
    _requestPermissions();
    _audioPlayer.onPlayerComplete.listen((_) {
      setState(() {
        isPlayAudio = true;
        _isPlaying = false;
      });
    });
    super.initState();
  }

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

  Future<void> _requestPermissions() async {
    if (await Permission.storage.request().isGranted) {
      // Permission is granted
    } else {
      // Handle the case where permission is not granted
    }
  }


  Future<void> _pickMedia({CompressionLevel? compressionLevel,required bool isNeedTimeStamp,required bool isVideo, required bool isAudio, required bool isRecording, required bool isStartRecording,
    required bool isSourceCamera, required bool isCompressionRequired,}) async {
    final XFile? pickedFile = await FlutterMediaPickerPro.getMedia(compressionLevel: compressionLevel??CompressionLevel.high,isStartRecording: isStartRecording,isRecording: isRecording,isAudio: isAudio,
      isSourceCamera: isSourceCamera,context: context, isVideo: isVideo, ref: ref, isCompressionRequired: isCompressionRequired, isNeedTimeStamp: isNeedTimeStamp,onProcessing: (bool isProcessing) {
      setState(() {
        _isProcessing = isProcessing;
      });
    },);

    if (pickedFile != null) {
      setState(() {
        _mediaFile = pickedFile;
      });
    }

    if (isAudio) {
     if(!isRecording){
       await _audioPlayer.play(DeviceFileSource((pickedFile?.path).toString()));
       setState(() {
         _isPlaying = true;
       });
     }
    }
  }

  final PageController  _pageController = PageController();
  int _activePage = 0;
  @override
  Widget build(BuildContext context) {
    return Scaffold(
        appBar: AppBar(
          title: const Row(
            children: [
              Icon(Icons.perm_media, color: Colors.white), // General media icon
              SizedBox(width: 12), // Spacing between icon and title
              Text('Flutter Media Picker Pro', style: TextStyle(color: Colors.white, fontSize: 18),),
            ],
          ),
          backgroundColor: Colors.deepPurpleAccent,
          actions: [
            IconButton(
              icon: const Icon(Icons.info_outline, color: Colors.white,),
              onPressed: () {
                // Handle info action (e.g., show package information)
                showDialog(
                  context: context,
                  builder: (context) => AlertDialog(
                    title: const Text('About Media Picker Pro', style: TextStyle(fontWeight: FontWeight.bold, fontSize: 16),),
                    content: const Text(
                        'This package helps you pick and process media files including images, videos, and audio.', style: TextStyle( fontSize: 14),),
                    actions: [
                      TextButton(
                        onPressed: () => Navigator.of(context).pop(),
                        child: const Text('Close'),
                      ),
                    ],
                  ),
                );
              },
            ),
          ],
        ),

        body: PageView.builder(
          physics: const NeverScrollableScrollPhysics(),
          controller: _pageController,
          itemCount: 4,
          onPageChanged: (int page) {
            setState(() {
              _activePage = page;
              _mediaFile = null;
              if (kDebugMode) {
                print(_activePage);
              }
            });
          },
          itemBuilder: (BuildContext context, int index) {
            if (kDebugMode) {
              print('index : $index');
            }
            if (_activePage == 0) {
              return SingleChildScrollView(
                child: Padding(
                  padding: const EdgeInsets.all(16.0),
                  child: Column(
                    children: [
                      _isProcessing
                          ? const Center(child: CircularProgressIndicator())
                          : _mediaFile == null
                          ? Container(
                        height: 200,
                        width: double.infinity,
                        decoration: BoxDecoration(
                          border: Border.all(color: Colors.grey),
                          borderRadius: BorderRadius.circular(8),
                        ),
                        child: const Center(
                          child: Text(
                            'No media selected!',
                            style: TextStyle(
                              fontSize: 18,
                            ),
                          ),
                        )
                      )
                          : mediaPicker.displayImage(File(_mediaFile!.path)),
                      const SizedBox(height: 20),
                      Wrap(
                        crossAxisAlignment: WrapCrossAlignment.start,
                        spacing: 10,
                        runSpacing: 10,
                        children: [
                          _buildMediaButton(
                            icon: Icons.camera_alt,
                            label: 'Capture Image',
                            onPressed: () {
                              _pickMedia(
                                  isVideo: false,
                                  isAudio: false,
                                  isRecording: false,
                                  isStartRecording: false,
                                  isNeedTimeStamp: false,
                                  isSourceCamera: true,
                                  isCompressionRequired: false);
                            },
                          ),
                          _buildMediaButton(
                            icon: Icons.image,
                            label: 'Pick Image',
                            onPressed: () {
                              _pickMedia(
                                  isVideo: false,
                                  isAudio: false,
                                  isRecording: false,
                                  isStartRecording: false,
                                  isNeedTimeStamp: false,
                                  isSourceCamera: false,
                                  isCompressionRequired: false);
                            },
                          ),
                          _buildMediaButton(
                            showSecondIcon: true,
                            secondIcon: Icons.compress,
                            icon: Icons.image,
                            label: 'Pick & Compress Image',
                            onPressed: () {
                              showCompressionDialog(isSourceCamera: false, isTimeStampNeeded: false);
                              /*_pickMedia(
                                  isVideo: false,
                                  isAudio: false,
                                  isRecording: false,
                                  isStartRecording: false,
                                  isNeedTimeStamp: false,
                                  isSourceCamera: false,
                                  isCompressionRequired: true);*/
                            },
                          ),

                          _buildMediaButton(
                            icon: Icons.camera_alt,
                            showSecondIcon: true,
                            secondIcon: Icons.compress,
                            label: 'Pick & Compress Image',
                            onPressed: () {
                              showCompressionDialog(isSourceCamera: true, isTimeStampNeeded: false);
                              /*_pickMedia(
                                  isVideo: false,
                                  isAudio: false,
                                  isRecording: false,
                                  isStartRecording: false,
                                  isNeedTimeStamp: false,
                                  isSourceCamera: true,
                                  isCompressionRequired: true);*/
                            },
                          ),
                          _buildMediaButton(
                            icon: Icons.access_time,
                            label: 'Add Timestamp on Gallery Image',
                            onPressed: () {
                              _pickMedia(
                                  isVideo: false,
                                  isAudio: false,
                                  isRecording: false,
                                  isStartRecording: false,
                                  isNeedTimeStamp: true,
                                  isSourceCamera: false,
                                  isCompressionRequired: false);
                            },
                          ),
                          _buildMediaButton(
                            icon: Icons.access_time,
                            label: 'Add Timestamp on Camera Image',
                            //color: Colors.white,
                            onPressed: () {
                              _pickMedia(
                                  isVideo: false,
                                  isAudio: false,
                                  isRecording: false,
                                  isStartRecording: false,
                                  isNeedTimeStamp: true,
                                  isSourceCamera: true,
                                  isCompressionRequired: false);
                            },
                          ),

                          _buildMediaButton(
                            icon: Icons.access_time,
                            showSecondIcon: true,
                            secondIcon: Icons.compress,
                            label: 'Add Timestamp & Compress Camera Image',
                            //color: Colors.white,
                            onPressed: () {
                              showCompressionDialog(isSourceCamera: true, isTimeStampNeeded: true);
                            },
                          ),

                          _buildMediaButton(
                            icon: Icons.access_time,
                            showSecondIcon: true,
                            secondIcon: Icons.compress,
                            label: 'Add Timestamp & Compress Gallery Image',
                            //color: Colors.white,
                            onPressed: () {
                              showCompressionDialog(isSourceCamera: false, isTimeStampNeeded: true);
                            },
                          ),
                        ],
                      ),
                    ],
                  ),
                ),
              );
            } else if (_activePage == 1) {
              return Column(
                mainAxisAlignment: MainAxisAlignment.center,
                crossAxisAlignment: CrossAxisAlignment.center,
                children: [

                 Padding(
                   padding: const EdgeInsets.all(8.0),
                   child: Container(
                     decoration: BoxDecoration(

                       borderRadius: BorderRadius.circular(10),
                       border: Border.all(color: Colors.blue)
                     ),
                     width: double.infinity,
                     child: Column(
                       children: [
                         if (_isStartRecording) const CustomRecordingWaveWidget(),
                         const SizedBox(height: 16),
                         Center(
                           child: CustomRecordingButton(
                             isRecording: _isStartRecording,
                             onPressed: () async {
                               _mediaFile = null;
                               audioPath = null;
                               if (_isStartRecording == false) {
                                 _isStartRecording = true;
                                 _pickMedia(
                                     isVideo: false,
                                     isAudio: true,
                                     isRecording: true,
                                     isStartRecording: true,
                                     isNeedTimeStamp: false,
                                     isSourceCamera: false,
                                     isCompressionRequired: false);
                               } else {
                                 _isStartRecording = false;
                                 audioPath = await FlutterMediaPickerPro.getMedia(
                                   isStartRecording: false,
                                   isRecording: true,
                                   isAudio: true,
                                   isSourceCamera: true,
                                   context: context,
                                   isVideo: false,
                                   ref: ref,
                                   isCompressionRequired: false,
                                   isNeedTimeStamp: true,
                                   onProcessing: (bool isProcessing) {
                                     setState(() {
                                       _isProcessing = isProcessing;
                                     });
                                   },
                                 );
                                 if (kDebugMode) {
                                   print('Checking audio path at stop recording::${audioPath.toString()}');
                                 }
                                 setState(() {});
                               }
                             },
                           ),
                         ),

                         audioPath != null
                             ? Text('$audioPath', textAlign: TextAlign.center,)
                             : const SizedBox(),
                         audioPath != null
                             ? IconButton(
                           icon: Icon(!isPlayAudio
                               ? Icons.pause
                               : Icons.play_arrow),
                           onPressed: () async {
                             if (kDebugMode) {
                               print('Checking audio path::${audioPath.toString()}');
                             }
                             if (isPlayAudio) {
                               isPlayAudio = false;
                               await _audioPlayer.play(DeviceFileSource(audioPath.toString()));
                               setState(() {});
                             } else {
                               isPlayAudio = true;
                               _audioPlayer.pause();
                             }
                             setState(() {});
                           },
                         )
                             : const SizedBox(),
                         const SizedBox(height: 16),
                       ],
                     ),
                   ),
                 ),
                  const SizedBox(width: 10),

                  if (_isProcessing)
                    const CircularProgressIndicator()
                  else if (_mediaFile == null)
                    const SizedBox(
                    )
                  else
                    Text(_mediaFile!.name),
                  _mediaFile != null
                      ? IconButton(
                    icon: Icon(_isPlaying ? Icons.pause : Icons.play_arrow),
                    onPressed: () async {
                      if (_isPlaying) {
                        await _audioPlayer.pause();
                      } else {
                        await _audioPlayer.resume();
                      }
                      setState(() {
                        _isPlaying = !_isPlaying;
                      });
                    },
                  )
                      : const SizedBox(),
                  _buildMediaButton(
                    icon: Icons.audiotrack,
                    label: 'Pick Audio',
                    onPressed: () {
                      _mediaFile = null;
                      audioPath = null;
                      _pickMedia(
                          isVideo: false,
                          isAudio: true,
                          isRecording: false,
                          isStartRecording: false,
                          isNeedTimeStamp: false,
                          isSourceCamera: false,
                          isCompressionRequired: false);
                    },
                  ),

                ],
              );
            }
            else if(_activePage == 2){
              return SingleChildScrollView(
                child: Column(
                  children: [
                    _isProcessing
                        ? const Center(child: CircularProgressIndicator())
                        : _mediaFile == null
                        ? Padding(
                          padding: const EdgeInsets.all(12.0),
                          child: Container(
                          height: 200,
                          width: double.infinity,
                          decoration: BoxDecoration(
                            border: Border.all(color: Colors.grey),
                            borderRadius: BorderRadius.circular(8),
                          ),
                          child: const Center(
                            child: Text(
                              'No media selected!',
                              style: TextStyle(
                                fontSize: 18,
                              ),
                            ),
                          )
                                              ),
                        )
                        : mediaPicker.displayVideo(File(_mediaFile!.path)),

                    Wrap(
                      crossAxisAlignment: WrapCrossAlignment.start,
                      spacing: 10,
                      runSpacing: 10,
                      children: [
                        _buildMediaButton(
                          icon: Icons.video_call,
                          label: 'Take Video',
                          //color: Colors.white,
                          onPressed: () {
                            _pickMedia(
                                isVideo: true,
                                isAudio: false,
                                isRecording: false,
                                isStartRecording: false,
                                isNeedTimeStamp: false,
                                isSourceCamera: true,
                                isCompressionRequired: false);
                          },
                        ),

                        _buildMediaButton(
                          icon: Icons.video_call,
                          label: 'Pick Video',
                          //color: Colors.white,
                          onPressed: () {
                            _pickMedia(
                                isVideo: true,
                                isAudio: false,
                                isRecording: false,
                                isStartRecording: false,
                                isNeedTimeStamp: false,
                                isSourceCamera: false,
                                isCompressionRequired: false);
                          },
                        ),

                        _buildMediaButton(
                          icon: Icons.image,
                          label: 'Compress Camera Video',
                          //color: Colors.white,
                          onPressed: () {
                            showCompressionDialog(isVideo: true,isTimeStampNeeded: false, isSourceCamera: true);
                          },
                        ),

                        _buildMediaButton(
                          icon: Icons.image,
                          label: 'Compress Gallery Video',
                          //color: Colors.white,
                          onPressed: () {
                            showCompressionDialog(isVideo: true,isTimeStampNeeded: false, isSourceCamera: false);
                          },
                        ),

                        _buildMediaButton(
                          icon: Icons.access_time,
                          label: 'Add Timestamp on Camera Video',
                          //color: Colors.white,
                          onPressed: () {
                            _pickMedia(
                                isVideo: true,
                                isAudio: false,
                                isRecording: false,
                                isStartRecording: false,
                                isNeedTimeStamp: true,
                                isSourceCamera: true,
                                isCompressionRequired: false);
                          },
                        ),

                        _buildMediaButton(
                          icon: Icons.access_time,
                          label: 'Add Timestamp on Gallery Video',
                          //color: Colors.white,
                          onPressed: () {
                            _pickMedia(
                                isVideo: true,
                                isAudio: false,
                                isRecording: false,
                                isStartRecording: false,
                                isNeedTimeStamp: true,
                                isSourceCamera: false,
                                isCompressionRequired: false);
                          },
                        ),

                        _buildMediaButton(
                          icon: Icons.access_time,
                          secondIcon: Icons.compress,
                          showSecondIcon: true,
                          label: 'Add Timestamp & Compress Gallery Video',
                          //color: Colors.white,
                          onPressed: () {
                            showCompressionDialog(isVideo: true,isTimeStampNeeded: true, isSourceCamera: false);
                          },
                        ),

                        _buildMediaButton(
                          icon: Icons.access_time,
                          secondIcon: Icons.compress,
                          showSecondIcon: true,
                          label: 'Add Timestamp & Compress Camera Video',
                          //color: Colors.white,
                          onPressed: () {
                            showCompressionDialog(isVideo: true,isTimeStampNeeded: true, isSourceCamera: true);
                          },
                        ),
                      ],
                    ),


                  ],
                ),
              );
            }
            else{
              return Column(
                mainAxisAlignment: MainAxisAlignment.center,
                crossAxisAlignment: CrossAxisAlignment.center,
                children: [

                  if (_isProcessing)
                    const CircularProgressIndicator()
                  else if (randomFile == null)
                    const SizedBox(
                    )
                  else
                    Padding(
                      padding: const EdgeInsets.all(8.0),
                      child: Text('Picked File Path: ${(randomFile?.path).toString()}', textAlign: TextAlign.center, ),
                    ),

                  _buildMediaButton(
                    icon: Icons.audiotrack,
                    label: 'Pick File',
                    onPressed: () async {
                      randomFile = await FlutterMediaPickerPro.getMedia(
                        isFile: true,
                        isStartRecording: false,
                        isRecording: false,
                        isAudio: false,
                        isSourceCamera: true,
                        context: context,
                        isVideo: false,
                        ref: ref,
                        isCompressionRequired: false,
                        isNeedTimeStamp: false,
                        onProcessing: (bool isProcessing) {
                          setState(() {
                            _isProcessing = isProcessing;
                          });
                        },
                      );
                    },
                  ),

                ],
              );
            }
          },
        ),
      // Center(
      //   child: _isProcessing
      //       ? CircularProgressIndicator()
      //       :_mediaFile == null
      //       ? Text('No media selected.')
      //       : _mediaFile!.path.endsWith('.mp4')
      //       ?
      //   mediaPicker.displayVideo(File(_mediaFile!.path))
      //       : _mediaFile!.path.endsWith('.mp3') || _mediaFile!.path.endsWith('.wav') || _mediaFile!.path.endsWith('.aac')
      //       ? Column(
      //     mainAxisAlignment: MainAxisAlignment.center,
      //     children: [
      //       Text('Playing audio: ${_mediaFile!.name}'),
      //       IconButton(
      //         icon: Icon(_isPlaying ? Icons.pause : Icons.play_arrow),
      //         onPressed: () async {
      //           if (_isPlaying) {
      //             await _audioPlayer.pause();
      //           } else {
      //             await _audioPlayer.resume();
      //           }
      //           setState(() {
      //             _isPlaying = !_isPlaying;
      //           });
      //         },
      //       ),
      //     ],
      //   )
      //       : mediaPicker.displayImage(File(_mediaFile!.path)),
      // ),
      floatingActionButton: SpeedDial(
        spacing: 8,
        spaceBetweenChildren: 5,
        animatedIcon: AnimatedIcons.menu_arrow,
        children: [
          SpeedDialChild(
            child: const Icon(Icons.image_outlined),
            label: 'Image',
            onTap: (){
              _pageController.animateToPage(
                0,
                duration: const Duration(milliseconds: 300),
                curve: Curves.easeInOut,
              );
            }
          ),
          SpeedDialChild(
              child: const Icon(Icons.video_call),
              label: 'Video',
              onTap: (){
                _pageController.animateToPage(
                  2,
                  duration: const Duration(milliseconds: 300),
                  curve: Curves.easeInOut,
                );
              }
          ),
          SpeedDialChild(
              child: const Icon(Icons.audiotrack),
              label: 'Audio',
              onTap: (){
                _pageController.animateToPage(
                  1,
                  duration: const Duration(milliseconds: 300),
                  curve: Curves.easeInOut,
                );

              }
          ),
          SpeedDialChild(
              child: const Icon(Icons.file_present),
              label: 'File',
              onTap: (){
                _pageController.animateToPage(
                  4,
                  duration: const Duration(milliseconds: 300),
                  curve: Curves.easeInOut,
                );

              }
          )
        ],
      )
    );
  }

  Widget _buildMediaButton({
    required IconData icon,
    IconData? secondIcon,
    bool showSecondIcon = false,
    required String label,
    Color? color,
    required VoidCallback onPressed,
  }) {
    return ElevatedButton.icon(
      onPressed: onPressed,
      icon: Row(
        children: [
          Icon(icon, color: Colors.white, size: 14,),
          showSecondIcon? Row(
            children: [
              const Padding(
                padding: EdgeInsets.symmetric(horizontal: 5.0),
                child: Text('+'),
              ),
              Icon(secondIcon, color: Colors.white, size: 14,),
            ],
          ): const SizedBox()
        ],
      ),
      label: Text(label, style: const TextStyle(color: Colors.white, fontSize: 12)),
      style: ElevatedButton.styleFrom(
        foregroundColor: Colors.white, backgroundColor: Colors.deepPurpleAccent,
        shape: RoundedRectangleBorder(
          borderRadius: BorderRadius.circular(12),
        ),
        elevation: 2,
        padding: const EdgeInsets.symmetric(vertical: 10, horizontal: 15),
      ),
    );
  }

  Future<void> showCompressionDialog({bool isVideo = false ,bool isSourceCamera = false, bool isTimeStampNeeded = false}) async {
    CompressionLevel? selectedLevel = CompressionLevel.high;

    await showDialog<void>(
      context: context,
      builder: (BuildContext context) {
        return AlertDialog(
          title: const Text('Select Compression Level', style: TextStyle(fontSize: 18, fontWeight: FontWeight.bold),),
          content: StatefulBuilder(
            builder: (BuildContext context, StateSetter setState) {
              return Column(
                mainAxisSize: MainAxisSize.min,
                mainAxisAlignment: MainAxisAlignment.start,
                crossAxisAlignment: CrossAxisAlignment.start,
                children: [
                  RadioListTile<CompressionLevel>(
                    title: const Text('High'),
                    value: CompressionLevel.high,
                    groupValue: selectedLevel,
                    onChanged: (CompressionLevel? value) {
                      setState(() {
                        selectedLevel = value;
                      });
                    },
                  ),
                  RadioListTile<CompressionLevel>(
                    title: const Text('Medium'),
                    value: CompressionLevel.medium,
                    groupValue: selectedLevel,
                    onChanged: (CompressionLevel? value) {
                      setState(() {
                        selectedLevel = value;
                      });
                    },
                  ),
                  RadioListTile<CompressionLevel>(
                    title: const Text('Low'),
                    value: CompressionLevel.low,
                    groupValue: selectedLevel,
                    onChanged: (CompressionLevel? value) {
                      setState(() {
                        selectedLevel = value;
                      });
                    },
                  ),
                ],
              );
            },
          ),
          actions: <Widget>[
            TextButton(
              child: const Text('Cancel'),
              onPressed: () {
                Navigator.of(context).pop();
              },
            ),
            TextButton(
              child: const Text('OK'),
              onPressed: () {
                Navigator.of(context).pop();
                if (selectedLevel != null) {
                  _pickMedia(
                    isVideo: isVideo,
                    isAudio: false,
                    isRecording: false,
                    isStartRecording: false,
                    isNeedTimeStamp: isTimeStampNeeded,
                    isSourceCamera: isSourceCamera,
                    isCompressionRequired: true,
                    compressionLevel: selectedLevel,
                  );
                }
              },
            ),
          ],
        );
      },
    );
  }

}
3
likes
0
points
13
downloads

Publisher

unverified uploader

Weekly Downloads

A versatile Flutter package for picking and handling images, videos, and audio, with compression, timestamps, and recording features.

Homepage

License

unknown (license)

Dependencies

audioplayers, ffmpeg_kit_flutter, file_picker, flutter, flutter_image_compress, flutter_riverpod, image, image_picker, intl, path, path_provider, permission_handler, record, video_compress, video_player

More

Packages that depend on flutter_media_picker_pro