Flutter视频压缩插件video_compress的使用

发布于 1周前 作者 sinazl 来自 Flutter

Flutter视频压缩插件video_compress的使用

video_compress 是一个用于Flutter应用的插件,它可以帮助开发者轻松地压缩视频、移除音频、生成缩略图以及确保视频与所有平台兼容。该库完全采用原生代码编写,不依赖FFMPEG,因此避免了其带来的性能和授权问题。

安装配置

1. 添加依赖

在项目的 pubspec.yaml 文件中添加如下依赖:

dependencies:
  video_compress: ^3.1.0

2. 安装包

通过命令行执行以下命令安装依赖:

$ pub get

3. 导入包

在Dart文件中导入 video_compress 包:

import 'package:video_compress/video_compress.dart';

使用方法

视频压缩

MediaInfo mediaInfo = await VideoCompress.compressVideo(
  path,
  quality: VideoQuality.DefaultQuality, 
  deleteOrigin: false, // 默认为false,表示不删除原始文件
);

检查压缩状态

VideoQuality.isCompressing

获取内存中的缩略图

final uint8list = await VideoCompress.getByteThumbnail(
  videopath,
  quality: 50, // 默认值为100
  position: -1 // 默认值为-1
);

获取文件形式的缩略图

final thumbnailFile = await VideoCompress.getFileThumbnail(
  videopath,
  quality: 50, // 默认值为100
  position: -1 // 默认值为-1
);

获取媒体信息

final info = await VideoCompress.getMediaInfo(videopath);

删除所有缓存文件

await VideoCompress.deleteAllCache()

监听压缩进度

class _Compress extends State<Compress> {
  Subscription? _subscription;

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

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

示例Demo

下面是一个完整的示例,展示了如何在一个Flutter应用中使用 video_compress 插件来选择并压缩视频:

import 'dart:io';

import 'package:file_selector/file_selector.dart';
import 'package:flutter/material.dart';
import 'package:image_picker/image_picker.dart';
import 'package:video_compress/video_compress.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: MyHomePage(title: 'Flutter Demo Home Page'),
    );
  }
}

class MyHomePage extends StatefulWidget {
  MyHomePage({Key? key, this.title}) : super(key: key);

  final String? title;

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

class _MyHomePageState extends State<MyHomePage> {
  String _counter = 'video';

  Future<void> _compressVideo() async {
    var file;
    if (Platform.isMacOS) {
      final typeGroup = XTypeGroup(label: 'videos', extensions: ['mov', 'mp4']);
      file = await openFile(acceptedTypeGroups: [typeGroup]);
    } else {
      final picker = ImagePicker();
      var pickedFile = await picker.pickVideo(source: ImageSource.gallery);
      file = File(pickedFile!.path);
    }
    if (file == null) {
      return;
    }
    await VideoCompress.setLogLevel(0);
    final info = await VideoCompress.compressVideo(
      file.path,
      quality: VideoQuality.MediumQuality,
      deleteOrigin: false,
      includeAudio: true,
    );
    print(info!.path);
    setState(() {
      _counter = info.path!;
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(widget.title!),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            Text(
              'You have pushed the button this many times:',
            ),
            Text(
              '$_counter',
              style: Theme.of(context).textTheme.headlineMedium,
            ),
            InkWell(
                child: Icon(
                  Icons.cancel,
                  size: 55,
                ),
                onTap: () {
                  VideoCompress.cancelCompression();
                }),
            ElevatedButton(
              onPressed: () {
                // 这里可以添加测试缩略图的逻辑
              },
              child: Text('Test thumbnail'),
            ),
          ],
        ),
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: () async => _compressVideo(),
        tooltip: 'Increment',
        child: Icon(Icons.add),
      ),
    );
  }
}

这个例子中,用户可以从相册中选择一段视频,并对其进行压缩处理。压缩完成后,会将新的视频路径显示出来。此外,还提供了取消压缩的功能按钮。


更多关于Flutter视频压缩插件video_compress的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html

1 回复

更多关于Flutter视频压缩插件video_compress的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


当然,下面是一个关于如何在Flutter项目中使用video_compress插件进行视频压缩的示例代码。这个插件可以帮助你有效地压缩视频文件,减少其大小,同时尽量保持视频质量。

首先,确保你已经在pubspec.yaml文件中添加了video_compress依赖:

dependencies:
  flutter:
    sdk: flutter
  video_compress: ^3.0.0  # 请检查最新版本号

然后,运行flutter pub get来安装依赖。

接下来,你可以在Dart代码中导入并使用video_compress插件。以下是一个完整的示例,展示如何选择一个视频文件,压缩它,并保存压缩后的视频:

import 'package:flutter/material.dart';
import 'package:video_compress/video_compress.dart';
import 'package:image_picker/image_picker.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: VideoCompressExample(),
    );
  }
}

class VideoCompressExample extends StatefulWidget {
  @override
  _VideoCompressExampleState createState() => _VideoCompressExampleState();
}

class _VideoCompressExampleState extends State<VideoCompressExample> {
  File? originalVideo;
  File? compressedVideo;

  final picker = ImagePicker();

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Video Compress Example'),
      ),
      body: Padding(
        padding: const EdgeInsets.all(16.0),
        child: Column(
          children: [
            originalVideo == null
                ? Text('No video selected.')
                : Stack(
                    alignment: Alignment.center,
                    children: [
                      Image.file(originalVideo!, fit: BoxFit.cover, width: double.infinity, height: 200),
                      Text('Original Video', style: TextStyle(color: Colors.white, fontSize: 16, backgroundColor: Colors.black45)),
                    ],
                  ),
            SizedBox(height: 20),
            ElevatedButton(
              onPressed: () => _pickVideo(context),
              child: Text('Pick Video'),
            ),
            SizedBox(height: 20),
            originalVideo != null
                ? ElevatedButton(
                    onPressed: () => _compressVideo(context, originalVideo!),
                    child: Text('Compress Video'),
                  )
                : Container(),
            SizedBox(height: 20),
            compressedVideo == null
                ? Text('No compressed video available.')
                : Stack(
                    alignment: Alignment.center,
                    children: [
                      Image.file(compressedVideo!, fit: BoxFit.cover, width: double.infinity, height: 200),
                      Text('Compressed Video', style: TextStyle(color: Colors.white, fontSize: 16, backgroundColor: Colors.black45)),
                    ],
                  ),
          ],
        ),
      ),
    );
  }

  Future<void> _pickVideo(BuildContext context) async {
    final pickerResult = await picker.pickVideo(source: ImageSource.camera);

    if (pickerResult != null && pickerResult.files.isNotEmpty) {
      setState(() {
        originalVideo = File(pickerResult.files.single.path);
      });
    } else {
      ScaffoldMessenger.of(context).showSnackBar(SnackBar(content: Text('Failed to pick video')));
    }
  }

  Future<void> _compressVideo(BuildContext context, File videoFile) async {
    final VideoCompress compress = VideoCompress();

    final result = await compress.compressVideo(
      videoFile.path,
      quality: VideoQuality.MediumQuality,
      startTime: 0, // Start from the beginning
      duration: -1, // Compress the whole video
      showProgressBar: true, // Show progress bar
      progress: (progress) {
        // You can show progress in UI
        print('Compression progress: $progress');
      },
    );

    if (result?.file != null) {
      setState(() {
        compressedVideo = result?.file;
      });
    } else {
      ScaffoldMessenger.of(context).showSnackBar(SnackBar(content: Text('Failed to compress video')));
    }
  }
}

关键点解释:

  1. 依赖管理:在pubspec.yaml中添加video_compressimage_picker依赖。
  2. 选择视频:使用ImagePicker插件选择视频文件。
  3. 视频压缩:使用VideoCompress插件的compressVideo方法进行视频压缩。你可以设置压缩质量、开始时间、持续时间以及是否显示进度条。
  4. UI更新:使用setState方法在UI中显示原始视频和压缩后的视频。

这个示例展示了如何集成和使用video_compress插件进行视频压缩,并提供了基本的用户界面来选择和查看视频。你可以根据需要进一步扩展和优化这个示例。

回到顶部