Flutter视频裁剪插件flutter_video_trimmer的使用
Flutter视频裁剪插件flutter_video_trimmer的使用
特性
- 可自定义视频裁剪器。
- 支持两种类型的裁剪预览器:固定长度和可滚动。
- 视频播放控制。
- 获取并存储视频文件。
此外,还支持转换为 GIF。
注意:版本
3.0.0
及以上使用了完整的 Flutter FFmpeg。要安装 LTS 版本,请使用此包的x.x.x-LTS
版本。
以下图片展示了 TrimViewer
的结构。它由顶部的 Duration
(显示开始时间、结束时间和滑块时间)、包含缩略图的 TrimArea
和一个允许你从视频中选择部分的 TrimEditor
组成。
示例
运行在 iPhone 13 Pro 设备上的示例应用:
使用
添加依赖
在 pubspec.yaml
文件中添加 flutter_video_trimmer
依赖:
对于使用主版本 FFmpeg 包的情况:
dependencies:
flutter_video_trimmer: ^3.0.0
对于使用 LTS 版本 FFmpeg 包的情况:
dependencies:
video_trimmer: ^3.0.0-LTS
Android 配置
无需额外配置即可在 Android 平台上使用。
iOS 配置
在 Info.plist
文件中添加以下键值对:
<key>NSCameraUsageDescription</key>
<string>用于演示图像选择插件</string>
<key>NSMicrophoneUsageDescription</key>
<string>用于捕获音频以供图像选择插件使用</string>
<key>NSPhotoLibraryUsageDescription</key>
<string>用于演示图像选择插件</string>
FFmpeg 发行版
该包支持 FFmpeg 主版本和 LTS 版本。
主版本 | LTS 版本 | |
---|---|---|
Android API Level | 24 | 16 |
Android 相机访问 | 是 | - |
Android 架构 | arm-v7a-neon, arm64-v8a, x86, x86-64 | arm-v7a, arm-v7a-neon, arm64-v8a, x86, x86-64 |
iOS 最小 SDK | 12.1 | 10 |
iOS 架构 | arm64, arm64-simulator, arm64-mac-catalyst, x86-64, x86-64-mac-catalyst | armv7, arm64, i386, x86-64 |
功能
加载输入视频文件
final Trimmer _trimmer = Trimmer();
await _trimmer.loadVideo(videoFile: file);
保存裁剪后的视频
返回一个字符串来指示保存操作是否成功。
await _trimmer
.saveTrimmedVideo(startValue: _startValue, endValue: _endValue)
.then((value) {
setState(() {
_value = value;
});
});
视频播放状态
返回视频播放状态。如果为 true
则视频正在播放,否则暂停。
await _trimmer.videoPlaybackControl(
startValue: _startValue,
endValue: _endValue,
);
高级命令
你可以使用高级的 FFmpeg 命令进行更多定制。通过 ffmpegCommand
属性定义你的 FFmpeg 命令,并使用 customVideoFormat
设置输出视频格式。
有关更多信息,请参阅 官方 FFmpeg 文档。
注意:传递错误的视频格式到
customVideoFormat
属性可能会导致崩溃。
// 定义自定义命令的示例
// 这个默认用于创建 GIF,因此你不需要使用这个。
await _trimmer
.saveTrimmedVideo(
startValue: _startValue,
endValue: _endValue,
ffmpegCommand:
'-vf "fps=10,scale=480:-1:flags=lanczos,split[s0][s1];[s0]palettegen[p];[s1][p]paletteuse" -loop 0',
customVideoFormat: '.gif')
.then((value) {
setState(() {
_value = value;
});
});
小部件
显示视频播放区域
VideoViewer(trimmer: _trimmer)
显示视频裁剪区域
TrimViewer(
trimmer: _trimmer,
viewerHeight: 50.0,
viewerWidth: MediaQuery.of(context).size.width,
maxVideoLength: const Duration(seconds: 10),
onChangeStart: (value) => _startValue = value,
onChangeEnd: (value) => _endValue = value,
onChangePlaybackState: (value) =>
setState(() => _isPlaying = value),
)
示例代码
替换新创建的 Flutter 项目的 main.dart
文件内容。
import 'dart:io';
import 'package:file_picker/file_picker.dart';
import 'package:flutter/material.dart';
import 'package:flutter_video_trimmer/flutter_video_trimmer.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Video Trimmer',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: HomePage(),
);
}
}
class HomePage extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("Video Trimmer"),
),
body: Center(
child: Container(
child: ElevatedButton(
child: Text("LOAD VIDEO"),
onPressed: () async {
FilePickerResult? result = await FilePicker.platform.pickFiles(
type: FileType.video,
allowCompression: false,
);
if (result != null) {
File file = File(result.files.single.path!);
Navigator.of(context).push(
MaterialPageRoute(builder: (context) {
return TrimmerView(file);
}),
);
}
},
),
),
),
);
}
}
class TrimmerView extends StatefulWidget {
final File file;
TrimmerView(this.file);
@override
_TrimmerViewState createState() => _TrimmerViewState();
}
class _TrimmerViewState extends State<TrimmerView> {
final Trimmer _trimmer = Trimmer();
double _startValue = 0.0;
double _endValue = 0.0;
bool _isPlaying = false;
bool _progressVisibility = false;
Future<String?> _saveVideo() async {
setState(() {
_progressVisibility = true;
});
String? _value;
await _trimmer
.saveTrimmedVideo(startValue: _startValue, endValue: _endValue)
.then((value) {
setState(() {
_progressVisibility = false;
_value = value;
});
});
return _value;
}
void _loadVideo() {
_trimmer.loadVideo(videoFile: widget.file);
}
@override
void initState() {
super.initState();
_loadVideo();
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("Video Trimmer"),
),
body: Builder(
builder: (context) => Center(
child: Container(
padding: EdgeInsets.only(bottom: 30.0),
color: Colors.black,
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
mainAxisSize: MainAxisSize.max,
children: <Widget>[
Visibility(
visible: _progressVisibility,
child: LinearProgressIndicator(
backgroundColor: Colors.red,
),
),
ElevatedButton(
onPressed: _progressVisibility
? null
: () async {
_saveVideo().then((outputPath) {
print('OUTPUT PATH: $outputPath');
final snackBar = SnackBar(
content: Text('Video Saved successfully'));
ScaffoldMessenger.of(context).showSnackBar(
snackBar,
);
});
},
child: Text("SAVE"),
),
Expanded(
child: VideoViewer(trimmer: _trimmer),
),
Center(
child: TrimViewer(
trimmer: _trimmer,
viewerHeight: 50.0,
viewerWidth: MediaQuery.of(context).size.width,
maxVideoLength: const Duration(seconds: 10),
onChangeStart: (value) => _startValue = value,
onChangeEnd: (value) => _endValue = value,
onChangePlaybackState: (value) =>
setState(() => _isPlaying = value),
),
),
TextButton(
child: _isPlaying
? Icon(
Icons.pause,
size: 80.0,
color: Colors.white,
)
: Icon(
Icons.play_arrow,
size: 80.0,
color: Colors.white,
),
onPressed: () async {
bool playbackState = await _trimmer.videoPlaybackControl(
startValue: _startValue,
endValue: _endValue,
);
setState(() {
_isPlaying = playbackState;
});
},
)
],
),
),
),
),
);
}
}
解决 LTS 版本问题
如果在 Android 平台上遇到 minSdkVersion
需要设置为 24
的错误,或者在 iOS 平台上遇到 Podfile 平台版本应为 11
的错误,首先查看 pubspec.lock
文件中 ffmpeg_kit_flutter
是否有 -LTS
后缀。这应该可以解决 iOS 平台的所有问题。
如果在 Android 上仍然遇到相同的问题,请尝试在 <project_directory>/android/app/src/main/AndroidManifest.xml
中添加以下内容:
<manifest xmlns:tools="http://schemas.android.com/tools" ....... >
<uses-sdk tools:overrideLibrary="com.arthenica.ffmpegkit.flutter, com.arthenica.ffmpegkit" />
</manifest>
更多关于Flutter视频裁剪插件flutter_video_trimmer的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
更多关于Flutter视频裁剪插件flutter_video_trimmer的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
当然,以下是如何在Flutter项目中使用flutter_video_trimmer
插件进行视频裁剪的示例代码。这个插件允许用户选择视频的一部分进行裁剪。
1. 添加依赖
首先,在你的pubspec.yaml
文件中添加flutter_video_trimmer
依赖:
dependencies:
flutter:
sdk: flutter
flutter_video_trimmer: ^0.5.0 # 请确保使用最新版本
然后运行flutter pub get
来安装依赖。
2. 导入插件
在你的Dart文件中导入插件:
import 'package:flutter_video_trimmer/flutter_video_trimmer.dart';
3. 使用插件
以下是一个完整的示例,展示如何集成flutter_video_trimmer
到你的Flutter应用中:
import 'package:flutter/material.dart';
import 'package:flutter_video_trimmer/flutter_video_trimmer.dart';
import 'package:path_provider/path_provider.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: VideoTrimmerScreen(),
);
}
}
class VideoTrimmerScreen extends StatefulWidget {
@override
_VideoTrimmerScreenState createState() => _VideoTrimmerScreenState();
}
class _VideoTrimmerScreenState extends State<VideoTrimmerScreen> {
late String videoPath;
late File trimmedVideoFile;
@override
void initState() {
super.initState();
_getSampleVideoPath();
}
Future<void> _getSampleVideoPath() async {
final directory = await getApplicationDocumentsDirectory();
videoPath = '${directory.path}/sample_video.mp4'; // 替换为你的视频路径
// 确保视频文件存在,或者你可以选择一个已存在的视频
// 这里我们假设已经有一个名为sample_video.mp4的视频文件在指定目录
setState(() {});
}
Future<void> _trimVideo(VideoTrimmerResult result) async {
final directory = await getApplicationDocumentsDirectory();
final trimmedVideoPath = '${directory.path}/trimmed_video.mp4';
trimmedVideoFile = File(trimmedVideoPath);
// 保存裁剪后的视频
await FlutterVideoTrimmer.trimVideo(
videoPath: videoPath,
startTime: result.startTime,
endTime: result.endTime,
outputPath: trimmedVideoPath,
showProgressBar: true,
);
// 处理裁剪后的视频文件,例如显示、上传等
print('Trimmed Video Path: $trimmedVideoPath');
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Video Trimmer Example'),
),
body: Center(
child: videoPath.isEmpty
? CircularProgressIndicator()
: VideoTrimmer(
videoPath: videoPath,
onTrimmed: _trimVideo,
),
),
);
}
}
4. 运行应用
确保你的开发环境中已经有一个有效的视频文件,并替换videoPath
为你的视频文件路径。运行你的Flutter应用,你应该能够看到一个视频裁剪界面,用户可以选择视频的开始和结束时间,然后点击确认进行裁剪。
注意事项
- 确保视频文件路径是正确的,并且文件存在。
flutter_video_trimmer
依赖于FFmpeg进行视频处理,因此在Android上可能需要配置FFmpeg的编译选项。- 在iOS上,你可能需要添加FFmpeg相关的权限配置。
这个示例应该能够帮助你快速集成flutter_video_trimmer
到你的Flutter应用中。如果需要更详细的功能或自定义,请参考插件的官方文档。