react-native-video-trim 1.0.24 → 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 +55 -9
- package/android/src/main/AndroidManifest.xml +15 -0
- package/android/src/main/java/com/videotrim/VideoTrimModule.java +191 -63
- package/android/src/main/java/com/videotrim/enums/ErrorCode.java +11 -0
- package/android/src/main/java/com/videotrim/interfaces/VideoTrimListener.java +6 -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 +36 -8
- package/android/src/main/java/com/videotrim/widgets/VideoTrimmerView.java +588 -308
- package/android/src/main/res/drawable/airpodsmax.xml +19 -0
- package/android/src/main/res/drawable/chevron_compact_left.xml +15 -0
- package/android/src/main/res/drawable/chevron_compact_right.xml +15 -0
- package/android/src/main/res/drawable/chevron_right_with_bg.xml +13 -0
- package/android/src/main/res/drawable/exclamationmark_triangle_fill.xml +15 -0
- package/android/src/main/res/drawable/pause_fill.xml +15 -0
- package/android/src/main/res/drawable/play_fill.xml +15 -0
- package/android/src/main/res/drawable/rounded_progress_indicator.xml +16 -0
- package/android/src/main/res/drawable/rounded_yellow_left_background.xml +8 -0
- package/android/src/main/res/drawable/rounded_yellow_right_background.xml +8 -0
- package/android/src/main/res/drawable/thumb_container_bg.xml +8 -0
- package/android/src/main/res/drawable/yellow_border.xml +9 -0
- package/android/src/main/res/layout/video_trimmer_view.xml +194 -75
- package/android/src/main/res/values/colors.xml +15 -13
- 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 +405 -168
- package/ios/VideoTrimmer.swift +16 -10
- package/ios/VideoTrimmerViewController.swift +79 -13
- 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/com/videotrim/adapters/VideoTrimmerAdapter.java +0 -54
- package/android/src/main/java/com/videotrim/widgets/RangeSeekBarView.java +0 -534
- package/android/src/main/java/com/videotrim/widgets/SpacesItemDecoration2.java +0 -33
- package/android/src/main/java/com/videotrim/widgets/ZVideoView.java +0 -48
- 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/android/src/main/res/drawable/ic_video_pause_black.png +0 -0
- package/android/src/main/res/drawable/ic_video_play_black.png +0 -0
- package/android/src/main/res/drawable/ic_video_thumb_handle.png +0 -0
- package/android/src/main/res/drawable/icon_seek_bar.png +0 -0
- package/android/src/main/res/layout/video_thumb_item_layout.xml +0 -16
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,54 +0,0 @@
|
|
|
1
|
-
package com.videotrim.adapters;
|
|
2
|
-
|
|
3
|
-
import android.content.Context;
|
|
4
|
-
import android.graphics.Bitmap;
|
|
5
|
-
import android.view.LayoutInflater;
|
|
6
|
-
import android.view.View;
|
|
7
|
-
import android.view.ViewGroup;
|
|
8
|
-
import android.widget.ImageView;
|
|
9
|
-
import android.widget.LinearLayout;
|
|
10
|
-
import androidx.annotation.NonNull;
|
|
11
|
-
import androidx.recyclerview.widget.RecyclerView;
|
|
12
|
-
import com.videotrim.R;
|
|
13
|
-
import com.videotrim.utils.VideoTrimmerUtil;
|
|
14
|
-
import java.util.ArrayList;
|
|
15
|
-
import java.util.List;
|
|
16
|
-
|
|
17
|
-
public class VideoTrimmerAdapter extends RecyclerView.Adapter {
|
|
18
|
-
private final List<Bitmap> mBitmaps = new ArrayList<>();
|
|
19
|
-
private final LayoutInflater mInflater;
|
|
20
|
-
|
|
21
|
-
public VideoTrimmerAdapter(Context context) {
|
|
22
|
-
this.mInflater = LayoutInflater.from(context);
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
@NonNull @Override public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
|
|
26
|
-
return new TrimmerViewHolder(mInflater.inflate(R.layout.video_thumb_item_layout, parent, false));
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
@Override public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, int position) {
|
|
30
|
-
((TrimmerViewHolder) holder).thumbImageView.setImageBitmap(mBitmaps.get(position));
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
@Override public int getItemCount() {
|
|
34
|
-
return mBitmaps.size();
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
public void addBitmaps(Bitmap bitmap) {
|
|
38
|
-
mBitmaps.add(bitmap);
|
|
39
|
-
notifyItemInserted(mBitmaps.size() - 1);
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
private static final class TrimmerViewHolder extends RecyclerView.ViewHolder {
|
|
43
|
-
ImageView thumbImageView;
|
|
44
|
-
|
|
45
|
-
TrimmerViewHolder(View itemView) {
|
|
46
|
-
super(itemView);
|
|
47
|
-
thumbImageView = itemView.findViewById(R.id.thumb);
|
|
48
|
-
LinearLayout.LayoutParams layoutParams = (LinearLayout.LayoutParams) thumbImageView.getLayoutParams();
|
|
49
|
-
layoutParams.width = VideoTrimmerUtil.VIDEO_FRAMES_WIDTH / VideoTrimmerUtil.MAX_COUNT_RANGE;
|
|
50
|
-
thumbImageView.setLayoutParams(layoutParams);
|
|
51
|
-
}
|
|
52
|
-
}
|
|
53
|
-
}
|
|
54
|
-
|