Flutter视频裁剪插件cutting_room的使用

Flutter视频裁剪插件cutting_room的使用

Cutting Room
Compose and render videos with compositions, backed by FFMPEG.

该项目是Flutter Bounty Hunters的概念验证。想要更多类型的组合和视频控制?今天就去资助一个里程碑任务吧!


在实际项目中的应用

cutting_room 插件被用来渲染 YouTube 频道 Flutter Bounty HuntersSuperDeclarative! 中的所有视频。


运行示例

要运行这些示例,你需要从 Git Large File System (LFS) 拉取示例视频资源。由于 pub.dev 不允许上传超过一定大小的包,这些资产存储在 Git LFS 中。

首先,安装 Git LFS 本地工具

一旦 Git LFS 设置完成,从该仓库的根目录运行以下命令以下载视频资源:

git lfs pull

快速入门

cutting_room 中,你所做的就是创建一个将通过 FFMPEG 渲染的组合。最终,会在命令行中运行一个巨大的 FFMPEG 命令并生成你的视频。

cutting_room 提供了声明式的组合,这样你可以像构建 Flutter 小部件树一样构建视频。在以下示例中,视频由两个其他视频片段组成,顺序播放(串联)。

// 创建所需的视频并构建 FFMPEG 命令来渲染它。
final cliCommand = await CompositionBuilder().build(
  // 这是你声明式的视频组合,类似于 Flutter 中的小部件树。
  SeriesComposition(
    compositions: [
      FullVideoComposition(
        videoPath: "assets/Butterfly-209.mp4", // 第一个视频路径
      ),
      FullVideoComposition(
        videoPath: "assets/bee.mp4", // 第二个视频路径
      ),
    ],
  ),
);

// 运行 FFMPEG 命令。
final process = await Ffmpeg().run(cliCommand);

// 将进程输出管道到 Dart 控制台。
process.stderr.transform(utf8.decoder).listen((data) {
  print(data); // 打印 FFMPEG 的错误日志
});

// 允许用户响应 FFMPEG 查询,例如文件覆盖确认。
stdin.pipe(process.stdin);

await process.exitCode; // 等待进程结束

组合类型

cutting_room 提供了许多内置的组合类型,包括:

  • <code>SeriesComposition</code>
    将多个视频片段按顺序连接起来。

  • <code>LayeredComposition</code>
    将多个视频层叠在一起。

  • <code>ImageOverlayComposition</code>
    在视频上叠加图片。

如果你发现内置的组合类型无法满足需求,可以定义自己的组合类型。要实现自定义组合类型,你需要了解如何定义 FFMPEG 命令,并组装实现目标的 FFMPEG 过滤器。


cutting_room 资源

内部而言,cutting_room 包含并使用了一些资源。例如,cutting_room 使用了一张填充黑色的 PNG 图像来渲染纯黑的组合。这些资源的使用有各种原因。未来,cutting_room 可能会找到一种方法来移除它们。

重要的是,这些资源是文件。这些文件包含在 cutting_room 中,在使用 dart 工具运行应用程序时,你应该不会注意到它们。但是,如果你将 Dart 应用程序编译为二进制可执行文件,则会失去对依赖项资源的访问权限,包括 cutting_room 中的资源。在这种情况下,当运行视频渲染时,cutting_room 会在本地文件系统中写入这些资源的新文件。因此,如果在运行视频渲染时生成了一些图像和视频文件,请不要感到惊讶。


完整示例代码

以下是一个完整的示例代码,展示如何使用 cutting_room 插件来组合和渲染视频:

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

void main() async {
  // 创建所需的视频并构建 FFMPEG 命令来渲染它。
  final cliCommand = await CompositionBuilder().build(
    SeriesComposition(
      compositions: [
        FullVideoComposition(
          videoPath: "assets/Butterfly-209.mp4", // 第一个视频路径
        ),
        FullVideoComposition(
          videoPath: "assets/bee.mp4", // 第二个视频路径
        ),
      ],
    ),
  );

  // 运行 FFMPEG 命令。
  final process = await Ffmpeg().run(cliCommand);

  // 将进程输出管道到 Dart 控制台。
  process.stderr.transform(utf8.decoder).listen((data) {
    print(data); // 打印 FFMPEG 的错误日志
  });

  // 允许用户响应 FFMPEG 查询,例如文件覆盖确认。
  stdin.pipe(process.stdin);

  // 等待进程结束
  await process.exitCode;
}

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

1 回复

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


cutting_room 是一个用于 Flutter 的视频裁剪插件,允许开发者从视频中选择特定的片段并进行裁剪。以下是使用 cutting_room 插件的基本步骤:

1. 添加依赖

首先,在 pubspec.yaml 文件中添加 cutting_room 插件的依赖:

dependencies:
  flutter:
    sdk: flutter
  cutting_room: ^1.0.0  # 请确保使用最新版本

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

2. 导入包

在需要使用 cutting_room 的 Dart 文件中导入插件:

import 'package:cutting_room/cutting_room.dart';

3. 选择视频文件

首先,你需要让用户选择一个视频文件。你可以使用 image_picker 插件来选择视频:

import 'package:image_picker/image_picker.dart';

final picker = ImagePicker();
final pickedFile = await picker.getVideo(source: ImageSource.gallery);

if (pickedFile != null) {
  final videoFile = File(pickedFile.path);
  // 使用 cutting_room 进行裁剪
}

4. 裁剪视频

使用 cutting_room 插件来裁剪视频。你可以指定开始和结束时间来选择视频片段:

final videoFile = File(pickedFile.path);
final outputFile = File('/path/to/output.mp4');  // 设置输出文件路径

final cutter = VideoCutter();

try {
  await cutter.extractVideo(
    videoFile: videoFile,
    outputFile: outputFile,
    start: Duration(seconds: 5),  // 裁剪开始时间
    end: Duration(seconds: 15),   // 裁剪结束时间
  );
  print('视频裁剪成功!');
} catch (e) {
  print('视频裁剪失败: $e');
}

5. 处理裁剪后的视频

裁剪后的视频会保存到你指定的 outputFile 路径中。你可以使用 video_player 插件来播放裁剪后的视频,或者将其上传到服务器等。

import 'package:video_player/video_player.dart';

final videoPlayerController = VideoPlayerController.file(outputFile);

await videoPlayerController.initialize();
await videoPlayerController.play();

6. 清理资源

在不需要的时候,记得释放资源:

videoPlayerController.dispose();
回到顶部