video_utils.dart
5.95 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
import 'dart:io';
import 'package:flutter/material.dart';
import 'package:path_provider/path_provider.dart';
import 'package:video_compress/video_compress.dart';
import 'package:video_thumbnail/video_thumbnail.dart';
class VideoUtils {
// 1280*720
static final int maxVideoPixel = 1280 * 720;
static final int maxVideoSize = 50;
/// 清除缓存
static Future<void> clearTemporaryDirectory() async {
Directory tempDir = await getTemporaryDirectory();
if (tempDir == null) return;
await _delete(tempDir);
}
static Future<void> _delete(FileSystemEntity file) async {
if (file is Directory) {
final List<FileSystemEntity> children = file.listSync();
for (final FileSystemEntity child in children) {
await _delete(child);
}
} else {
await file.delete();
}
}
static getDuration(double duration, {String dateFormat = 'mm:ss'}) {
int value = duration ~/ 1000; // 毫秒转换为秒;
int hour = (value) ~/ 3600;
String hourStr = '${hour}';
if (hour < 10) {
//时
hourStr = "0" + '${hour}';
}
int minute = (value % 3600) ~/ 60;
String minuteStr = '${minute}';
if (minute < 10) {
//分
minuteStr = "0" + '${minute}';
}
int second = value % 60;
String secondStr = '${second}';
if (second < 10) {
//秒
secondStr = "0" + '${second}';
}
switch (dateFormat) {
case 'hh:mm':
return hourStr + ":" + minuteStr;
break;
case 'mm:ss':
return minuteStr + ":" + secondStr;
break;
case 'hh':
return hourStr;
break;
default:
return hourStr + ":" + minuteStr + ":" + secondStr;
break;
}
}
// 获取视频的大小(以 MB 为单位)
static Future<double> getVideoFileSize(String videoPath) async {
final File file = File(videoPath);
return file.lengthSync() / 1024 / 1024;
}
// 获取视频的像素大小(宽度 * 高度)
static Future<int> getVideoPixelSize(String videoPath) async {
final info =
await VideoCompress.getMediaInfo(videoPath); //视频信息:时长、像素(宽高)、大小、path
final int width = info.width;
final int height = info.height;
return width * height;
}
// 获取视频的像素大小(宽度 * 高度)
// static Future<double> getVideoPixelSize(String videoPath) async {
// final VideoPlayerController _controller = VideoPlayerController.file(File(videoPath));
// await _controller.initialize();
// final double width = _controller.value.size.width;
// final double height = _controller.value.size.height;
// await _controller.dispose();
// return width * height;
// }
// 获取视频的封面图
// static Future<String> getVideoThumbnail(String videoPath) async {
// final thumbnailPath = await VideoThumbnail.thumbnailFile(
// video: videoPath,
// thumbnailPath: (await getTemporaryDirectory()).path,
// imageFormat: ImageFormat.JPEG,
// maxHeight: 128, // 设置最大高度
// quality: 75, // 设置质量
// );
// return thumbnailPath;
// }
// 获取视频的封面图
static Future<String> getThumbnailFile(String url) async {
// final fileName = await VideoThumbnail.thumbnailFile(
// video: url,
// thumbnailPath: (await getTemporaryDirectory()).path,
// // imageFormat: ImageFormat.WEBP,
// // maxHeight:
// // 64, // specify the height of the thumbnail, let the width auto-scaled to keep the source aspect ratio
// quality: 100,
// );
final thumbnail = await VideoThumbnail.thumbnailFile(
video: url,
imageFormat: ImageFormat.PNG,
quality: 100,
);
// 获取应用文件夹路径
String name = DateTime.now().millisecondsSinceEpoch.toString();
final directory = await getApplicationDocumentsDirectory();
final String thumbnailPath = '${directory.path}/${name}.png';
// 将封面图保存到应用文件夹
final File file = File(thumbnailPath);
await file.writeAsBytes(await File(thumbnail).readAsBytes());
// print('Thumbnail saved to $thumbnailPath');
return thumbnailPath;
}
Future<void> copyFile(String oldPath, String newPath) async {
// 获取应用的临时目录
final tempDir = await getTemporaryDirectory();
final newTempPath = '${tempDir.path}/$newPath';
// 创建新文件的目录
final newDir =
Directory(newTempPath.substring(0, newTempPath.lastIndexOf('/')));
if (!newDir.existsSync()) {
newDir.createSync(recursive: true);
}
// 复制文件到新路径
final file = File(oldPath);
await file.copy(newTempPath);
print('文件已复制到: $newTempPath');
}
// Future<String> getTempDirectoryPathWithTimestamp() async {
// // 获取临时目录
// final tempDir = await getTemporaryDirectory();
// // 获取当前时间戳
// final timestamp = DateTime.now().millisecondsSinceEpoch;
// // 拼接路径和时间戳
// final tempPathWithTimestamp = join(tempDir.path, '$timestamp');
// return tempPathWithTimestamp;
// }
// 是否压缩 (压缩前的校验)
// 视频像素大小 小于 720p || 视频大小 小于 50mb --> 压缩
static Future<bool> shouldCompress(String videoPath) async {
int p = await getVideoPixelSize(videoPath);
double s = await getVideoFileSize(videoPath); //size
if (p > maxVideoPixel || s >= maxVideoSize) {
return true;
} else {
return false;
}
}
// 压缩视频的方法
static Future<File> compress(String videoPath) async {
// 订阅压缩进度
// _subscription = VideoCompress.compressProgress$.subscribe((progress) {
// _progress = progress;
// // 回调进度给外部
// if (onProgress != null) {
// onProgress!(progress);
// }
// });
MediaInfo info = await VideoCompress.compressVideo(
videoPath,
quality: VideoQuality.Res1280x720Quality,
deleteOrigin: false,
);
return info.file;
}
}