react-native-video-trim 4.1.0 → 5.0.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/LICENSE +1 -1
- package/README.md +89 -76
- package/VideoTrim.podspec +3 -3
- package/android/build.gradle +6 -53
- package/android/gradle.properties +1 -1
- package/android/src/main/AndroidManifest.xml +1 -1
- package/android/src/main/java/com/{margelo/nitro/videotrim/VideoTrim.kt → videotrim/VideoTrimModule.kt} +246 -232
- package/android/src/main/java/com/videotrim/VideoTrimPackage.kt +33 -0
- package/android/src/main/java/com/{margelo/nitro/videotrim → videotrim}/enums/ErrorCode.java +1 -1
- package/android/src/main/java/com/{margelo/nitro/videotrim → videotrim}/interfaces/IVideoTrimmerView.java +1 -1
- package/android/src/main/java/com/{margelo/nitro/videotrim → videotrim}/interfaces/VideoTrimListener.java +5 -4
- package/android/src/main/java/com/{margelo/nitro/videotrim → videotrim}/utils/MediaMetadataUtil.java +1 -1
- package/android/src/main/java/com/{margelo/nitro/videotrim → videotrim}/utils/StorageUtil.java +1 -1
- package/android/src/main/java/com/{margelo/nitro/videotrim → videotrim}/utils/VideoTrimmerUtil.java +20 -18
- package/android/src/main/java/com/{margelo/nitro/videotrim → videotrim}/widgets/VideoTrimmerView.java +44 -45
- package/ios/AssetLoader.h +19 -0
- package/ios/AssetLoader.mm +87 -0
- package/ios/ErrorCode.h +9 -0
- package/ios/ProgressAlertController.h +15 -0
- package/ios/ProgressAlertController.mm +78 -0
- package/ios/VideoTrim.h +31 -0
- package/ios/VideoTrim.mm +663 -0
- package/ios/VideoTrimmer.h +67 -0
- package/ios/VideoTrimmer.mm +863 -0
- package/ios/VideoTrimmerThumb.h +23 -0
- package/ios/VideoTrimmerThumb.mm +175 -0
- package/ios/VideoTrimmerViewController.h +52 -0
- package/ios/VideoTrimmerViewController.mm +533 -0
- package/lib/module/NativeVideoTrim.js +5 -0
- package/lib/module/NativeVideoTrim.js.map +1 -0
- package/lib/module/index.js +22 -24
- package/lib/module/index.js.map +1 -1
- package/lib/typescript/src/NativeVideoTrim.d.ts +107 -0
- package/lib/typescript/src/NativeVideoTrim.d.ts.map +1 -0
- package/lib/typescript/src/index.d.ts +13 -10
- package/lib/typescript/src/index.d.ts.map +1 -1
- package/package.json +15 -18
- package/src/NativeVideoTrim.ts +113 -0
- package/src/index.tsx +26 -31
- package/android/CMakeLists.txt +0 -24
- package/android/src/main/cpp/cpp-adapter.cpp +0 -6
- package/android/src/main/java/com/margelo/nitro/videotrim/VideoTrimPackage.kt +0 -22
- package/ios/AssetLoader.swift +0 -99
- package/ios/ErrorCode.swift +0 -17
- package/ios/ProgressAlertController.swift +0 -100
- package/ios/VideoTrim.swift +0 -67
- package/ios/VideoTrimImpl.swift +0 -957
- package/ios/VideoTrimmer.swift +0 -872
- package/ios/VideoTrimmerThumb.swift +0 -175
- package/ios/VideoTrimmerViewController.swift +0 -557
- package/lib/module/VideoTrim.nitro.js +0 -4
- package/lib/module/VideoTrim.nitro.js.map +0 -1
- package/lib/typescript/src/VideoTrim.nitro.d.ts +0 -257
- package/lib/typescript/src/VideoTrim.nitro.d.ts.map +0 -1
- package/nitrogen/generated/android/c++/JEditorConfig.hpp +0 -237
- package/nitrogen/generated/android/c++/JFileValidationResult.hpp +0 -61
- package/nitrogen/generated/android/c++/JFunc_void.hpp +0 -74
- package/nitrogen/generated/android/c++/JFunc_void_std__string_std__unordered_map_std__string__std__string_.hpp +0 -89
- package/nitrogen/generated/android/c++/JHybridVideoTrimSpec.cpp +0 -151
- package/nitrogen/generated/android/c++/JHybridVideoTrimSpec.hpp +0 -68
- package/nitrogen/generated/android/c++/JTrimOptions.hpp +0 -109
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/videotrim/EditorConfig.kt +0 -72
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/videotrim/FileValidationResult.kt +0 -28
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/videotrim/Func_void.kt +0 -80
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/videotrim/Func_void_std__string_std__unordered_map_std__string__std__string_.kt +0 -80
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/videotrim/HybridVideoTrimSpec.kt +0 -86
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/videotrim/TrimOptions.kt +0 -40
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/videotrim/videotrimOnLoad.kt +0 -35
- package/nitrogen/generated/android/videotrim+autolinking.cmake +0 -78
- package/nitrogen/generated/android/videotrim+autolinking.gradle +0 -27
- package/nitrogen/generated/android/videotrimOnLoad.cpp +0 -50
- package/nitrogen/generated/android/videotrimOnLoad.hpp +0 -25
- package/nitrogen/generated/ios/VideoTrim+autolinking.rb +0 -60
- package/nitrogen/generated/ios/VideoTrim-Swift-Cxx-Bridge.cpp +0 -96
- package/nitrogen/generated/ios/VideoTrim-Swift-Cxx-Bridge.hpp +0 -374
- package/nitrogen/generated/ios/VideoTrim-Swift-Cxx-Umbrella.hpp +0 -56
- package/nitrogen/generated/ios/VideoTrimAutolinking.mm +0 -33
- package/nitrogen/generated/ios/VideoTrimAutolinking.swift +0 -25
- package/nitrogen/generated/ios/c++/HybridVideoTrimSpecSwift.cpp +0 -11
- package/nitrogen/generated/ios/c++/HybridVideoTrimSpecSwift.hpp +0 -127
- package/nitrogen/generated/ios/swift/EditorConfig.swift +0 -541
- package/nitrogen/generated/ios/swift/FileValidationResult.swift +0 -57
- package/nitrogen/generated/ios/swift/Func_void.swift +0 -46
- package/nitrogen/generated/ios/swift/Func_void_FileValidationResult.swift +0 -46
- package/nitrogen/generated/ios/swift/Func_void_bool.swift +0 -46
- package/nitrogen/generated/ios/swift/Func_void_double.swift +0 -46
- package/nitrogen/generated/ios/swift/Func_void_std__exception_ptr.swift +0 -46
- package/nitrogen/generated/ios/swift/Func_void_std__string.swift +0 -46
- package/nitrogen/generated/ios/swift/Func_void_std__string_std__unordered_map_std__string__std__string_.swift +0 -54
- package/nitrogen/generated/ios/swift/Func_void_std__vector_std__string_.swift +0 -46
- package/nitrogen/generated/ios/swift/HybridVideoTrimSpec.swift +0 -54
- package/nitrogen/generated/ios/swift/HybridVideoTrimSpec_cxx.swift +0 -241
- package/nitrogen/generated/ios/swift/TrimOptions.swift +0 -189
- package/nitrogen/generated/shared/c++/EditorConfig.hpp +0 -253
- package/nitrogen/generated/shared/c++/FileValidationResult.hpp +0 -77
- package/nitrogen/generated/shared/c++/HybridVideoTrimSpec.cpp +0 -27
- package/nitrogen/generated/shared/c++/HybridVideoTrimSpec.hpp +0 -80
- package/nitrogen/generated/shared/c++/TrimOptions.hpp +0 -125
- package/src/VideoTrim.nitro.ts +0 -263
|
@@ -0,0 +1,533 @@
|
|
|
1
|
+
#import "VideoTrimmerViewController.h"
|
|
2
|
+
#import "VideoTrimmer.h"
|
|
3
|
+
#import <AVFoundation/AVFoundation.h>
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
@implementation VideoTrimmerViewController
|
|
7
|
+
|
|
8
|
+
- (instancetype)init {
|
|
9
|
+
if (self = [super init]) {
|
|
10
|
+
self.cancelButtonText = @"Cancel";
|
|
11
|
+
self.saveButtonText = @"Save";
|
|
12
|
+
self.headerTextSize = 16;
|
|
13
|
+
self.headerTextColor = 0xFFFFFF;
|
|
14
|
+
self.autoplay = NO;
|
|
15
|
+
self.jumpToPositionOnLoad = 0;
|
|
16
|
+
self.enableHapticFeedback = YES;
|
|
17
|
+
self.chaseTime = kCMTimeZero;
|
|
18
|
+
self.isSeekInProgress = NO;
|
|
19
|
+
self.playerController = [[AVPlayerViewController alloc] init];
|
|
20
|
+
self.loadingIndicator = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleMedium];
|
|
21
|
+
}
|
|
22
|
+
return self;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
- (void)setAsset:(AVAsset *)asset {
|
|
26
|
+
NSLog(@"📱 VideoTrimmerViewController setAsset called with: %@", asset);
|
|
27
|
+
|
|
28
|
+
_asset = asset;
|
|
29
|
+
if (asset) {
|
|
30
|
+
[self setupVideoTrimmer];
|
|
31
|
+
[self setupPlayerController];
|
|
32
|
+
[self setupTimeObserver];
|
|
33
|
+
[self updateLabels];
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
- (AVPlayer *)player {
|
|
38
|
+
return self.playerController.player;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
- (void)onAssetFailToLoad {
|
|
42
|
+
[self.loadingIndicator stopAnimating];
|
|
43
|
+
[self.btnStackView removeArrangedSubview:self.loadingIndicator];
|
|
44
|
+
[self.loadingIndicator removeFromSuperview];
|
|
45
|
+
|
|
46
|
+
UIView *imageViewContainer = [[UIView alloc] init];
|
|
47
|
+
UIImageView *imageView = [[UIImageView alloc] initWithImage:[UIImage systemImageNamed:@"exclamationmark.triangle.fill"]];
|
|
48
|
+
imageView.tintColor = [UIColor systemYellowColor];
|
|
49
|
+
imageView.translatesAutoresizingMaskIntoConstraints = NO;
|
|
50
|
+
|
|
51
|
+
[imageViewContainer addSubview:imageView];
|
|
52
|
+
[NSLayoutConstraint activateConstraints:@[
|
|
53
|
+
[imageView.widthAnchor constraintEqualToConstant:36],
|
|
54
|
+
[imageView.heightAnchor constraintEqualToConstant:36],
|
|
55
|
+
[imageView.centerXAnchor constraintEqualToAnchor:imageViewContainer.centerXAnchor],
|
|
56
|
+
[imageView.centerYAnchor constraintEqualToAnchor:imageViewContainer.centerYAnchor]
|
|
57
|
+
]];
|
|
58
|
+
imageViewContainer.alpha = 0;
|
|
59
|
+
|
|
60
|
+
[self.btnStackView insertArrangedSubview:imageViewContainer atIndex:1];
|
|
61
|
+
|
|
62
|
+
[UIView animateWithDuration:0.25 animations:^{
|
|
63
|
+
imageViewContainer.alpha = 1;
|
|
64
|
+
}];
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
- (void)didBeginTrimmingFromStart:(VideoTrimmer *)sender {
|
|
68
|
+
[self handleBeforeProgressChange];
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
- (void)leadingGrabberChanged:(VideoTrimmer *)sender {
|
|
72
|
+
[self handleProgressChanged:self.trimmer.selectedRange.start];
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
- (void)didEndTrimmingFromStart:(VideoTrimmer *)sender {
|
|
76
|
+
[self handleTrimmingEnd:YES];
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
- (void)didBeginTrimmingFromEnd:(VideoTrimmer *)sender {
|
|
80
|
+
[self handleBeforeProgressChange];
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
- (void)trailingGrabberChanged:(VideoTrimmer *)sender {
|
|
84
|
+
[self handleProgressChanged:CMTimeRangeGetEnd(self.trimmer.selectedRange)];
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
- (void)didEndTrimmingFromEnd:(VideoTrimmer *)sender {
|
|
88
|
+
[self handleTrimmingEnd:NO];
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
- (void)didBeginScrubbing:(VideoTrimmer *)sender {
|
|
92
|
+
[self handleBeforeProgressChange];
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
- (void)didEndScrubbing:(VideoTrimmer *)sender {
|
|
96
|
+
[self updateLabels];
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
- (void)progressDidChanged:(VideoTrimmer *)sender {
|
|
100
|
+
[self handleProgressChanged:self.trimmer.progress];
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
- (void)updateLabels {
|
|
104
|
+
self.leadingTrimLabel.text = [self displayStringFromCMTime:self.trimmer.selectedRange.start];
|
|
105
|
+
self.currentTimeLabel.text = [self displayStringFromCMTime:self.trimmer.progress];
|
|
106
|
+
self.trailingTrimLabel.text = [self displayStringFromCMTime:CMTimeRangeGetEnd(self.trimmer.selectedRange)];
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
- (NSString *)displayStringFromCMTime:(CMTime)time {
|
|
110
|
+
NSTimeInterval offset = CMTimeGetSeconds(time);
|
|
111
|
+
double numberOfNanosecondsFloat = (offset - (NSTimeInterval)((int)offset)) * 100.0;
|
|
112
|
+
int nanoseconds = (int)numberOfNanosecondsFloat;
|
|
113
|
+
|
|
114
|
+
NSDateComponentsFormatter *formatter = [[NSDateComponentsFormatter alloc] init];
|
|
115
|
+
formatter.unitsStyle = NSDateComponentsFormatterUnitsStylePositional;
|
|
116
|
+
formatter.zeroFormattingBehavior = NSDateComponentsFormatterZeroFormattingBehaviorPad;
|
|
117
|
+
formatter.allowedUnits = NSCalendarUnitMinute | NSCalendarUnitSecond;
|
|
118
|
+
|
|
119
|
+
NSString *timeString = [formatter stringFromTimeInterval:offset] ?: @"00:00";
|
|
120
|
+
return [NSString stringWithFormat:@"%@.%02d", timeString, nanoseconds];
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
- (void)handleBeforeProgressChange {
|
|
124
|
+
[self updateLabels];
|
|
125
|
+
[self.player pause];
|
|
126
|
+
[self setPlayBtnIcon];
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
- (void)handleProgressChanged:(CMTime)time {
|
|
130
|
+
[self updateLabels];
|
|
131
|
+
[self seek:time];
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
- (void)handleTrimmingEnd:(BOOL)start {
|
|
135
|
+
self.trimmer.progress = start ? self.trimmer.selectedRange.start : CMTimeRangeGetEnd(self.trimmer.selectedRange);
|
|
136
|
+
[self updateLabels];
|
|
137
|
+
[self seek:self.trimmer.progress];
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
- (void)viewDidLoad {
|
|
141
|
+
[super viewDidLoad];
|
|
142
|
+
[self setupView];
|
|
143
|
+
[self setupButtons];
|
|
144
|
+
[self setupTimeLabels];
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
- (void)viewWillDisappear:(BOOL)animated {
|
|
148
|
+
[super viewWillDisappear:animated];
|
|
149
|
+
|
|
150
|
+
if (!self.asset) return;
|
|
151
|
+
[self.player pause];
|
|
152
|
+
|
|
153
|
+
[self.player removeObserver:self forKeyPath:@"status"];
|
|
154
|
+
|
|
155
|
+
if (self.timeObserverToken) {
|
|
156
|
+
[self.player removeTimeObserver:self.timeObserverToken];
|
|
157
|
+
self.timeObserverToken = nil;
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
[[NSNotificationCenter defaultCenter] removeObserver:self name:AVPlayerItemDidPlayToEndTimeNotification object:self.player.currentItem];
|
|
161
|
+
|
|
162
|
+
self.playerController.player = nil;
|
|
163
|
+
[self.playerController dismissViewControllerAnimated:NO completion:nil];
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
- (void)pausePlayer {
|
|
167
|
+
[self.player pause];
|
|
168
|
+
[self setPlayBtnIcon];
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
- (void)togglePlay:(UIButton *)sender {
|
|
172
|
+
if (self.player.timeControlStatus == AVPlayerTimeControlStatusPlaying) {
|
|
173
|
+
[self.player pause];
|
|
174
|
+
} else {
|
|
175
|
+
if (CMTimeCompare(self.trimmer.progress, CMTimeRangeGetEnd(self.trimmer.selectedRange)) != -1) {
|
|
176
|
+
self.trimmer.progress = self.trimmer.selectedRange.start;
|
|
177
|
+
[self seek:self.trimmer.progress];
|
|
178
|
+
}
|
|
179
|
+
[self.player play];
|
|
180
|
+
}
|
|
181
|
+
[self setPlayBtnIcon];
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
- (void)onSaveBtnClicked {
|
|
185
|
+
if (self.saveBtnClicked) {
|
|
186
|
+
self.saveBtnClicked(self.trimmer.selectedRange);
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
- (void)onCancelBtnClicked {
|
|
191
|
+
if (self.cancelBtnClicked) {
|
|
192
|
+
self.cancelBtnClicked();
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
- (UIColor *)colorFromHex:(double)hex defaultColor:(UIColor *)defaultColor {
|
|
197
|
+
int32_t hexValue = (int32_t)hex;
|
|
198
|
+
CGFloat red = ((hexValue >> 16) & 0xFF) / 255.0;
|
|
199
|
+
CGFloat green = ((hexValue >> 8) & 0xFF) / 255.0;
|
|
200
|
+
CGFloat blue = (hexValue & 0xFF) / 255.0;
|
|
201
|
+
CGFloat alpha = (hexValue > 0xFFFFFF) ? ((hexValue >> 24) & 0xFF) / 255.0 : 1.0;
|
|
202
|
+
return [UIColor colorWithRed:red green:green blue:blue alpha:alpha];
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
- (UIButton *)createButtonWithTitle:(NSString *)title
|
|
206
|
+
font:(UIFont *)font
|
|
207
|
+
titleColor:(UIColor *)titleColor
|
|
208
|
+
image:(UIImage *)image
|
|
209
|
+
tintColor:(UIColor *)tintColor
|
|
210
|
+
target:(id)target
|
|
211
|
+
action:(SEL)action {
|
|
212
|
+
UIButton *button = [UIButton buttonWithType:UIButtonTypeSystem];
|
|
213
|
+
if (title) [button setTitle:title forState:UIControlStateNormal];
|
|
214
|
+
if (image) [button setImage:image forState:UIControlStateNormal];
|
|
215
|
+
if (font) button.titleLabel.font = font;
|
|
216
|
+
if (titleColor) [button setTitleColor:titleColor forState:UIControlStateNormal];
|
|
217
|
+
if (tintColor) button.tintColor = tintColor;
|
|
218
|
+
[button addTarget:target action:action forControlEvents:UIControlEventTouchUpInside];
|
|
219
|
+
return button;
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
- (UILabel *)createLabelWithAlignment:(NSTextAlignment)alignment textColor:(UIColor *)color {
|
|
223
|
+
UILabel *label = [[UILabel alloc] init];
|
|
224
|
+
label.font = [UIFont preferredFontForTextStyle:UIFontTextStyleCaption1];
|
|
225
|
+
label.textAlignment = alignment;
|
|
226
|
+
label.textColor = color;
|
|
227
|
+
return label;
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
- (void)setupView {
|
|
231
|
+
self.overrideUserInterfaceStyle = UIUserInterfaceStyleDark;
|
|
232
|
+
self.view.backgroundColor = [UIColor blackColor];
|
|
233
|
+
|
|
234
|
+
if (self.headerText) {
|
|
235
|
+
self.headerView = [[UIView alloc] init];
|
|
236
|
+
self.headerView.translatesAutoresizingMaskIntoConstraints = NO;
|
|
237
|
+
[self.view addSubview:self.headerView];
|
|
238
|
+
|
|
239
|
+
UITextView *headerTextView = [[UITextView alloc] init];
|
|
240
|
+
headerTextView.text = self.headerText;
|
|
241
|
+
headerTextView.textAlignment = NSTextAlignmentCenter;
|
|
242
|
+
headerTextView.textColor = [self colorFromHex:self.headerTextColor defaultColor:[UIColor whiteColor]];
|
|
243
|
+
headerTextView.font = [UIFont systemFontOfSize:self.headerTextSize];
|
|
244
|
+
headerTextView.translatesAutoresizingMaskIntoConstraints = NO;
|
|
245
|
+
[self.headerView addSubview:headerTextView];
|
|
246
|
+
|
|
247
|
+
[NSLayoutConstraint activateConstraints:@[
|
|
248
|
+
[self.headerView.topAnchor constraintEqualToAnchor:self.view.safeAreaLayoutGuide.topAnchor],
|
|
249
|
+
[self.headerView.leadingAnchor constraintEqualToAnchor:self.view.leadingAnchor],
|
|
250
|
+
[self.headerView.trailingAnchor constraintEqualToAnchor:self.view.trailingAnchor],
|
|
251
|
+
[self.headerView.heightAnchor constraintGreaterThanOrEqualToConstant:50],
|
|
252
|
+
|
|
253
|
+
[headerTextView.topAnchor constraintEqualToAnchor:self.headerView.topAnchor],
|
|
254
|
+
[headerTextView.bottomAnchor constraintEqualToAnchor:self.headerView.bottomAnchor],
|
|
255
|
+
[headerTextView.leadingAnchor constraintEqualToAnchor:self.headerView.leadingAnchor],
|
|
256
|
+
[headerTextView.trailingAnchor constraintEqualToAnchor:self.headerView.trailingAnchor],
|
|
257
|
+
]];
|
|
258
|
+
|
|
259
|
+
[self.view layoutIfNeeded];
|
|
260
|
+
}
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
- (void)setupButtons {
|
|
264
|
+
self.cancelBtn = [self createButtonWithTitle:self.cancelButtonText
|
|
265
|
+
font:[UIFont systemFontOfSize:18]
|
|
266
|
+
titleColor:[UIColor whiteColor]
|
|
267
|
+
image:nil
|
|
268
|
+
tintColor:nil
|
|
269
|
+
target:self
|
|
270
|
+
action:@selector(onCancelBtnClicked)];
|
|
271
|
+
|
|
272
|
+
self.playBtn = [self createButtonWithTitle:nil
|
|
273
|
+
font:nil
|
|
274
|
+
titleColor:nil
|
|
275
|
+
image:[UIImage systemImageNamed:@"play.fill"]
|
|
276
|
+
tintColor:[UIColor whiteColor]
|
|
277
|
+
target:self
|
|
278
|
+
action:@selector(togglePlay:)];
|
|
279
|
+
self.playBtn.alpha = 0;
|
|
280
|
+
self.playBtn.enabled = NO;
|
|
281
|
+
|
|
282
|
+
self.saveBtn = [self createButtonWithTitle:self.saveButtonText
|
|
283
|
+
font:[UIFont systemFontOfSize:18]
|
|
284
|
+
titleColor:[UIColor systemBlueColor]
|
|
285
|
+
image:nil
|
|
286
|
+
tintColor:nil
|
|
287
|
+
target:self
|
|
288
|
+
action:@selector(onSaveBtnClicked)];
|
|
289
|
+
self.saveBtn.alpha = 0;
|
|
290
|
+
self.saveBtn.enabled = NO;
|
|
291
|
+
|
|
292
|
+
[self.loadingIndicator startAnimating];
|
|
293
|
+
|
|
294
|
+
self.btnStackView = [[UIStackView alloc] initWithArrangedSubviews:@[self.cancelBtn, self.loadingIndicator, self.saveBtn]];
|
|
295
|
+
self.btnStackView.axis = UILayoutConstraintAxisHorizontal;
|
|
296
|
+
self.btnStackView.alignment = UIStackViewAlignmentCenter;
|
|
297
|
+
self.btnStackView.distribution = UIStackViewDistributionFillEqually;
|
|
298
|
+
self.btnStackView.spacing = UIStackViewSpacingUseSystem;
|
|
299
|
+
self.btnStackView.translatesAutoresizingMaskIntoConstraints = NO;
|
|
300
|
+
|
|
301
|
+
[self.view addSubview:self.btnStackView];
|
|
302
|
+
|
|
303
|
+
[NSLayoutConstraint activateConstraints:@[
|
|
304
|
+
[self.btnStackView.leadingAnchor constraintEqualToAnchor:self.view.safeAreaLayoutGuide.leadingAnchor constant:16],
|
|
305
|
+
[self.btnStackView.trailingAnchor constraintEqualToAnchor:self.view.safeAreaLayoutGuide.trailingAnchor constant:-16],
|
|
306
|
+
[self.btnStackView.bottomAnchor constraintEqualToAnchor:self.view.safeAreaLayoutGuide.bottomAnchor constant:-16]
|
|
307
|
+
]];
|
|
308
|
+
}
|
|
309
|
+
|
|
310
|
+
- (void)setupTimeLabels {
|
|
311
|
+
self.leadingTrimLabel = [self createLabelWithAlignment:NSTextAlignmentLeft textColor:[UIColor whiteColor]];
|
|
312
|
+
self.leadingTrimLabel.text = @"00:00.000";
|
|
313
|
+
|
|
314
|
+
self.currentTimeLabel = [self createLabelWithAlignment:NSTextAlignmentCenter textColor:[UIColor whiteColor]];
|
|
315
|
+
self.currentTimeLabel.text = @"00:00.000";
|
|
316
|
+
|
|
317
|
+
self.trailingTrimLabel = [self createLabelWithAlignment:NSTextAlignmentRight textColor:[UIColor whiteColor]];
|
|
318
|
+
self.trailingTrimLabel.text = @"00:00.000";
|
|
319
|
+
|
|
320
|
+
self.timingStackView = [[UIStackView alloc] initWithArrangedSubviews:@[self.leadingTrimLabel, self.currentTimeLabel, self.trailingTrimLabel]];
|
|
321
|
+
self.timingStackView.axis = UILayoutConstraintAxisHorizontal;
|
|
322
|
+
self.timingStackView.alignment = UIStackViewAlignmentFill;
|
|
323
|
+
self.timingStackView.distribution = UIStackViewDistributionFillEqually;
|
|
324
|
+
self.timingStackView.spacing = UIStackViewSpacingUseSystem;
|
|
325
|
+
self.timingStackView.translatesAutoresizingMaskIntoConstraints = NO;
|
|
326
|
+
|
|
327
|
+
[self.view addSubview:self.timingStackView];
|
|
328
|
+
|
|
329
|
+
[NSLayoutConstraint activateConstraints:@[
|
|
330
|
+
[self.timingStackView.leadingAnchor constraintEqualToAnchor:self.view.safeAreaLayoutGuide.leadingAnchor constant:16],
|
|
331
|
+
[self.timingStackView.trailingAnchor constraintEqualToAnchor:self.view.safeAreaLayoutGuide.trailingAnchor constant:-16],
|
|
332
|
+
[self.timingStackView.bottomAnchor constraintEqualToAnchor:self.btnStackView.topAnchor constant:-8]
|
|
333
|
+
]];
|
|
334
|
+
}
|
|
335
|
+
|
|
336
|
+
- (void)setupVideoTrimmer {
|
|
337
|
+
self.trimmer = [[VideoTrimmer alloc] init];
|
|
338
|
+
self.trimmer.asset = self.asset;
|
|
339
|
+
self.trimmer.minimumDuration = CMTimeMake(1 * 600, 600); // 1 second
|
|
340
|
+
self.trimmer.enableHapticFeedback = self.enableHapticFeedback;
|
|
341
|
+
|
|
342
|
+
if (self.maximumDuration > 0) {
|
|
343
|
+
CMTime maxDuration = CMTimeMake(MAX(1, self.maximumDuration) * 600, 600);
|
|
344
|
+
if (CMTimeCompare(maxDuration, self.asset.duration) > 0) {
|
|
345
|
+
maxDuration = self.asset.duration;
|
|
346
|
+
}
|
|
347
|
+
self.trimmer.maximumDuration = maxDuration;
|
|
348
|
+
self.trimmer.selectedRange = CMTimeRangeMake(kCMTimeZero, maxDuration);
|
|
349
|
+
}
|
|
350
|
+
|
|
351
|
+
if (self.minimumDuration > 0) {
|
|
352
|
+
self.trimmer.minimumDuration = CMTimeMake(MAX(1, self.minimumDuration) * 600, 600);
|
|
353
|
+
}
|
|
354
|
+
|
|
355
|
+
// Add target-action for all VideoTrimmer custom events
|
|
356
|
+
[self.trimmer addTarget:self action:@selector(didBeginScrubbing:) forControlEvents:[VideoTrimmer didBeginScrubbing]];
|
|
357
|
+
[self.trimmer addTarget:self action:@selector(didEndScrubbing:) forControlEvents:[VideoTrimmer didEndScrubbing]];
|
|
358
|
+
[self.trimmer addTarget:self action:@selector(progressDidChanged:) forControlEvents:[VideoTrimmer progressChanged]];
|
|
359
|
+
|
|
360
|
+
[self.trimmer addTarget:self action:@selector(didBeginTrimmingFromStart:) forControlEvents:[VideoTrimmer didBeginTrimmingFromStart]];
|
|
361
|
+
[self.trimmer addTarget:self action:@selector(leadingGrabberChanged:) forControlEvents:[VideoTrimmer leadingGrabberChanged]];
|
|
362
|
+
[self.trimmer addTarget:self action:@selector(didEndTrimmingFromStart:) forControlEvents:[VideoTrimmer didEndTrimmingFromStart]];
|
|
363
|
+
|
|
364
|
+
[self.trimmer addTarget:self action:@selector(didBeginTrimmingFromEnd:) forControlEvents:[VideoTrimmer didBeginTrimmingFromEnd]];
|
|
365
|
+
[self.trimmer addTarget:self action:@selector(trailingGrabberChanged:) forControlEvents:[VideoTrimmer trailingGrabberChanged]];
|
|
366
|
+
[self.trimmer addTarget:self action:@selector(didEndTrimmingFromEnd:) forControlEvents:[VideoTrimmer didEndTrimmingFromEnd]];
|
|
367
|
+
|
|
368
|
+
self.trimmer.alpha = 0;
|
|
369
|
+
self.trimmer.translatesAutoresizingMaskIntoConstraints = NO;
|
|
370
|
+
[self.view addSubview:self.trimmer];
|
|
371
|
+
|
|
372
|
+
[NSLayoutConstraint activateConstraints:@[
|
|
373
|
+
[self.trimmer.leadingAnchor constraintEqualToAnchor:self.view.safeAreaLayoutGuide.leadingAnchor],
|
|
374
|
+
[self.trimmer.trailingAnchor constraintEqualToAnchor:self.view.safeAreaLayoutGuide.trailingAnchor],
|
|
375
|
+
[self.trimmer.bottomAnchor constraintEqualToAnchor:self.timingStackView.topAnchor constant:-16],
|
|
376
|
+
[self.trimmer.heightAnchor constraintEqualToConstant:50]
|
|
377
|
+
]];
|
|
378
|
+
|
|
379
|
+
[UIView animateWithDuration:0.25 animations:^{
|
|
380
|
+
self.trimmer.alpha = 1;
|
|
381
|
+
}];
|
|
382
|
+
}
|
|
383
|
+
|
|
384
|
+
- (void)setupPlayerController {
|
|
385
|
+
self.playerController.showsPlaybackControls = NO;
|
|
386
|
+
if (@available(iOS 16.0, *)) {
|
|
387
|
+
self.playerController.allowsVideoFrameAnalysis = NO;
|
|
388
|
+
}
|
|
389
|
+
self.playerController.player = [[AVPlayer alloc] init];
|
|
390
|
+
[self.player replaceCurrentItemWithPlayerItem:[AVPlayerItem playerItemWithAsset:self.asset]];
|
|
391
|
+
|
|
392
|
+
[self.player addObserver:self forKeyPath:@"status" options:NSKeyValueObservingOptionNew | NSKeyValueObservingOptionInitial context:nil];
|
|
393
|
+
|
|
394
|
+
NSError *error = nil;
|
|
395
|
+
[[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryPlayback mode:AVAudioSessionModeDefault options:0 error:&error];
|
|
396
|
+
if (error) {
|
|
397
|
+
NSLog(@"AVAudioSession error: %@", error);
|
|
398
|
+
}
|
|
399
|
+
|
|
400
|
+
[self addChildViewController:self.playerController];
|
|
401
|
+
[self.view addSubview:self.playerController.view];
|
|
402
|
+
self.playerController.view.translatesAutoresizingMaskIntoConstraints = NO;
|
|
403
|
+
|
|
404
|
+
[NSLayoutConstraint activateConstraints:@[
|
|
405
|
+
[self.playerController.view.leadingAnchor constraintEqualToAnchor:self.view.leadingAnchor],
|
|
406
|
+
[self.playerController.view.trailingAnchor constraintEqualToAnchor:self.view.trailingAnchor],
|
|
407
|
+
[self.playerController.view.topAnchor constraintEqualToAnchor:self.headerView ? self.headerView.bottomAnchor : self.view.safeAreaLayoutGuide.topAnchor],
|
|
408
|
+
[self.playerController.view.bottomAnchor constraintEqualToAnchor:self.trimmer.topAnchor constant:-16]
|
|
409
|
+
]];
|
|
410
|
+
|
|
411
|
+
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(playerDidFinishPlaying:) name:AVPlayerItemDidPlayToEndTimeNotification object:self.player.currentItem];
|
|
412
|
+
}
|
|
413
|
+
|
|
414
|
+
- (void)playerDidFinishPlaying:(NSNotification *)notification {
|
|
415
|
+
[self.playBtn setImage:[UIImage systemImageNamed:@"play.fill"] forState:UIControlStateNormal];
|
|
416
|
+
}
|
|
417
|
+
|
|
418
|
+
- (void)setupTimeObserver {
|
|
419
|
+
__weak __typeof__(self) weakSelf = self;
|
|
420
|
+
self.timeObserverToken = [self.player addPeriodicTimeObserverForInterval:CMTimeMake(1, 30) queue:dispatch_get_main_queue() usingBlock:^(CMTime time) {
|
|
421
|
+
if (weakSelf.player.timeControlStatus != AVPlayerTimeControlStatusPlaying) {
|
|
422
|
+
return;
|
|
423
|
+
}
|
|
424
|
+
|
|
425
|
+
weakSelf.trimmer.progress = time;
|
|
426
|
+
|
|
427
|
+
if (CMTimeCompare(weakSelf.trimmer.progress, CMTimeRangeGetEnd(weakSelf.trimmer.selectedRange)) == 1) {
|
|
428
|
+
[weakSelf.player pause];
|
|
429
|
+
weakSelf.trimmer.progress = CMTimeRangeGetEnd(weakSelf.trimmer.selectedRange);
|
|
430
|
+
[weakSelf seek:CMTimeRangeGetEnd(weakSelf.trimmer.selectedRange)];
|
|
431
|
+
}
|
|
432
|
+
|
|
433
|
+
weakSelf.currentTimeLabel.text = [weakSelf displayStringFromCMTime:weakSelf.trimmer.progress];
|
|
434
|
+
[weakSelf setPlayBtnIcon];
|
|
435
|
+
}];
|
|
436
|
+
}
|
|
437
|
+
|
|
438
|
+
- (void)setPlayBtnIcon {
|
|
439
|
+
UIImage *icon = (self.player.timeControlStatus == AVPlayerTimeControlStatusPlaying) ?
|
|
440
|
+
[UIImage systemImageNamed:@"pause.fill"] :
|
|
441
|
+
[UIImage systemImageNamed:@"play.fill"];
|
|
442
|
+
[self.playBtn setImage:icon forState:UIControlStateNormal];
|
|
443
|
+
}
|
|
444
|
+
|
|
445
|
+
- (void)seek:(CMTime)time {
|
|
446
|
+
[self seekSmoothlyToTime:time];
|
|
447
|
+
}
|
|
448
|
+
|
|
449
|
+
- (void)seekSmoothlyToTime:(CMTime)newChaseTime {
|
|
450
|
+
if (CMTimeCompare(newChaseTime, self.chaseTime) != 0) {
|
|
451
|
+
self.chaseTime = newChaseTime;
|
|
452
|
+
|
|
453
|
+
if (!self.isSeekInProgress) {
|
|
454
|
+
[self trySeekToChaseTime];
|
|
455
|
+
}
|
|
456
|
+
}
|
|
457
|
+
}
|
|
458
|
+
|
|
459
|
+
- (void)trySeekToChaseTime {
|
|
460
|
+
if (self.player.status != AVPlayerStatusReadyToPlay) return;
|
|
461
|
+
[self actuallySeekToTime];
|
|
462
|
+
}
|
|
463
|
+
|
|
464
|
+
- (void)actuallySeekToTime {
|
|
465
|
+
self.isSeekInProgress = YES;
|
|
466
|
+
CMTime seekTimeInProgress = self.chaseTime;
|
|
467
|
+
|
|
468
|
+
[self.player seekToTime:seekTimeInProgress toleranceBefore:kCMTimeZero toleranceAfter:kCMTimeZero completionHandler:^(BOOL finished) {
|
|
469
|
+
if (CMTimeCompare(seekTimeInProgress, self.chaseTime) == 0) {
|
|
470
|
+
self.isSeekInProgress = NO;
|
|
471
|
+
} else {
|
|
472
|
+
[self trySeekToChaseTime];
|
|
473
|
+
}
|
|
474
|
+
}];
|
|
475
|
+
}
|
|
476
|
+
|
|
477
|
+
- (void)configureWithConfig:(JS::NativeVideoTrim::EditorConfig)config {
|
|
478
|
+
if (config.maxDuration() > 0) {
|
|
479
|
+
self.maximumDuration = (NSInteger)config.maxDuration();
|
|
480
|
+
}
|
|
481
|
+
|
|
482
|
+
if (config.minDuration() > 0) {
|
|
483
|
+
self.minimumDuration = (NSInteger)config.minDuration();
|
|
484
|
+
}
|
|
485
|
+
|
|
486
|
+
self.cancelButtonText = config.cancelButtonText();
|
|
487
|
+
self.saveButtonText = config.saveButtonText();
|
|
488
|
+
self.jumpToPositionOnLoad = config.jumpToPositionOnLoad();
|
|
489
|
+
|
|
490
|
+
self.enableHapticFeedback = config.enableHapticFeedback();
|
|
491
|
+
self.autoplay = config.autoplay();
|
|
492
|
+
|
|
493
|
+
NSString *headerText = config.headerText();
|
|
494
|
+
if (headerText && headerText.length > 0) {
|
|
495
|
+
self.headerText = headerText;
|
|
496
|
+
self.headerTextSize = (NSInteger)config.headerTextSize();
|
|
497
|
+
self.headerTextColor = config.headerTextColor();
|
|
498
|
+
}
|
|
499
|
+
}
|
|
500
|
+
|
|
501
|
+
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary<NSKeyValueChangeKey,id> *)change context:(void *)context {
|
|
502
|
+
if ([keyPath isEqualToString:@"status"]) {
|
|
503
|
+
if (self.player.status == AVPlayerStatusReadyToPlay) {
|
|
504
|
+
[self.loadingIndicator stopAnimating];
|
|
505
|
+
[self.btnStackView removeArrangedSubview:self.loadingIndicator];
|
|
506
|
+
[self.loadingIndicator removeFromSuperview];
|
|
507
|
+
[self.btnStackView insertArrangedSubview:self.playBtn atIndex:1];
|
|
508
|
+
|
|
509
|
+
[UIView animateWithDuration:0.25 animations:^{
|
|
510
|
+
self.playBtn.alpha = 1;
|
|
511
|
+
self.playBtn.enabled = YES;
|
|
512
|
+
self.saveBtn.alpha = 1;
|
|
513
|
+
self.saveBtn.enabled = YES;
|
|
514
|
+
}];
|
|
515
|
+
|
|
516
|
+
if (self.jumpToPositionOnLoad > 0) {
|
|
517
|
+
double duration = CMTimeGetSeconds(self.asset.duration) * 1000;
|
|
518
|
+
double time = (self.jumpToPositionOnLoad > duration) ? duration : self.jumpToPositionOnLoad;
|
|
519
|
+
CMTime cmtime = CMTimeMake((CMTimeValue)time, 1000);
|
|
520
|
+
|
|
521
|
+
[self seek:cmtime];
|
|
522
|
+
self.trimmer.progress = cmtime;
|
|
523
|
+
self.currentTimeLabel.text = [self displayStringFromCMTime:self.trimmer.progress];
|
|
524
|
+
}
|
|
525
|
+
|
|
526
|
+
if (self.autoplay) {
|
|
527
|
+
[self togglePlay:self.playBtn];
|
|
528
|
+
}
|
|
529
|
+
}
|
|
530
|
+
}
|
|
531
|
+
}
|
|
532
|
+
|
|
533
|
+
@end
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"names":["TurboModuleRegistry","getEnforcing"],"sourceRoot":"../../src","sources":["NativeVideoTrim.ts"],"mappings":";;AACA,SAASA,mBAAmB,QAAQ,cAAc;AA+GlD,eAAeA,mBAAmB,CAACC,YAAY,CAAO,WAAW,CAAC","ignoreList":[]}
|
package/lib/module/index.js
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
|
|
3
|
-
import
|
|
3
|
+
import VideoTrim from "./NativeVideoTrim.js";
|
|
4
4
|
import { processColor } from 'react-native';
|
|
5
|
-
|
|
5
|
+
export * from "./NativeVideoTrim.js";
|
|
6
6
|
function createBaseOptions(overrides = {}) {
|
|
7
7
|
return {
|
|
8
8
|
saveToPhoto: false,
|
|
@@ -25,8 +25,7 @@ function createEditorConfig(overrides = {}) {
|
|
|
25
25
|
return {
|
|
26
26
|
enableHapticFeedback: true,
|
|
27
27
|
maxDuration: -1,
|
|
28
|
-
|
|
29
|
-
minDuration: 1000,
|
|
28
|
+
minDuration: -1,
|
|
30
29
|
cancelButtonText: 'Cancel',
|
|
31
30
|
saveButtonText: 'Save',
|
|
32
31
|
enableCancelDialog: true,
|
|
@@ -42,7 +41,6 @@ function createEditorConfig(overrides = {}) {
|
|
|
42
41
|
trimmingText: 'Trimming video...',
|
|
43
42
|
fullScreenModalIOS: false,
|
|
44
43
|
autoplay: false,
|
|
45
|
-
// Adjust default as needed
|
|
46
44
|
jumpToPositionOnLoad: -1,
|
|
47
45
|
closeWhenFinish: true,
|
|
48
46
|
enableCancelTrimming: true,
|
|
@@ -53,7 +51,6 @@ function createEditorConfig(overrides = {}) {
|
|
|
53
51
|
cancelTrimmingDialogCancelText: 'Close',
|
|
54
52
|
cancelTrimmingDialogConfirmText: 'Proceed',
|
|
55
53
|
headerText: '',
|
|
56
|
-
// Adjust default as needed
|
|
57
54
|
headerTextSize: 16,
|
|
58
55
|
headerTextColor: processColor('white'),
|
|
59
56
|
alertOnFailToLoad: true,
|
|
@@ -72,71 +69,72 @@ function createTrimOptions(overrides = {}) {
|
|
|
72
69
|
...overrides
|
|
73
70
|
};
|
|
74
71
|
}
|
|
75
|
-
function noop() {}
|
|
76
72
|
|
|
77
73
|
/**
|
|
78
|
-
*
|
|
74
|
+
* Show video editor
|
|
79
75
|
*
|
|
80
|
-
* @param {string}
|
|
76
|
+
* @param {string} filePath: absolute non-empty file path to edit
|
|
81
77
|
* @param {EditorConfig} config: editor configuration
|
|
82
|
-
* @
|
|
78
|
+
* @param {Function} onEvent: event callback
|
|
79
|
+
* @returns {void}
|
|
83
80
|
*/
|
|
84
|
-
export function showEditor(filePath, config
|
|
81
|
+
export function showEditor(filePath, config) {
|
|
85
82
|
const {
|
|
86
83
|
headerTextColor
|
|
87
84
|
} = config;
|
|
88
85
|
const color = processColor(headerTextColor || 'white');
|
|
89
|
-
|
|
86
|
+
VideoTrim.showEditor(filePath, createEditorConfig({
|
|
90
87
|
...config,
|
|
91
88
|
headerTextColor: color
|
|
92
|
-
})
|
|
89
|
+
}));
|
|
93
90
|
}
|
|
94
91
|
|
|
95
92
|
/**
|
|
96
|
-
*
|
|
93
|
+
* List output files generated at all time
|
|
97
94
|
*
|
|
98
95
|
* @returns {Promise<string[]>} A **Promise** which resolves to array of files
|
|
99
96
|
*/
|
|
100
97
|
export function listFiles() {
|
|
101
|
-
return
|
|
98
|
+
return VideoTrim.listFiles();
|
|
102
99
|
}
|
|
103
100
|
|
|
104
101
|
/**
|
|
105
102
|
* Clean output files generated at all time
|
|
106
103
|
*
|
|
107
|
-
* @returns {Promise} A **Promise** which resolves to number of deleted files
|
|
104
|
+
* @returns {Promise<number>} A **Promise** which resolves to number of deleted files
|
|
108
105
|
*/
|
|
109
106
|
export function cleanFiles() {
|
|
110
|
-
return
|
|
107
|
+
return VideoTrim.cleanFiles();
|
|
111
108
|
}
|
|
112
109
|
|
|
113
110
|
/**
|
|
114
111
|
* Delete a file
|
|
115
112
|
*
|
|
116
113
|
* @param {string} filePath: absolute non-empty file path to delete
|
|
117
|
-
* @returns {Promise} A **Promise** which resolves `true` if successful
|
|
114
|
+
* @returns {Promise<boolean>} A **Promise** which resolves `true` if successful
|
|
118
115
|
*/
|
|
119
116
|
export function deleteFile(filePath) {
|
|
120
117
|
if (!filePath?.trim().length) {
|
|
121
118
|
throw new Error('File path cannot be empty!');
|
|
122
119
|
}
|
|
123
|
-
return
|
|
120
|
+
return VideoTrim.deleteFile(filePath);
|
|
124
121
|
}
|
|
125
122
|
|
|
126
123
|
/**
|
|
127
124
|
* Close editor
|
|
128
125
|
*/
|
|
129
|
-
export function closeEditor(
|
|
130
|
-
return
|
|
126
|
+
export function closeEditor() {
|
|
127
|
+
return VideoTrim.closeEditor();
|
|
131
128
|
}
|
|
132
129
|
|
|
133
130
|
/**
|
|
134
131
|
* Check if a file is valid audio or video file
|
|
135
132
|
*
|
|
136
|
-
* @
|
|
133
|
+
* @param {string} url: file path to validate
|
|
134
|
+
* @returns {Promise<FileValidationResult>} A **Promise** which resolves file info if successful
|
|
137
135
|
*/
|
|
138
136
|
export function isValidFile(url) {
|
|
139
|
-
return
|
|
137
|
+
return VideoTrim.isValidFile(url);
|
|
140
138
|
}
|
|
141
139
|
|
|
142
140
|
/**
|
|
@@ -147,6 +145,6 @@ export function isValidFile(url) {
|
|
|
147
145
|
* @returns {Promise<string>} A **Promise** which resolves to the trimmed file path
|
|
148
146
|
*/
|
|
149
147
|
export function trim(url, options) {
|
|
150
|
-
return
|
|
148
|
+
return VideoTrim.trim(url, createTrimOptions(options));
|
|
151
149
|
}
|
|
152
150
|
//# sourceMappingURL=index.js.map
|