Flutter video compress - Generate a new file by compressed video, and provide metadata. Get video thumbnail from a video path, supports JPEG/GIF. To reduce app size not using FFmpeg in IOS.

Last update: Jul 16, 2022

flutter_video_compress

Generate a new path by compressed video, Choose to keep the source video or delete it by a parameter. Get video thumbnail from a video path and provide video information. Easy to deal with compressed video. Considering reduce application size is not using FFmpeg in IOS.

pub version license android min Sdk Version ios min target

flutter compress video

languages

English 简体中文 日本語

Usage

Installing add flutter_video_compress as a dependency in your pubspec.yaml file.

dependencies:
  flutter_video_compress: ^0.3.x

Create an instance

final _flutterVideoCompress = FlutterVideoCompress();

Get thumbnail from video path

final uint8list = await _flutterVideoCompress.getThumbnail(
  file.path,
  quality: 50, // default(100)
  position: -1 // default(-1)
);

Get thumbnail file from video path

final thumbnailFile = await _flutterVideoCompress.getThumbnailWithFile(
  file.path,
  quality: 50, // default(100)
  position: -1 // default(-1)
);

Convert video to a gif

final file = await _flutterVideoCompress.convertVideoToGif(
  videoFile.path,
  startTime: 0, // default(0)
  duration: 5, // default(-1)
  // endTime: -1 // default(-1)
);
debugPrint(file.path);

Get media information

only support video now.

final info = await _flutterVideoCompress.getMediaInfo(file.path);
debugPrint(info.toJson().toString());

Compression Video

Compatible with IOS, Android and Web after compression.

final info = await _flutterVideoCompress.compressVideo(
  file.path,
  quality: VideoQuality.DefaultQuality, // default(VideoQuality.DefaultQuality)
  deleteOrigin: false, // default(false)
);
debugPrint(info.toJson().toString());

Check Compressing state

_flutterVideoCompress.isCompressing

Stop compression

Will print InterruptedException in android, but not affect to use.

await _flutterVideoCompress.cancelCompression()

delete all cache files

Delete all files generated by this will delete all files located at 'flutter_video_compress', you shoule ought to know what are you doing.

await _flutterVideoCompress.deleteAllCache()

Subscribe the compression progress steam

class ... extends State<MyApp> {
  Subscription _subscription;

  @override
  void initState() {
    super.initState();
    _subscription =
        _flutterVideoCompress.compressProgress$.subscribe((progress) {
      debugPrint('progress: $progress');
    });
  }

  @override
  void dispose() {
    super.dispose();
    _subscription.unsubscribe();
  }
}

Methods

Functions Parameters Description Returns
getThumbnail String path[video path], int quality(1-100)[thumbnail quality], int position[Get a thumbnail from video position] get thumbnail from video path Future<Uint8List>
getThumbnailWithFile String path[video path], int quality(1-100)[thumbnail quality], int position[Get a thumbnail from video position] get thumbnail file from video path Future<File>
convertVideoToGif String path[video path], int startTime(from 0 start)[convert video to gif start time], int endTime[convert video to gif end time], int duration[convert video to gif duration from start time] convert video to gif from video path Future<File>
getMediaInfo String path[video path] get media information from video path Future<MediaInfo>
compressVideo String path[video path], VideoQuality quality[compressed video quality], bool deleteOrigin[delete the origin video], int startTime[compression video start time], int duration[compression video duration from start time], bool includeAudio[is include audio in compressed video], int frameRate[compressed video frame rate] compression video at origin video path Future<MediaInfo>
cancelCompression none cancel compressing Future<void>
deleteAllCache none Delete all files generated by 'flutter_video_compress' will delete all files located at 'flutter_video_compress' Future<bool>

Subscriptions

Subscriptions Description Stream
compressProgress$ Subscribe the compression progress steam double progress

Notice

If your application is significantly larger after using the plugin, you can reduce the application size in the following way:

  • exclude x86 related files (./assets)

  • This library not use ffprobe, only used ffmpeg, but the application still has ffprobe, so you will need to exclude (asssets/arm or assets/x86)

add this config in build.gradle:

  • Don't use ignoreAssetsPattern "!x86" in debug mode, will crash on the simulator
android {
 ...
 // Reduce your application size with this configuration
 aaptOptions {
     ignoreAssetsPattern "!x86:!*ffprobe"
 }
 
 buildTypes {
 ...
}

look detail

Questions

If your application is not enabled AndroidX, you will need to add the following code to the last line of the android/build.gradle file.

rootProject.allprojects {
    subprojects {
        project.configurations.all {
            resolutionStrategy.eachDependency { details ->
                if (details.requested.group == 'androidx.core' && !details.requested.name.contains('androidx')) {
                    details.useVersion "1.0.1"
                }
            }
        }
    }
}

If your application not support swift, you need to add the following code in ios/Podfile.

target 'Runner' do
  use_frameworks! # <--- add this
  ...
end

look detail

If your application never used a swift plugin before, maybe you would meet the error, you need to add the following code in ios/Podfile.

The 'Pods-Runner' target has transitive dependencies that include static binaries

pre_install do |installer|
  # workaround for https://github.com/CocoaPods/CocoaPods/issues/3289
  Pod::Installer::Xcode::TargetValidator.send(:define_method, :verify_no_static_framework_transitive_dependencies) {}
end

If the above method not work, you report bug of the error repository. The reason is「can't support swift」

look detail

if show error of Regift

  • Regift does not specify a Swift version and none of the targets (Runner) integrating it have the SWIFT_VERSION attribute set. Please contact the author or set the SWIFT_VERSION attribute in at least one of the targets that integrate this pod.
pre_install do |installer|
  installer.analysis_result.specifications.each do |s|
      if s.name == 'Regift'
        s.swift_version = '4.0'
      end
  end
end

post_install do |installer|
  installer.pods_project.targets.each do |target|
    target.build_configurations.each do |config|
      config.build_settings['ENABLE_BITCODE'] = 'NO'
    end
  end
end

Contribute

Contributions are always welcome!

GitHub

https://github.com/TenkaiRuri/flutter_video_compress
Comments
  • 1. Remove videoToGif and instead add creating a short video without sound

    Description

    Since Gif is lossless format, gifs made from video have are bigger in size than short videos without audio. Also, there is a problem with Regift library since it is targeting iOS 11.1. My suggestion is to remove videoToGif and add a couple of optional parameters to startCompression for creating video preview.

    Platform

    Both

    Code Example (if has)

    void main() {
         _flutterVideoCompress.startCompress(
              file.path,
              deleteOrigin: true,
              quality: VideoQuality.LowQuality,
              startTime: 0,
              duration: 5,
              includeAudio: false,
              frameRate: 24,
            );
    }
    

    Expected solution

    I will implement this by adding parameters to this method if @TenkaiRuri agrees?

    Reviewed by vlada3003 at 2019-06-19 12:47
  • 2. [Bug] Cannot run example on iOS with swift version 4.2.1

    Description

    My Swift version:

    Apple Swift version 4.2.1 (swiftlang-1000.11.42 clang-1000.11.45.1)
    Target: x86_64-apple-darwin18.6.0
    

    Unable to run the example. The error says:

    Launching lib/main.dart on iPhone XR in debug mode...
    Xcode build done.                                            1.7s
    Failed to build iOS app
    Error output from Xcode build:
    ↳
        ** BUILD FAILED **
    Xcode's output:
    ↳
        === BUILD TARGET video_player OF PROJECT Pods WITH CONFIGURATION Debug ===
        The “Swift Language Version” (SWIFT_VERSION) build setting must be set to a supported value for targets which use Swift. Supported values are: 3.0, 4.0, 4.2. This setting can be set in the build settings editor.
    Could not build the application for the simulator.
    Error launching application on iPhone XR.
    Exited (sigterm)
    

    Platform

    iOS

    Backtracking step

    1. clone this repo https://github.com/rurico/flutter_video_compress.git
    2. cd flutter_video_compress/example/
    3. flutter packages get
    4. flutter run

    Expected solution

    Does the plugin support swift 4.2?

    Reviewed by VictorUvarov at 2019-07-08 15:35
  • 3. [Help/Performance] Video compressing taking too long

    Description

    I need to take a video from camera/gallery, compress it (lower resolution or quality or width/height) and upload to firebase storage so I can download it later and show it on a VideoPlayer on a ListView.

    Platform

    Android

    Using

    Latest Image Picker

    Expected solution

    I did some tests and the compressing is taking around 1 minute for each video second: A 5 seconds video needs ~5 minutes to compress; A 12 seconds video needs ~12 minutes to compress.

    Is there an easy way to improve performance of compressing? Like using an Isolate or something like.

    Which is the best approach for that? Should I start compressing right after picking video to save time? Should I use camera plugin instead of image picker for taking videos?

    My goal is to make an Instagram-like social network so it can't take so long to upload a small video.

    Reviewed by GustavoContreiras at 2019-06-18 16:12
  • 4. Compressing seems to never stop

    When compressing a second video after compressing the first one, I get following Error:

    Already have a compression process, you need to wait for the process to finish

    It seems that the compression process of the first video is still in progress. Does it not stop automatically? Do I need to stop it manually by calling _stopCompress() ?

    Thanks for your help!

    Reviewed by kamami at 2019-05-23 10:08
  • 5. Return file instead of path

    Hi, I need to upload the compressed video to firebase. Any possability to return the compressed file instead of the path?

    Good job btw. with the widget!

    Reviewed by kamami at 2019-05-19 18:23
  • 6. Compression hangs

    Hi Im having trouble getting a video to compress after I have already compressed one. I compress one video and it works fine but the second seems to hang and never returns from the await. I'm doing it like this

    final String newPath = await _flutterVideoCompress.compressVideo(path: file.path, deleteOrigin: true);

    Would you please be able to help me

    Thanks Jawad

    Reviewed by jawadt1 at 2019-05-05 14:26
  • 7. [Bug] this happens when I subscribe to compressor

    Code Example (if has)

    void main() {
    final _flutterVideoCompress = FlutterVideoCompress();
                _conpressSubscription = _flutterVideoCompress.compressProgress$.subscribe((progress) {
                      debugPrint('progress: $progress');
                    });
                File myFile = _file;
                debugPrint(_file.lengthSync().toString());
                final info = await _flutterVideoCompress.getMediaInfo(_file.path);
                print(info.toJson());
                if (info.duration > 120 || _file.lengthSync() > 5000000) {
                  Fluttertoast.showToast(msg: 'در حال کم کردن حجم....');
                  VideoQuality quality = VideoQuality.HighestQuality;
                  if (_file.lengthSync() > 5000000) {
                    quality = VideoQuality.MediumQuality;
                  }
                  final info2 = await _flutterVideoCompress.compressVideo(
                    _file.path,
                    startTime: 0,
                    duration: 120,
                    quality: quality, // default(VideoQuality.DefaultQuality)
                    deleteOrigin: false, // default(false)
                  );
                  debugPrint(info2.toJson().toString());
                  myFile = info2.file;
                }
    }
    

    this is the log : I/flutter ( 6520): progress: 0.0 I/flutter ( 6520): progress: 0.0 I/flutter ( 6520): progress: 0.0 I/flutter ( 6520): progress: 0.0 I/flutter ( 6520): progress: 0.0 I/flutter ( 6520): progress: 0.0 I/flutter ( 6520): progress: 0.0 I/flutter ( 6520): progress: 0.0 I/flutter ( 6520): progress: 0.0 I/flutter ( 6520): progress: 0.0 I/flutter ( 6520): progress: 0.0 I/flutter ( 6520): progress: 0.0 I/flutter ( 6520): progress: 0.0 I/flutter ( 6520): progress: 0.0 I/flutter ( 6520): progress: 0.0 I/flutter ( 6520): progress: 0.0 I/flutter ( 6520): progress: 0.0 I/flutter ( 6520): progress: 0.0 I/flutter ( 6520): progress: 0.0 I/flutter ( 6520): progress: 0.0 I/flutter ( 6520): progress: 0.0 I/flutter ( 6520): {path: /storage/emulated/0/Android/data/netonote.ir.netonote/files/flutter_video_compress/VID_20191221_010843_056.mp4, title: , author: , width: 2700, ......

    Reviewed by sepehr13494 at 2020-01-19 15:01
  • 8. [Bug]编译iOS的时候报The 'Pods-Runner' target has transitive dependencies that include statically linked binaries

    编译iOS的时候报: [!] The 'Pods-Runner' target has transitive dependencies that include statically linked binaries: (/Users/siwen/MyProject/viiapp/ios/Pods/AlipaySDK-iOS/AlipaySDK.framework, /Users/siwen/MyProject/viiapp/ios/Pods/UMCAnalytics/UMAnalytics.framework, and /Users/siwen/MyProject/viiapp/ios/Pods/UMCCommon/UMCommon.framework)

    请问如何解决?感谢

    Reviewed by goodsiwen at 2019-07-03 04:31
  • 9. [Bug] Pod install problems with latest version

    Description

    Build breaks when use_frameworks! is added to a Podfile. When a library that has s.static_framework = true is added to a project that has flutter_video_compress, '$pod install' fails with a message "[!] The 'Pods-Runner' target has transitive dependencies that include statically linked binaries: (image_cropper)" image_cropper is a library that has s.static_framework = true if use_frameworks! isn't set then Regift won't compile.

    Platform

    IOS

    Proposed solution

    Is to fork Regift and to reduce the ios minimum supported version and remove the use_frameworks! flag. However, this is just a guess since I'm unfamiliar with iOS build system.

    Reviewed by vlada3003 at 2019-06-21 14:14
  • 10. compressed video is null

    I am trying to compress a video file and return the new compressed file, but following code prints NULL both times:

       final MediaInfo newPath = await _flutterVideoCompress.startCompress(
        widget.videoFile.path,
        deleteOrigin: true,
      );
    
      setState(() {
        video = newPath.file;
      });
    
       print("${newPath.file}");
       print("$video");
    
    Reviewed by kamami at 2019-05-23 14:01
  • 11. [Suggestion] Rename methods

    I saw that you owners are not americans and maybe thats the reason the methods don't have a intuitive name.

    My suggestions for rename: startCompress -> compressVideo convertVideoToGif -> compressVideoToGif stopCompress -> cancelCompress getThumbnail -> getThumbnailBytesList getThumbnailWithFile -> getThumbnail

    Reviewed by GustavoContreiras at 2019-06-21 16:20
  • 12. [Bug] Compress tiktok downloaded video

    Description

    When im trying to compress tiktok downloaded video the default size 7mb after the compressing done the compressed video has size 22 mb.

    Platform

    IOS|Android|Both|Other

    Reviewed by mcleaw at 2022-08-09 09:06
  • 13. [Feature]flutter_video_compress uses a deprecated version of the Android embedding

    Description

    While building under Flutter v2.10.*, there's a warning below, please take care, thanks in advance!

    The plugin `flutter_video_compress` uses a deprecated version of the Android embedding.
    To avoid unexpected runtime failures, or future build failures, try to see if this plugin supports the Android V2 embedding.
    Otherwise, consider removing it since a future release of Flutter will remove these deprecated APIs.
    If you are plugin author, take a look at the docs for migrating the plugin to the V2 embedding:
    https://flutter.dev/go/android-plugin-migration.
    

    Platform

    Android

    Code Example (if has)

    flutter build apk
    

    Expected solution

    Improvement.

    Reviewed by michael-towify at 2022-03-01 08:30
  • 14. Null Safety

    Description

    Thanks, I'm currently using it and everything is fine, but I want to go to null safety. When will it go to null safety? are there plans for that in the future?

    Platform

    IOS|Android|

    Code Example (if has)

    Expected solution

    Reviewed by davidisraelgc at 2021-05-17 19:13
  • 15. [help]Video compression can not get compression progress 【flutter_video_compress: ^0.3.7+8】

    Description

    Video compression can not get compression progress

    微信截图_20210502234246

    Platform

    Android

    Code Example (if has)

    import 'dart:async'; import 'dart:io';

    import 'package:flutter/material.dart'; import 'package:flutter/widgets.dart'; import 'package:flutter_video_compress/flutter_video_compress.dart'; import 'package:image_pickers/image_pickers.dart';

    class TestVideoPage extends StatefulWidget {

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

    class _TestVideoPageState extends State {

    final _flutterVideoCompress = FlutterVideoCompress(); Subscription _subscription;

    Image _thumbnailFileImage; Image _gifFileImage;

    MediaInfo _originalVideoInfo = MediaInfo(path: ''); MediaInfo _compressedVideoInfo = MediaInfo(path: ''); String _taskName; double _progressState = 0;

    final _loadingStreamCtrl = StreamController.broadcast();

    @override void initState() { // TODO: implement initState super.initState(); _subscription = _flutterVideoCompress.compressProgress$.subscribe((progress) { debugPrint("progress----" + progress.toString()); setState(() { _progressState = progress; }); }); }

    @override void dispose() { super.dispose(); _subscription.unsubscribe(); _loadingStreamCtrl.close(); }

    Future runFlutterVideoCompressMethods(String videoFile) async { _loadingStreamCtrl.sink.add(true);

    var _startDateTime = DateTime.now();
    print('[Compressing Video] start');
    _taskName = '[Compressing Video]';
    final compressedVideoInfo = await _flutterVideoCompress.compressVideo(
      videoFile,
      quality: VideoQuality.DefaultQuality,
      deleteOrigin: false,
    );
    _taskName = null;
    print(
        '[Compressing Video] done! ${DateTime
            .now()
            .difference(_startDateTime)
            .inSeconds}s');
    
    _startDateTime = DateTime.now();
    
    print('[Getting Thumbnail File] start');
    final thumbnailFile = await _flutterVideoCompress
        .getThumbnailWithFile(videoFile, quality: 50);
    print(
        '[Getting Thumbnail File] done! ${DateTime
            .now()
            .difference(_startDateTime)
            .inSeconds}s');
    
    _startDateTime = DateTime.now();
    print('[Getting Gif File] start');
    _taskName = '[Getting Gif File]';
    final gifFile = await _flutterVideoCompress
        .convertVideoToGif(videoFile, startTime: 0, duration: 5);
    print(
        '[Getting Gif File] done! ${DateTime
            .now()
            .difference(_startDateTime)
            .inSeconds}s');
    _taskName = null;
    
    final videoInfo = await _flutterVideoCompress.getMediaInfo(videoFile);
    
    setState(() {
      _thumbnailFileImage = Image.file(thumbnailFile);
      _gifFileImage = Image.file(gifFile);
      _originalVideoInfo = videoInfo;
      _compressedVideoInfo = compressedVideoInfo;
    });
    _loadingStreamCtrl.sink.add(false);
    

    }

    @override Widget build(BuildContext context) { return Scaffold( body: Center( child: OutlinedButton( onPressed: () async { List _listVideoPaths = await ImagePickers.pickerPaths( galleryMode: GalleryMode.video, selectCount: 1, ); runFlutterVideoCompressMethods(_listVideoPaths[0].path); }, child: Text("选择视频"), ), ), ); } }

    Expected solution

    Expect description of the solution

    Reviewed by lswd at 2021-05-02 15:43

Related

Esizer - A Flutter package provide responsive, dynamic, configurable size for each device screen size
Esizer - A Flutter package provide responsive, dynamic, configurable size for each device screen size

ESizer A Flutter package provide responsive, dynamic, configurable size for each

Feb 15, 2022
Gif image widget help to controll gif progress,speed,repeat frames
Gif image widget help to controll gif progress,speed,repeat frames

We should know that in order to achieve Gif in flutter, we can use Image, but we have no way to manipulate Gif, for example: change its speed, control it has been playing in a frame, in which frame range loop. These problems can be solved by this widget,it also help you contain gif cache,avoid load frame every time.

Jun 4, 2022
Cross-platform flutter plugin for reading and writing NFC tags. Not maintained anymore - not looking for new maintainer, fork instead.
Cross-platform flutter plugin for reading and writing NFC tags. Not maintained anymore - not looking for new maintainer, fork instead.

nfc_in_flutter NFC in Flutter is a plugin for reading and writing NFC tags in Flutter. It works on both Android and iOS with a simple stream interface

Jul 18, 2022
A Flutter plugin to read 🔖 metadata of 🎵 media files. Supports Windows, Linux & Android.
A Flutter plugin to read 🔖 metadata of 🎵 media files. Supports Windows, Linux & Android.

flutter_media_metadata A Flutter plugin to read metadata of media files. A part of Harmonoid open source project ?? Install Add in your pubspec.yaml.

Aug 17, 2022
An image compress package like Luban for Dart
An image compress package like Luban for Dart

flutter_luban An image compress package like Luban for Dart, based on image.This library has no system platform constraints. Example CompressObject

Aug 8, 2022
Automatically generate profile picture with random first name and background color. But you can still provide pictures if you have them. As the default color, based on the name of the first letter. :fire: :fire: :fire:
Automatically generate profile picture with random first name and background color. But you can still provide pictures if you have them. As the default color, based on the name of the first letter. :fire: :fire: :fire:

FLUTTER PROFILE PICTURE Automatically generate profile picture with random first name and background color. But you can still provide pictures if you

May 3, 2022
A widget based on Flutter's new Interactive Viewer that makes picture pinch zoom, and return to its initial size and position when released.
A widget based on Flutter's new Interactive Viewer that makes picture pinch zoom, and return to its initial size and position when released.

pinch_zoom A widget based on Flutter's new Interactive Viewer that makes picture pinch zoom, and return to its initial size and position when released

May 11, 2022
System info plus - A Flutter plugin to get device Random Access Memory (RAM) size

system_info_plus A Flutter plugin to get device Random Access Memory (RAM) size.

Jan 10, 2022
A Video Player For Vimeo Videos in Flutter. This plugin allows us to play video from Vimeo and it supports Android and iOS platforms.
A Video Player For Vimeo Videos in Flutter. This plugin allows us to play video from Vimeo and it supports Android and iOS platforms.

vimeo_video_player A Video Player For Vimeo Videos in Flutter. This plugin allow us to play video from vimeo and it's supports Android and iOS platfor

Jul 17, 2022
Given a JSON string, this library will generate all the necessary Dart classes to parse and generate JSON.

JSON to Dart Given a JSON string, this library will generate all the necessary Dart classes to parse and generate JSON. This library is designed to ge

Aug 17, 2022
Aves is a gallery and metadata explorer app, built for Android with Flutter.
Aves is a gallery and metadata explorer app, built for Android with Flutter.

Aves Aves is a gallery and metadata explorer app. It is built for Android, with Flutter. Features Aves can handle all sorts of images and videos, incl

Aug 10, 2022
changelog.dart provides a library and a command-line application to manage in the correct way the git metadata to build the changelog between two release
changelog.dart provides a library and a command-line application to manage in the correct way the git metadata to build the changelog between two release

changelog.dart ?? changelog.dart: a collection of tools to manages in a fashion way a repository as maintainer. ?? Project Homepage Table of Content I

Apr 2, 2022
Datacollection - This will help to generate the data collection in *.g.dart file from api response

datacollection this will help to generate the data collection in *.g.dart file f

Feb 5, 2022
A simple flutter app that downloads a file from the internet, shows a custom-made download progress dialog and saves the file to device's internal storage

http_downloader A simple flutter app that downloads a file from the internet using the http plugin. It has a custom-designed progress dialog which dis

Apr 6, 2021
Flutter file based routing - File based routing and nested layouts for Flutter

Flutter File Based Routing I was inspired by the routing in remix.run with neste

Jul 8, 2022
Add easily to your app an introduction screen to provide informations to new users

IntroductionScreen Introduction screen allow you to have a screen at launcher for example, where you can explain your app. This Widget is very customi

Aug 12, 2022
A powerful Http client for Dart, which supports Interceptors, FormData, Request Cancellation, File Downloading, Timeout etc.

dio_http A powerful Http client for Dart, which supports Interceptors, Global configuration, FormData, Request Cancellation, File downloading, Timeout

Dec 19, 2021