SoFunction
Updated on 2025-03-02

Example code for implementing video compression function in Flutter

Why does the Flutter application require video compression

In mobile applications, videos take up a lot of storage space and bandwidth. This affects the performance and user experience of the application to a certain extent. Therefore, in many applications we need to compress the video file to optimize its size and quality. By compressing video, the volume of video files can be effectively reduced, and the bandwidth required for video transmission and playback can be greatly reduced while ensuring picture quality. Video compression is also very important for Flutter applications.

Common video compression algorithms and formats

Video compression algorithms can be divided into two ways: lossy compression and lossless compression. Lossy compression is a way to compress video by discarding redundant data while ensuring visual quality. Conversely, lossless compression preserves all video data, but usually requires more storage space.

In practical applications, we often use the following video compression formats: H.264, HEVC, AV1, etc. Among them, H.264 is one of the most mainstream compression formats in mobile applications. It supports a wide range of support and has a relatively balanced file size and clarity. Taking the Flutter application as an example, we can use the FFmpeg library for video compression to support a variety of popular video compression formats. Next, we will explain how to use FFmpeg to compress videos of Flutter applications.

Compress videos in Flutter apps using the FFmpeg library

How to integrate the FFmpeg library in a Flutter application

To use FFmpeg for video compression, we first need to integrate the FFmpeg library into the Flutter application. Here are some basic operating steps:

  • Download the FFmpeg library from the official website of FFmpeg and unzip the file.
  • Add FFmpeg's gradle dependency to the Android directory of the Flutter application.
  • Add FFmpeg's pod dependency to the iOS directory of the Flutter application.
  • Initialize the required configuration and parameters when using the FFmpeg library in a Flutter application.

Here are some key code steps and tutorials for your reference:

1. Download and decompress the FFmpeg library

$ curl -LO /releases/ffmpeg-<version>.tar.bz2
$ tar jxvf ffmpeg-<version>.tar.bz2

Here you need to select the corresponding version you need to download.

2. Add FFmpeg's gradle dependency

In the application's android/app/ file, add the following dependencies:

repositories {
    jcenter()
}
dependencies {
    implementation ':mobile-ffmpeg-full:4.'
}

After using the above dependencies, we can use the FFmpeg library in our application.

3. Add FFmpeg pod dependencies in the iOS directory

In the application's ios/Podfile file, add the following dependencies:

target 'Runner' do
  use_frameworks!
  # Pods for Runner
  # Add the following line:
  pod 'MobileFFmpeg', '4.'
end

After adding a dependency, we can update our dependencies using CocoaPods:

cd ios
pod install

4. Initialize the FFmpeg library configuration and parameters

Before using FFmpeg for any operation, we need to initialize the basic configuration and parameters of the FFmpeg library through some settings. This step needs to be performed when starting the application and can be executed according to the following code:

import 'package:flutter_video_compress/flutter_video_compress.dart';
FlutterVideoCompress flutterVideoCompress = FlutterVideoCompress();
await ();
(LogLevel.AV_LOG_ERROR);
await ();

The above is the basic code for integrating the FFmpeg library in Flutter, which lays the necessary foundation for subsequent video compression operations. Next, we will introduce the basic video compression operation of the FFmpeg library.

Basic steps for video compression using FFmpeg library

Before we compress the video, we need to decode the video and re-encode it as required. This process requires the help of the FFmpeg library and complete the following steps:

  • Open the input file;
  • Decode the input file;
  • Perform required operations (such as compression, conversion, etc.);
  • Write the output after the operation to the output file;
  • Close the input file and the output file.
await ([
    '-y',
    '-i',
    'input.mp4',
    '-c:v',
    'libx264',
    '-crf',
    '18',
    '-preset',
    'superfast',
    '-c:a',
    'aac',
    '-b:a',
    '128k',
    '-strict',
    '-2',
    'output.mp4',
]);

In this example,input.mp4It is the file name we need to compress, by specifying-c:v libx264 -crf 18 -preset superfastThe video is compressed and-c:a aac -b:a 128kThe audio is encoded to ensure the quality of the audio and finally generate itoutput.mp4document.

This is the basic process of using FFmpeg for video compression. Next, we will explain in detail how to encapsulate the FFmpeg command in the Dart language.

Encapsulate the FFmpeg command using Dart language

When using the FFmpeg library for video compression in a Flutter application, we usually need to enter a large number of parameters to start the command execution. For easy operation, we often use the features of the Dart language to encapsulate the FFmpeg command.

Usually, we useMethod execution command:

import 'dart:convert';
import 'dart:io';
await Process
    .run('ffmpeg', ['-i', 'input.mp4', '-vf', 'scale=-1:360', '-c:v', 'libx264', '-preset', 'fast', '-crf', '23', '-ac', '1', '-ar', '44100', '-acodec', 'aac', 'output.mp4'])
    .then((ProcessResult result) {
      print('standard out:\n${}\n');
      print('standard in:\n${}\n');
      String message = ();
      if (('Cannot find ffmpeg')) {
        throw ('${()}');
      }
    });

In the above example, we useThe method executes the FFmpeg command,-i input.mp4Specify the file name to be compressed.-vf scale=-1:360Specify the size of the video frame to be 360.-c:v libx264 -preset fast -crf 23It is the video compression parameter.-ac 1 -ar 44100 -acodec aacIt is the audio encoding parameter, and we finally passoutput.mp4Output the compressed video file.

However, for cases where similar operations are performed multiple times, we do not want to enter a long list of command parameters each time. At this time, we can use classes in the Dart language to encapsulate the FFmpeg command for easy testing and reuse.

In the following example, we encapsulate the basic FFmpeg command inFFmpegCommandsin the class and passtoCommandThe method converts the parameters to a command line command:

class FFmpegCommands {
  String _inputPath;
  String _outputPath;
  List<String> _videoFilters;
  List<String> _audioFilters;
  String _crf;
  String _bitrate;
  FFmpegCommands({
    @required String inputPath,
    @required String outputPath,
    List<String> videoFilters,
    List<String> audioFilters,
    String crf = '23',
    String bitrate = '1024k',
  })  : assert(inputPath != null),
        assert(outputPath != null) {
    this._inputPath = inputPath;
    this._outputPath = outputPath;
    this._videoFilters = videoFilters;
    this._audioFilters = audioFilters;
    this._crf = crf;
    this._bitrate = bitrate;
  }
  String toCommand() {
    List<String> commands = [];
    ([
      'ffmpeg',
      '-i',
      this._inputPath,
    ]);
    if (this._videoFilters != null) {
      (['-vf', this._videoFilters.join(',')]);
    }
    if (this._crf != null) {
      (['-crf', this._crf]);
    }
    if (this._bitrate != null) {
      (['-b:a', this._bitrate]);
    }
    (['-y', this._outputPath]);
    return (' ');
  }
}

Using the FFmpeg command to encapsulate classes will not change the final operation, but can improve reuse and maintainability. Below, we use an example to show how to use it for video compression.

void main() async {
  FFmpegCommands ffmpegCommands = FFmpegCommands(
    inputPath: 'input.mp4',
    outputPath: 'output.mp4',
    videoFilters: ['scale=-1:360'],
    crf: '23',
    bitrate: '1024k',
  );
  await Process
      .run((), [])
      .then((ProcessResult result) {
        print();
        print();
      });
}

In the above example, we first construct aFFmpegCommandsObject, which contains all parameters, then pass()The method generates an executable command line command, and finally passesMethod performs compression.

The above is how to encapsulate the FFmpeg command using the Dart language. Next, we will combine examples to explain how to use the FFmpeg library for video compression in a Flutter application.

Best practices for video compression in Flutter apps

We will introduce best practices for video compression using the FFmpeg library in a Flutter application through examples.

Choose the most suitable video compression algorithm and format

In practical applications, we choose the most suitable compression algorithm and format based on the needs of video compression.

Size compression: For the need to compress the video size, you can use thescaleFilters to change the resolution of the video, thereby reducing the size of the video file, for example:

String command = 'ffmpeg -i input.mp4 -vf scale=-1:360 output.mp4';

Video encoding and compression: On the premise of ensuring video quality, you can choose the encoding format of the compressed video, such as using H.264 or HEVC.

Audio encoding compression: Selecting the appropriate audio encoding format can also reduce the video file size.

Taking into account the needs comprehensively, we need to make choices based on actual conditions.

Configure the FFmpeg tool for compression

After selecting the appropriate compression algorithm and format, you can use the FFmpeg tool to compress.

String command = 'ffmpeg -i input.mp4 -c:v libx264 -crf 23 -preset fast -c:a aac -b:a 128k output.mp4';
await (command, []);

Before executing the command, we need to make sure that we have integrated the FFmpeg library as described earlier. In addition, depending on specific needs, we can pass different parameters to achieve compression of different effects.

For example, if we want to preserve the video's aspect ratio during compression, we can change the compression command to:

String command = 'ffmpeg -i input.mp4 -c:v libx264 -filter:v "scale=-1:360:force_original_aspect_ratio=decrease,pad=360:360:(ow-iw)/2:(oh-ih)/2" -crf 23 -preset fast -c:a aac -b:a 128k output.mp4';

Used herepadFilters to maintain the aspect ratio while usingforce_original_aspect_ratio=decreaseEnsure that the video aspect ratio remains unchanged.

Encapsulate the FFmpeg command using Dart language

Encapsulating the FFmpeg command with the Dart language allows us to better combine and maintain parameters. The following is an example of using the FFmpeg command to encapsulate the class for video compression:

class FFmpegCommands {
  String _inputPath;
  String _outputPath;
  List<String> _videoFilters;
  List<String> _audioFilters;
  String _crf;
  String _bitrate;
  FFmpegCommands({
    @required String inputPath,
    @required String outputPath,
    List<String> videoFilters,
    List<String> audioFilters,
    String crf = '23',
    String bitrate = '1024k',
  })  : assert(inputPath != null),
        assert(outputPath != null) {
    this._inputPath = inputPath;
    this._outputPath = outputPath;
    this._videoFilters = videoFilters;
    this._audioFilters = audioFilters;
    this._crf = crf;
    this._bitrate = bitrate;
  }
  String toCommand() {
    List<String> commands = [];
    ([
      'ffmpeg',
      '-i',
      this._inputPath,
    ]);
    if (this._videoFilters != null) {
      (['-vf', this._videoFilters.join(',')]);
    }
    if (this._crf != null) {
      (['-crf', this._crf]);
    }
    if (this._bitrate != null) {
      (['-b:a', this._bitrate]);
    }
    (['-y', this._outputPath]);
    return (' ');
  }
}
void main() async {
  FFmpegCommands ffmpegCommands = FFmpegCommands(
    inputPath: 'input.mp4',
    outputPath: 'output.mp4',
    videoFilters: ['scale=-1:360', 'pad=360:360:(ow-iw)/2:(oh-ih)/2:color=black'],
    crf: '23',
    bitrate: '1024k',
  );
  await Process
      .run((), [])
      .then((ProcessResult result) {
        print();
        print();
      });
}

In the above example, we first defineFFmpegCommandsclass, then construct an object to specify the parameters of the FFmpeg command, and finally passtoCommandThe method generates an executable command line command and passesMethods perform video compression. During the entire process, we can freely set the parameters in the FFmpeg command to achieve different video compression effects.

Implement updates and callbacks of video compression progress

During video compression, we usually want to be able to display the compression progress in real time and provide a progress bar for users to observe the operation progress. To achieve this, we can update the compression progress by listening to the output stream of the FFmpeg tool.

Here is a sample code for implementing video compression progress updates and callbacks:

class VideoCompressUtil {
  static final FlutterVideoCompress _flutterVideoCompress = FlutterVideoCompress();
  static StreamSubscription _subscription;
  static int _prevProgress;
  static Future<void> compressVideo({
    @required String inputPath,
    @required String outputPath,
    List<String> videoFilters,
    List<String> audioFilters,
    String crf = '23',
    String bitrate = '1024k',
    Function(int) onProgress,
  }) async {
    if (_subscription != null) {
      throw 'Another FFmpeg compression is already in progress.';
    }
    int totalDuration = await _flutterVideoCompress.getMediaInformation(inputPath: inputPath).then((info) => info
        .duration
        .inMilliseconds);
    int previousPercent = 0;
    final Completer completer = Completer();
    FFmpegCommands cmd = FFmpegCommands(
      inputPath: inputPath,
      outputPath: outputPath,
      videoFilters: videoFilters,
      audioFilters: audioFilters,
      crf: crf,
      bitrate: bitrate,
    );
    String command = ();
    print(command);
    _prevProgress = 0;
    _subscription = _flutterVideoCompress.pipe(command).listen((RetrieveData stdout) async {
      String data = ();
      if (('frame=')) {
        String progressString = ('frame=')[1].split('fps=')[0].trim();
        int progress = (progressString);
        if (previousPercent != ((progress * 100) ~/ totalDuration)) {
          previousPercent = ((progress * 100) ~/ totalDuration);
          onProgress(previousPercent);
        }
      }
      if (('Stream mapping')) {
        _prevProgress = null;
      }
      if (('size=')) {
        String durString = ("Duration:")[1].split(",")[0].trim();
        Duration duration = Duration(
            hours: ((":")[0]),
            minutes: ((":")[1]),
            seconds: ((":")[2].split(".")[0]),
            milliseconds: ((":")[2].split(".")[1]));
        int totalDuration = ;
        double _progress = 0;
        RegExp timeRegExp = new RegExp(r"(?:(\d+):)?(\d{2}):(\d{2})\.(\d{1,3})");
        String lastMatch;
        ('\n').forEach((line) {
          lastMatch = line;
          if (('time=')) {
            final match = (line).elementAt(0);
            final hours = (1) != null ? ((1)) : 0;
            final minutes = ((2));
            final seconds = ((3));
            final videoDurationInSeconds = (hours * 3600) + (minutes * 60) + seconds;
            _progress = (videoDurationInSeconds / totalDuration) * 100;
            if ((_progress - _prevProgress).abs()>= 1.0) {
              _prevProgress = _progress.toInt();
              onProgress(_prevProgress);
            }
          }
        });
        ();
      }
      // Output FFmpeg log to console.
      print(data);
    });
    await ;
    await _subscription.cancel();
    _subscription = null;
    _prevProgress = 0;
  }
}

In the above code, we defineVideoCompressUtilclass, through internalFFmpegCommandsThe class encapsulates the FFmpeg command and listens to the FFmpeg tool output stream to implement updates and callbacks to video compression progress. During the compression process, we passonProgressParameters to achieve real-time update of compression progress.

Summarize

This article introduces methods to use Flutter to develop video compression functions, including integrating the FFmpeg library, using the FFmpeg command for video compression, encapsulating the FFmpeg command and implementing compression progress updates and callbacks.

In actual development, video compression is a commonly used technology. By mastering the methods and techniques described in this article, we can easily implement the video compression function and allow users to better experience the functions and services of the application. Brothers, please try it out quickly.

The above is the detailed content of the sample code for Flutter to implement video compression. For more information about Flutter video compression, please follow my other related articles!