flutter_video_compress 0.3.7+8 copy "flutter_video_compress: ^0.3.7+8" to clipboard
flutter_video_compress: ^0.3.7+8 copied to clipboard

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.

example/lib/main.dart

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

import 'package:flutter/material.dart';
import 'package:flutter_video_compress/flutter_video_compress.dart';
import 'package:image_picker/image_picker.dart' show ImagePicker, ImageSource;
import 'package:video_player/video_player.dart';
import 'my-theme.dart';

void main() => runApp(MyApp(title: 'Flutter Video Compress Example'));

class MyApp extends StatefulWidget {
  MyApp({this.title});

  final String title;

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

class _MyAppState extends State<MyApp> {
  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<bool>.broadcast();

  @override
  void initState() {
    super.initState();
    _subscription =
        _flutterVideoCompress.compressProgress$.subscribe((progress) {
      setState(() {
        _progressState = progress;
      });
    });
  }

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

  Future<void> runFlutterVideoCompressMethods(File videoFile) async {
    _loadingStreamCtrl.sink.add(true);

    var _startDateTime = DateTime.now();
    print('[Compressing Video] start');
    _taskName = '[Compressing Video]';
    final compressedVideoInfo = await _flutterVideoCompress.compressVideo(
      videoFile.path,
      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.path, 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.path, startTime: 0, duration: 5);
    print(
        '[Getting Gif File] done! ${DateTime.now().difference(_startDateTime).inSeconds}s');
    _taskName = null;

    final videoInfo = await _flutterVideoCompress.getMediaInfo(videoFile.path);

    setState(() {
      _thumbnailFileImage = Image.file(thumbnailFile);
      _gifFileImage = Image.file(gifFile);
      _originalVideoInfo = videoInfo;
      _compressedVideoInfo = compressedVideoInfo;
    });
    _loadingStreamCtrl.sink.add(false);
  }

  Widget _buildMaterialWarp(Widget body) {
    return MaterialApp(
      title: widget.title,
      theme: myTheme,
      home: Scaffold(
          appBar: AppBar(
            title: Text(widget.title),
            actions: <Widget>[
              IconButton(
                onPressed: () async {
                  await _flutterVideoCompress.deleteAllCache();
                },
                icon: Icon(Icons.delete_forever),
              ),
            ],
          ),
          body: body),
    );
  }

  Widget _buildRoundedRectangleButton(String text, ImageSource source) {
    return Padding(
      padding: const EdgeInsets.symmetric(horizontal: 32),
      child: RaisedButton(
        shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(30)),
        child: Text(text, style: TextStyle(color: Colors.white)),
        color: Colors.grey[800],
        onPressed: () async {
          final videoFile = await ImagePicker.pickVideo(source: source);
          if (videoFile != null) {
            runFlutterVideoCompressMethods(videoFile);
          }
        },
      ),
    );
  }

  String _infoConvert(MediaInfo info) {
    return 'path: ${info.path}\n'
        'duration: ${info.duration} microseconds\n'
        'size: ${info.filesize} bytes\n'
        'size: ${info.width} x ${info.height}\n'
        'orientation: ${info.orientation}°\n'
        'compression cancelled: ${info.isCancel}\n'
        'author: ${info.author}';
  }

  List<Widget> _buildInfoPanel(String title,
      {MediaInfo info, Image image, bool isVideoModel = false}) {
    if (info?.file == null && image == null && !isVideoModel) return [];
    return [
      if (!isVideoModel || info?.file != null)
        Card(
          child: ListTile(
            title: Text(title),
            dense: true,
          ),
        ),
      if (info?.file != null)
        Padding(
          padding: const EdgeInsets.all(8),
          child: Text(_infoConvert(info)),
        ),
      if (image != null) image,
      if (isVideoModel && info?.file != null) VideoPlayerView(file: info.file)
    ];
  }

  @override
  Widget build(context) {
    return _buildMaterialWarp(
      Stack(children: <Widget>[
        ListView(
          children: <Widget>[
            const SizedBox(height: 20),
            _buildRoundedRectangleButton(
              'Take video from camera with Image Picker',
              ImageSource.camera,
            ),
            _buildRoundedRectangleButton(
              'Take video from gallery with Image Picker',
              ImageSource.gallery,
            ),
            ..._buildInfoPanel(
              'Original video information',
              info: _originalVideoInfo,
            ),
            ..._buildInfoPanel(
              'Original video view',
              info: _originalVideoInfo,
              isVideoModel: true,
            ),
            ..._buildInfoPanel(
              'Compressed video information',
              info: _compressedVideoInfo,
            ),
            ..._buildInfoPanel(
              'Compressed video view',
              info: _compressedVideoInfo,
              isVideoModel: true,
            ),
            ..._buildInfoPanel(
              'Thumbnail image from file preview',
              image: _thumbnailFileImage,
            ),
            ..._buildInfoPanel(
              'Gif image from original video preview',
              image: _gifFileImage,
            ),
          ].expand((widget) {
            if (widget is SizedBox || widget is Card) {
              return [widget];
            }
            return [widget, const SizedBox(height: 8)];
          }).toList(),
        ),
        StreamBuilder<bool>(
          stream: _loadingStreamCtrl.stream,
          builder: (context, AsyncSnapshot<bool> snapshot) {
            if (snapshot.data == true) {
              return GestureDetector(
                onTap: () {
                  _flutterVideoCompress.cancelCompression();
                },
                child: Card(
                  child: Container(
                    color: Colors.black54,
                    width: MediaQuery.of(context).size.width,
                    height: MediaQuery.of(context).size.height,
                    child: Column(
                      mainAxisAlignment: MainAxisAlignment.center,
                      mainAxisSize: MainAxisSize.max,
                      children: [
                        CircularProgressIndicator(),
                        if (_taskName != null)
                          Padding(
                            padding: const EdgeInsets.all(8),
                            child: Text('[$_taskName] $_progressState%'),
                          ),
                        Padding(
                          padding: const EdgeInsets.all(8),
                          child: const Text('click cancel...'),
                        )
                      ],
                    ),
                  ),
                ),
              );
            }
            return Container();
          },
        ),
      ]),
    );
  }
}

class VideoPlayerView extends StatefulWidget {
  VideoPlayerView({this.file});

  final File file;

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

class _VideoPlayerViewState extends State<VideoPlayerView> {
  VideoPlayerController _controller;

  @override
  void initState() {
    super.initState();
    _controller = VideoPlayerController.file(widget.file)
      ..initialize().then((_) {
        setState(() {});
      })
      ..setVolume(1)
      ..play();
  }

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

  @override
  Widget build(context) {
    return GestureDetector(
      onTap: () {
        setState(() {
          _controller.value.isPlaying
              ? _controller.pause()
              : _controller.play();
        });
      },
      child: SingleChildScrollView(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.spaceBetween,
          mainAxisSize: MainAxisSize.max,
          children: <Widget>[
            Stack(
              alignment: Alignment.center,
              children: <Widget>[
                _controller.value.initialized
                    ? AspectRatio(
                        aspectRatio: _controller.value.aspectRatio,
                        child: VideoPlayer(_controller),
                      )
                    : Container(),
                Icon(
                  _controller.value.isPlaying ? null : Icons.play_arrow,
                  size: 80,
                ),
              ],
            ),
            VideoProgressIndicator(
              _controller,
              allowScrubbing: true,
              colors: VideoProgressColors(
                playedColor: Color.fromRGBO(255, 255, 255, 0.1),
              ),
            ),
          ],
        ),
      ),
    );
  }
}
86
likes
40
pub points
78%
popularity

Publisher

unverified uploader

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.

Repository (GitHub)
View/report issues

License

MIT (license)

Dependencies

flutter

More

Packages that depend on flutter_video_compress