Flutter视频压缩插件video_compress_ds的使用

Flutter视频压缩插件video_compress_ds的使用

简介

video_compress_ds 是一个用于压缩视频、移除音频、处理缩略图并使视频在所有平台上兼容的轻量级高效库。该库完全使用原生代码编写,不使用FFMPEG,因为其速度慢、体积大且GNU许可证对商业应用不利。

该插件适用于ANDROID、IOS和桌面(目前仅支持MacOS)。

安装与配置

  1. 添加依赖

    在您的 pubspec.yaml 文件中添加以下内容:

    dependencies:
      video_compress: ^3.1.0
    
  2. 安装包

    从命令行安装包:

    $ pub get
    
  3. 导入包

    在您的 Dart 代码中导入:

    import 'package:video_compress_ds/video_compress_ds.dart';
    

使用方法

导入
import 'package:video_compress_ds/video_compress_ds.dart';
视频压缩
// 压缩视频示例
MediaInfo mediaInfo = await VideoCompress.compressVideo(
  path, // 视频文件路径
  quality: VideoQuality.DefaultQuality, // 压缩质量
  deleteOrigin: false, // 是否删除原始文件,默认为false
);
检查压缩状态
// 检查压缩状态
bool isCompressing = 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); // 视频文件路径
删除所有缓存文件
// 删除所有由video_compress生成的缓存文件
await VideoCompress.deleteAllCache();
监听压缩进度
class _Compress extends State<Compress> {

  Subscription _subscription;

  [@override](/user/override)
  void initState() {
    super.initState();
    // 订阅压缩进度
    _subscription =
        VideoCompress.compressProgress$.subscribe((progress) {
      debugPrint('progress: $progress');
    });
  }

  [@override](/user/override)
  void dispose() {
    super.dispose();
    _subscription.unsubscribe(); // 取消订阅
  }
}

示例代码

以下是一个完整的示例代码,展示了如何使用 video_compress_ds 插件进行视频压缩:

import 'package:flutter/material.dart';
import 'package:image_picker/image_picker.dart';
import 'package:video_compress_ds/video_compress_ds.dart';
import 'dart:io';

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

class MyApp extends StatelessWidget {
  [@override](/user/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](/user/override)
  _MyHomePageState createState() => _MyHomePageState();
}

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

  [@override](/user/override)
  void initState() {
    super.initState();
    // 订阅压缩进度
    VideoCompress.compressProgress$.subscribe((progress) {
      if (progress > 0) {
        print('progress: $progress');
      }
    });
  }

  _compressVideo() async {
    var file;
    if (Platform.isMacOS) {
      // MacOS下选择文件
      final typeGroup = XTypeGroup(label: 'videos', extensions: ['mov', 'mp4']);
      file = await openFile(acceptedTypeGroups: [typeGroup]);
    } else {
      // 其他平台使用ImagePicker选择视频
      final picker = ImagePicker();
      PickedFile? pickedFile =
          await picker.getVideo(source: ImageSource.gallery);
      file = File(pickedFile!.path);
    }
    if (file == null) {
      return;
    }
    await VideoCompress.setLogLevel(0);
    final MediaInfo? info = await VideoCompress.compressVideo(
      file.path, // 视频文件路径
      quality: VideoQuality.MediumQuality, // 压缩质量
      deleteOrigin: false, // 是否删除原始文件
      includeAudio: true, // 是否包含音频
    );
    if (info != null) {
      print("isCancel: ${info.isCancel}");
      if (info.path != null) {
        setState(() {
          _counter = info.path!;
        });
      }
    } else {
      print("info == null");
    }
  }

  [@override](/user/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.headline4,
            ),
            InkWell(
                child: Icon(
                  Icons.cancel,
                  size: 55,
                ),
                onTap: () {
                  VideoCompress.cancelCompression(); // 取消压缩
                }),
          ],
        ),
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: () async => _compressVideo(), // 压缩视频
        tooltip: 'Increment',
        child: Icon(Icons.add),
      ),
    );
  }
}

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

1 回复

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


当然,以下是如何在Flutter项目中使用video_compress_ds插件进行视频压缩的详细代码示例。这个插件提供了一个简单的方法来压缩视频文件,同时支持调整输出视频的分辨率、比特率等参数。

第一步:添加依赖

首先,你需要在pubspec.yaml文件中添加video_compress_ds插件的依赖:

dependencies:
  flutter:
    sdk: flutter
  video_compress_ds: ^x.y.z  # 请替换为最新版本号

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

第二步:导入插件并配置权限

在你的Dart文件中导入插件,并确保在Android和iOS项目中配置了必要的权限。

Dart 文件

import 'package:flutter/material.dart';
import 'package:video_compress_ds/video_compress_ds.dart';
import 'package:path_provider/path_provider.dart';

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

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

class VideoCompressScreen extends StatefulWidget {
  @override
  _VideoCompressScreenState createState() => _VideoCompressScreenState();
}

class _VideoCompressScreenState extends State<VideoCompressScreen> {
  String? compressedVideoPath;

  void _compressVideo(String videoPath) async {
    final VideoCompressDs videoCompressDs = VideoCompressDs();
    
    // 配置压缩参数
    final CompressOptions options = CompressOptions(
      width: 640,  // 宽度
      height: 360, // 高度
      bitrate: 500 * 1000, // 比特率(bps)
      quality: 70, // 质量(1-100)
      removeAudio: false, // 是否移除音频
    );

    // 获取输出路径(这里使用临时目录)
    final Directory tempDir = await getTemporaryDirectory();
    final String outputPath = "${tempDir.path}/compressed_video.mp4";

    try {
      final CompressResult result = await videoCompressDs.compressVideo(videoPath, outputPath, options);
      if (result.success) {
        setState(() {
          compressedVideoPath = result.outputPath;
        });
      } else {
        print("压缩失败: ${result.error}");
      }
    } catch (e) {
      print("压缩过程发生错误: $e");
    }
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('视频压缩示例'),
      ),
      body: Padding(
        padding: const EdgeInsets.all(16.0),
        child: Column(
          crossAxisAlignment: CrossAxisAlignment.start,
          children: [
            Text('原始视频路径(请替换为你的视频路径):'),
            TextField(
              decoration: InputDecoration(
                border: OutlineInputBorder(),
                labelText: '输入视频路径',
              ),
              onEditingComplete: () async {
                final String inputPath = this.textEditingController?.text ?? '';
                _compressVideo(inputPath);
              },
              controller: TextEditingController(text: '/path/to/your/video.mp4'), // 替换为你的视频路径
            ),
            SizedBox(height: 20),
            if (compressedVideoPath != null)
              Text('压缩后的视频路径: $compressedVideoPath'),
          ],
        ),
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: () async {
          final TextEditingController? controller = 
            (findNodeWithFocus() as? TextField)?.controller;
          if (controller != null && controller!.text.isNotEmpty) {
            _compressVideo(controller!.text);
          } else {
            print('请输入视频路径');
          }
        },
        tooltip: '压缩视频',
        child: Icon(Icons.compress),
      ),
    );
  }
}

第三步:配置权限

Android

AndroidManifest.xml中添加以下权限:

<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />

iOS

Info.plist中添加以下权限:

<key>NSAppTransportSecurity</key>
<dict>
    <key>NSAllowsArbitraryLoads</key>
    <true/>
</dict>
<key>NSPhotoLibraryUsageDescription</key>
<string>需要访问相册以选择视频</string>
<key>NSCameraUsageDescription</key>
<string>需要访问相机以拍摄视频</string>
<key>NSMicrophoneUsageDescription</key>
<string>需要访问麦克风以录制音频</string>

注意事项

  1. 确保你提供的视频路径是有效的,并且设备具有读取该路径的权限。
  2. 压缩后的视频路径可能会根据设备的存储情况而变化,因此建议使用临时目录或应用私有目录存储压缩后的视频。
  3. 根据实际需求调整压缩参数,以达到最佳的压缩效果和质量平衡。

这样,你就可以在Flutter项目中使用video_compress_ds插件进行视频压缩了。

回到顶部