react-native-video-trim 2.0.0 → 2.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +33 -9
- package/android/src/main/AndroidManifest.xml +13 -0
- package/android/src/main/java/com/videotrim/VideoTrimModule.java +185 -64
- package/android/src/main/java/com/videotrim/enums/ErrorCode.java +11 -0
- package/android/src/main/java/com/videotrim/interfaces/VideoTrimListener.java +2 -1
- package/android/src/main/java/com/videotrim/utils/MediaMetadataUtil.java +75 -0
- package/android/src/main/java/com/videotrim/utils/StorageUtil.java +2 -2
- package/android/src/main/java/com/videotrim/utils/VideoTrimmerUtil.java +15 -8
- package/android/src/main/java/com/videotrim/widgets/VideoTrimmerView.java +239 -70
- package/android/src/main/res/drawable/airpodsmax.xml +19 -0
- package/android/src/main/res/drawable/exclamationmark_triangle_fill.xml +15 -0
- package/android/src/main/res/drawable/thumb_container_bg.xml +8 -0
- package/android/src/main/res/layout/video_trimmer_view.xml +51 -4
- package/android/src/main/res/xml/file_paths.xml +5 -0
- package/ios/AssetLoader.swift +99 -0
- package/ios/ErrorCode.swift +16 -0
- package/ios/VideoTrim.mm +4 -2
- package/ios/VideoTrim.swift +380 -167
- package/ios/VideoTrimmer.swift +16 -10
- package/ios/VideoTrimmerViewController.swift +78 -12
- package/lib/commonjs/index.js +20 -57
- package/lib/commonjs/index.js.map +1 -1
- package/lib/module/index.js +19 -57
- package/lib/module/index.js.map +1 -1
- package/lib/typescript/index.d.ts +47 -9
- package/lib/typescript/index.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/index.tsx +56 -66
- package/android/src/main/java/iknow/android/utils/BuildConfig.java +0 -18
- package/android/src/main/java/iknow/android/utils/DateUtil.java +0 -64
package/src/index.tsx
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { NativeModules,
|
|
1
|
+
import { NativeModules, Platform } from 'react-native';
|
|
2
2
|
|
|
3
3
|
const LINKING_ERROR =
|
|
4
4
|
`The package 'react-native-video-trim' doesn't seem to be linked. Make sure: \n\n` +
|
|
@@ -18,8 +18,16 @@ const VideoTrim = NativeModules.VideoTrim
|
|
|
18
18
|
);
|
|
19
19
|
|
|
20
20
|
export interface EditorConfig {
|
|
21
|
+
/**
|
|
22
|
+
* Enable haptic feedback
|
|
23
|
+
* @default true
|
|
24
|
+
*/
|
|
25
|
+
enableHapticFeedback?: boolean;
|
|
26
|
+
/**
|
|
27
|
+
* Save the output file to Photos Library. Only video is supported. Note that you have to make sure you have permission to save to Photos Library.
|
|
28
|
+
* @default false
|
|
29
|
+
*/
|
|
21
30
|
saveToPhoto?: boolean;
|
|
22
|
-
removeAfterSavedToPhoto?: boolean;
|
|
23
31
|
maxDuration?: number;
|
|
24
32
|
minDuration?: number;
|
|
25
33
|
cancelButtonText?: string;
|
|
@@ -36,6 +44,34 @@ export interface EditorConfig {
|
|
|
36
44
|
saveDialogConfirmText?: string;
|
|
37
45
|
trimmingText?: string;
|
|
38
46
|
fullScreenModalIOS?: boolean;
|
|
47
|
+
/**
|
|
48
|
+
* Type of the file to edit. If video file, recommend to use `video`. If audio file, recommend to use `audio`.
|
|
49
|
+
* @default "video"
|
|
50
|
+
*/
|
|
51
|
+
type?: 'video' | 'audio';
|
|
52
|
+
/**
|
|
53
|
+
* Output file extension. If video file, recommend to use `mp4` or `mov`. If audio file, recommend to use `wav` or `m4a`.
|
|
54
|
+
* @default "mp4"
|
|
55
|
+
* @example "mp4", "mov", "wav", "m4a", "3gp", "avi", "mkv", "flv", "wmv", "webm"
|
|
56
|
+
*/
|
|
57
|
+
outputExt?: string;
|
|
58
|
+
openDocumentsOnFinish?: boolean;
|
|
59
|
+
openShareSheetOnFinish?: boolean;
|
|
60
|
+
|
|
61
|
+
removeAfterSavedToPhoto?: boolean;
|
|
62
|
+
removeAfterFailedToSavePhoto?: boolean;
|
|
63
|
+
removeAfterSavedToDocuments?: boolean;
|
|
64
|
+
removeAfterFailedToSaveDocuments?: boolean;
|
|
65
|
+
/**
|
|
66
|
+
* Remove the file after shared to other apps. Currently only support iOS, on Android there's no way to detect if the file is shared or not.
|
|
67
|
+
* @default false
|
|
68
|
+
*/
|
|
69
|
+
removeAfterShared?: boolean;
|
|
70
|
+
/**
|
|
71
|
+
* Remove the file after failed to share to other apps. Currently only support iOS, on Android there's no way to detect if the file is shared or not.
|
|
72
|
+
* @default false
|
|
73
|
+
*/
|
|
74
|
+
removeAfterFailedToShare?: boolean;
|
|
39
75
|
}
|
|
40
76
|
|
|
41
77
|
/**
|
|
@@ -45,70 +81,8 @@ export interface EditorConfig {
|
|
|
45
81
|
* @param {EditorConfig} config: editor configuration
|
|
46
82
|
* @returns {void} A **Promise** which resolves `void`
|
|
47
83
|
*/
|
|
48
|
-
export
|
|
49
|
-
filePath
|
|
50
|
-
config: EditorConfig = {}
|
|
51
|
-
): Promise<void> {
|
|
52
|
-
if (!filePath?.trim().length) {
|
|
53
|
-
throw new Error('File path cannot be empty!');
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
const { saveToPhoto = true } = config;
|
|
57
|
-
const outputPath = await VideoTrim.showEditor(filePath, config);
|
|
58
|
-
|
|
59
|
-
if (Platform.OS === 'android') {
|
|
60
|
-
if (saveToPhoto) {
|
|
61
|
-
try {
|
|
62
|
-
if (Platform.Version >= 33) {
|
|
63
|
-
// since android 13 it's not needed to request permission for write storage: https://github.com/facebook/react-native/issues/36714#issuecomment-1491338276
|
|
64
|
-
await VideoTrim.saveVideo(outputPath);
|
|
65
|
-
|
|
66
|
-
if (config.removeAfterSavedToPhoto) {
|
|
67
|
-
deleteFile(outputPath);
|
|
68
|
-
}
|
|
69
|
-
} else {
|
|
70
|
-
const granted = await PermissionsAndroid.request(
|
|
71
|
-
PermissionsAndroid.PERMISSIONS.WRITE_EXTERNAL_STORAGE!,
|
|
72
|
-
{
|
|
73
|
-
title: 'Video Trimmer Photos Access Required',
|
|
74
|
-
message: 'Grant access to your Photos to write output Video',
|
|
75
|
-
buttonNeutral: 'Ask Me Later',
|
|
76
|
-
buttonNegative: 'Cancel',
|
|
77
|
-
buttonPositive: 'OK',
|
|
78
|
-
}
|
|
79
|
-
);
|
|
80
|
-
if (granted === PermissionsAndroid.RESULTS.GRANTED) {
|
|
81
|
-
await VideoTrim.saveVideo(outputPath);
|
|
82
|
-
|
|
83
|
-
if (config.removeAfterSavedToPhoto) {
|
|
84
|
-
deleteFile(outputPath);
|
|
85
|
-
}
|
|
86
|
-
} else {
|
|
87
|
-
throw new Error('Photos Library permission denied');
|
|
88
|
-
}
|
|
89
|
-
}
|
|
90
|
-
} catch (err) {
|
|
91
|
-
throw err;
|
|
92
|
-
} finally {
|
|
93
|
-
VideoTrim.hideDialog();
|
|
94
|
-
}
|
|
95
|
-
} else {
|
|
96
|
-
VideoTrim.hideDialog();
|
|
97
|
-
}
|
|
98
|
-
}
|
|
99
|
-
}
|
|
100
|
-
|
|
101
|
-
/**
|
|
102
|
-
* Delete a file
|
|
103
|
-
*
|
|
104
|
-
* @param {string} filePath: absolute non-empty file path to check if editable
|
|
105
|
-
* @returns {Promise} A **Promise** which resolves `true` if editable
|
|
106
|
-
*/
|
|
107
|
-
export function isValidVideo(filePath: string): Promise<boolean> {
|
|
108
|
-
if (!filePath?.trim().length) {
|
|
109
|
-
throw new Error('File path cannot be empty!');
|
|
110
|
-
}
|
|
111
|
-
return VideoTrim.isValidVideo(filePath);
|
|
84
|
+
export function showEditor(filePath: string, config: EditorConfig = {}): void {
|
|
85
|
+
VideoTrim.showEditor(filePath, config);
|
|
112
86
|
}
|
|
113
87
|
|
|
114
88
|
/**
|
|
@@ -141,3 +115,19 @@ export function deleteFile(filePath: string): Promise<boolean> {
|
|
|
141
115
|
}
|
|
142
116
|
return VideoTrim.deleteFile(filePath);
|
|
143
117
|
}
|
|
118
|
+
|
|
119
|
+
/**
|
|
120
|
+
* Close editor
|
|
121
|
+
*/
|
|
122
|
+
export function closeEditor(): void {
|
|
123
|
+
return VideoTrim.closeEditor();
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
/**
|
|
127
|
+
* Check if a file is valid audio or video file
|
|
128
|
+
*
|
|
129
|
+
* @returns {Promise} A **Promise** which resolves file info if successful
|
|
130
|
+
*/
|
|
131
|
+
export function isValidFile(url: string): Promise<boolean> {
|
|
132
|
+
return VideoTrim.isValidFile(url);
|
|
133
|
+
}
|
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
//
|
|
2
|
-
// Source code recreated from a .class file by IntelliJ IDEA
|
|
3
|
-
// (powered by FernFlower decompiler)
|
|
4
|
-
//
|
|
5
|
-
|
|
6
|
-
package iknow.android.utils;
|
|
7
|
-
|
|
8
|
-
public final class BuildConfig {
|
|
9
|
-
public static final boolean DEBUG = false;
|
|
10
|
-
public static final String APPLICATION_ID = "iknow.android.utils";
|
|
11
|
-
public static final String BUILD_TYPE = "release";
|
|
12
|
-
public static final String FLAVOR = "";
|
|
13
|
-
public static final int VERSION_CODE = 1;
|
|
14
|
-
public static final String VERSION_NAME = "1.0";
|
|
15
|
-
|
|
16
|
-
public BuildConfig() {
|
|
17
|
-
}
|
|
18
|
-
}
|
|
@@ -1,64 +0,0 @@
|
|
|
1
|
-
package iknow.android.utils;
|
|
2
|
-
|
|
3
|
-
import android.text.TextUtils;
|
|
4
|
-
|
|
5
|
-
import java.text.SimpleDateFormat;
|
|
6
|
-
import java.util.Date;
|
|
7
|
-
import java.util.Locale;
|
|
8
|
-
|
|
9
|
-
/**
|
|
10
|
-
* Author:J.Chou
|
|
11
|
-
* Date: 2016.07.21 11:43.
|
|
12
|
-
* Email: who_know_me@163.com
|
|
13
|
-
* Describe:
|
|
14
|
-
*/
|
|
15
|
-
public final class DateUtil {
|
|
16
|
-
|
|
17
|
-
/**
|
|
18
|
-
* second to HH:MM:ss
|
|
19
|
-
* @param seconds
|
|
20
|
-
* @return
|
|
21
|
-
*/
|
|
22
|
-
public static String convertSecondsToTime(long seconds) {
|
|
23
|
-
String timeStr = null;
|
|
24
|
-
int hour = 0;
|
|
25
|
-
int minute = 0;
|
|
26
|
-
int second = 0;
|
|
27
|
-
if (seconds <= 0)
|
|
28
|
-
return "00:00";
|
|
29
|
-
else {
|
|
30
|
-
minute = (int)seconds / 60;
|
|
31
|
-
if (minute < 60) {
|
|
32
|
-
second = (int)seconds % 60;
|
|
33
|
-
timeStr = unitFormat(minute) + ":" + unitFormat(second);
|
|
34
|
-
} else {
|
|
35
|
-
hour = minute / 60;
|
|
36
|
-
if (hour > 99)
|
|
37
|
-
return "99:59:59";
|
|
38
|
-
minute = minute % 60;
|
|
39
|
-
second = (int)(seconds - hour * 3600 - minute * 60);
|
|
40
|
-
timeStr = unitFormat(hour) + ":" + unitFormat(minute) + ":" + unitFormat(second);
|
|
41
|
-
}
|
|
42
|
-
}
|
|
43
|
-
return timeStr;
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
public static String convertSecondsToFormat(long seconds,String format){
|
|
47
|
-
|
|
48
|
-
if(TextUtils.isEmpty(format))
|
|
49
|
-
return "";
|
|
50
|
-
|
|
51
|
-
Date date = new Date(seconds);
|
|
52
|
-
SimpleDateFormat sdf = new SimpleDateFormat(format, Locale.getDefault());
|
|
53
|
-
return sdf.format(date);
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
private static String unitFormat(int i) {
|
|
57
|
-
String retStr = null;
|
|
58
|
-
if (i >= 0 && i < 10)
|
|
59
|
-
retStr = "0" + Integer.toString(i);
|
|
60
|
-
else
|
|
61
|
-
retStr = "" + i;
|
|
62
|
-
return retStr;
|
|
63
|
-
}
|
|
64
|
-
}
|