react-native-video-trim 6.0.11 → 6.0.13
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/ios/VideoTrim.swift +16 -109
- package/package.json +1 -1
package/ios/VideoTrim.swift
CHANGED
|
@@ -3,14 +3,12 @@ import Photos
|
|
|
3
3
|
import ffmpegkit
|
|
4
4
|
|
|
5
5
|
let FILE_PREFIX = "trimmedVideo"
|
|
6
|
-
let BEFORE_TRIM_PREFIX = "beforeTrim"
|
|
7
6
|
|
|
8
7
|
@objc(VideoTrimSwift)
|
|
9
8
|
public class VideoTrim: RCTEventEmitter, AssetLoaderDelegate, UIDocumentPickerDelegate {
|
|
10
9
|
// MARK: instance private props
|
|
11
10
|
private var isShowing = false
|
|
12
11
|
private var vc: VideoTrimmerViewController?
|
|
13
|
-
private var isVideoType = true
|
|
14
12
|
private var outputFile: URL?
|
|
15
13
|
private var editorConfig: NSDictionary?
|
|
16
14
|
|
|
@@ -261,7 +259,7 @@ public class VideoTrim: RCTEventEmitter, AssetLoaderDelegate, UIDocumentPickerDe
|
|
|
261
259
|
}
|
|
262
260
|
}
|
|
263
261
|
|
|
264
|
-
private func trim(viewController: VideoTrimmerViewController, inputFile: URL, videoDuration: Double, startTime: Double, endTime: Double) {
|
|
262
|
+
private func trim(viewController: VideoTrimmerViewController, inputFile: URL, videoDuration: Double, startTime: Double, endTime: Double, isVideoType: Bool) {
|
|
265
263
|
vc?.pausePlayer()
|
|
266
264
|
|
|
267
265
|
let timestamp = Int(Date().timeIntervalSince1970)
|
|
@@ -343,12 +341,12 @@ public class VideoTrim: RCTEventEmitter, AssetLoaderDelegate, UIDocumentPickerDe
|
|
|
343
341
|
|
|
344
342
|
cmds.append(contentsOf: [
|
|
345
343
|
"-i",
|
|
346
|
-
|
|
344
|
+
inputFile.path,
|
|
347
345
|
"-c",
|
|
348
346
|
"copy",
|
|
349
347
|
"-metadata",
|
|
350
348
|
"creation_time=\(dateTime)",
|
|
351
|
-
outputFile!.
|
|
349
|
+
outputFile!.path
|
|
352
350
|
])
|
|
353
351
|
|
|
354
352
|
print("Command: ", cmds.joined(separator: " "))
|
|
@@ -372,7 +370,7 @@ public class VideoTrim: RCTEventEmitter, AssetLoaderDelegate, UIDocumentPickerDe
|
|
|
372
370
|
let eventPayload: [String: Any] = ["outputPath": self.outputFile!.absoluteString, "startTime": (startTime * 1000).rounded(), "endTime": (endTime * 1000).rounded(), "duration": (videoDuration * 1000).rounded()]
|
|
373
371
|
self.emitEventToJS("onFinishTrimming", eventData: eventPayload)
|
|
374
372
|
|
|
375
|
-
if (self.saveToPhoto &&
|
|
373
|
+
if (self.saveToPhoto && isVideoType) {
|
|
376
374
|
PHPhotoLibrary.requestAuthorization { status in
|
|
377
375
|
guard status == .authorized else {
|
|
378
376
|
self.onError(message: "Permission to access Photo Library is not granted", code: .noPhotoPermission)
|
|
@@ -465,13 +463,7 @@ public class VideoTrim: RCTEventEmitter, AssetLoaderDelegate, UIDocumentPickerDe
|
|
|
465
463
|
// New Arch
|
|
466
464
|
@objc(trim:url:config:)
|
|
467
465
|
public func _trim(inputFile: String, config: NSDictionary, completion: @escaping ([String: Any]) -> Void) {
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
if inputFile.hasPrefix("http://") || inputFile.hasPrefix("https://") {
|
|
471
|
-
destPath = URL(string: inputFile)
|
|
472
|
-
} else {
|
|
473
|
-
destPath = renameFile(at: URL(string: inputFile)!, newName: BEFORE_TRIM_PREFIX)
|
|
474
|
-
}
|
|
466
|
+
let destPath = URL(string: inputFile)
|
|
475
467
|
|
|
476
468
|
guard let destPath = destPath else {
|
|
477
469
|
let result = [
|
|
@@ -511,12 +503,12 @@ public class VideoTrim: RCTEventEmitter, AssetLoaderDelegate, UIDocumentPickerDe
|
|
|
511
503
|
|
|
512
504
|
cmds.append(contentsOf: [
|
|
513
505
|
"-i",
|
|
514
|
-
|
|
506
|
+
destPath.path,
|
|
515
507
|
"-c",
|
|
516
508
|
"copy",
|
|
517
509
|
"-metadata",
|
|
518
510
|
"creation_time=\(dateTime)",
|
|
519
|
-
outputFile.
|
|
511
|
+
outputFile.path
|
|
520
512
|
])
|
|
521
513
|
|
|
522
514
|
print("Command: ", cmds.joined(separator: " "))
|
|
@@ -706,40 +698,6 @@ public class VideoTrim: RCTEventEmitter, AssetLoaderDelegate, UIDocumentPickerDe
|
|
|
706
698
|
]
|
|
707
699
|
self.emitEventToJS("onError", eventData: eventPayload)
|
|
708
700
|
}
|
|
709
|
-
|
|
710
|
-
private func renameFile(at url: URL, newName: String) -> URL? {
|
|
711
|
-
let fileManager = FileManager.default
|
|
712
|
-
|
|
713
|
-
// Get the directory of the existing file
|
|
714
|
-
let directory = url.deletingLastPathComponent()
|
|
715
|
-
|
|
716
|
-
// Get the file extension
|
|
717
|
-
let fileExtension = url.pathExtension
|
|
718
|
-
|
|
719
|
-
// Create the new file URL with the new name and the same extension
|
|
720
|
-
let newFileURL = directory.appendingPathComponent(newName).appendingPathExtension(fileExtension)
|
|
721
|
-
|
|
722
|
-
// Check if a file with the new name already exists
|
|
723
|
-
if fileManager.fileExists(atPath: newFileURL.path) {
|
|
724
|
-
do {
|
|
725
|
-
// If the file exists, remove it first to avoid conflicts
|
|
726
|
-
try fileManager.removeItem(at: newFileURL)
|
|
727
|
-
} catch {
|
|
728
|
-
print("Error removing existing file: \(error)")
|
|
729
|
-
return nil
|
|
730
|
-
}
|
|
731
|
-
}
|
|
732
|
-
|
|
733
|
-
do {
|
|
734
|
-
// Rename (move) the file
|
|
735
|
-
try fileManager.moveItem(at: url, to: newFileURL)
|
|
736
|
-
print("File renamed successfully to \(newFileURL.absoluteString)")
|
|
737
|
-
return newFileURL
|
|
738
|
-
} catch {
|
|
739
|
-
print("Error renaming file: \(error)")
|
|
740
|
-
return nil
|
|
741
|
-
}
|
|
742
|
-
}
|
|
743
701
|
}
|
|
744
702
|
|
|
745
703
|
// MARK: @objc instance methods
|
|
@@ -751,63 +709,10 @@ extension VideoTrim {
|
|
|
751
709
|
return
|
|
752
710
|
}
|
|
753
711
|
editorConfig = config
|
|
712
|
+
print("Show editor called with URI: \(uri)")
|
|
754
713
|
|
|
755
|
-
|
|
756
|
-
|
|
757
|
-
//
|
|
758
|
-
// removeAfterSavedToPhoto = config["removeAfterSavedToPhoto"] as? Bool ?? false
|
|
759
|
-
// removeAfterFailedToSavePhoto = config["removeAfterFailedToSavePhoto"] as? Bool ?? false
|
|
760
|
-
// removeAfterSavedToDocuments = config["removeAfterSavedToDocuments"] as? Bool ?? false
|
|
761
|
-
// removeAfterFailedToSaveDocuments = config["removeAfterFailedToSaveDocuments"] as? Bool ?? false
|
|
762
|
-
// removeAfterShared = config["removeAfterShared"] as? Bool ?? false
|
|
763
|
-
// removeAfterFailedToShare = config["removeAfterFailedToShare"] as? Bool ?? false
|
|
764
|
-
//
|
|
765
|
-
// enableCancelDialog = config["enableCancelDialog"] as? Bool ?? true
|
|
766
|
-
// cancelDialogTitle = config["cancelDialogTitle"] as? String ?? "Warning!"
|
|
767
|
-
// cancelDialogMessage = config["cancelDialogMessage"] as? String ?? "Are you sure want to cancel?"
|
|
768
|
-
// cancelDialogCancelText = config["cancelDialogCancelText"] as? String ?? "Close"
|
|
769
|
-
// cancelDialogConfirmText = config["cancelDialogConfirmText"] as? String ?? "Proceed"
|
|
770
|
-
//
|
|
771
|
-
// enableSaveDialog = config["enableSaveDialog"] as? Bool ?? true
|
|
772
|
-
// saveDialogTitle = config["saveDialogTitle"] as? String ?? "Confirmation!"
|
|
773
|
-
// saveDialogMessage = config["saveDialogMessage"] as? String ?? "Are you sure want to save?"
|
|
774
|
-
// saveDialogCancelText = config["saveDialogCancelText"] as? String ?? "Close"
|
|
775
|
-
// saveDialogConfirmText = config["saveDialogConfirmText"] as? String ?? "Proceed"
|
|
776
|
-
// trimmingText = config["trimmingText"] as? String ?? "Trimming video..."
|
|
777
|
-
// fullScreenModalIOS = config["fullScreenModalIOS"] as? Bool ?? false
|
|
778
|
-
// isVideoType = (config["type"] as? String ?? "video") == "video"
|
|
779
|
-
// outputExt = config["outputExt"] as? String ?? "mp4"
|
|
780
|
-
// openDocumentsOnFinish = config["openDocumentsOnFinish"] as? Bool ?? false
|
|
781
|
-
// openShareSheetOnFinish = config["openShareSheetOnFinish"] as? Bool ?? false
|
|
782
|
-
//
|
|
783
|
-
// closeWhenFinish = config["closeWhenFinish"] as? Bool ?? true
|
|
784
|
-
// enableCancelTrimming = config["enableCancelTrimming"] as? Bool ?? true
|
|
785
|
-
// cancelTrimmingButtonText = config["cancelTrimmingButtonText"] as? String ?? "Cancel"
|
|
786
|
-
// enableCancelTrimmingDialog = config["enableCancelTrimmingDialog"] as? Bool ?? true
|
|
787
|
-
// cancelTrimmingDialogTitle = config["cancelTrimmingDialogTitle"] as? String ?? "Warning!"
|
|
788
|
-
// cancelTrimmingDialogMessage = config["cancelTrimmingDialogMessage"] as? String ?? "Are you sure want to cancel trimming?"
|
|
789
|
-
// cancelTrimmingDialogCancelText = config["cancelTrimmingDialogCancelText"] as? String ?? "Close"
|
|
790
|
-
// cancelTrimmingDialogConfirmText = config["cancelTrimmingDialogConfirmText"] as? String ?? "Proceed"
|
|
791
|
-
// alertOnFailToLoad = config["alertOnFailToLoad"] as? Bool ?? true
|
|
792
|
-
// alertOnFailTitle = config["alertOnFailTitle"] as? String ?? "Error"
|
|
793
|
-
// alertOnFailMessage = config["alertOnFailMessage"] as? String ?? "Fail to load media. Possibly invalid file or no network connection"
|
|
794
|
-
// alertOnFailCloseText = config["alertOnFailCloseText"] as? String ?? "Close"
|
|
795
|
-
//
|
|
796
|
-
// if let cancelBtnText = config["cancelButtonText"] as? String, !cancelBtnText.isEmpty {
|
|
797
|
-
// self.cancelButtonText = cancelBtnText
|
|
798
|
-
// }
|
|
799
|
-
//
|
|
800
|
-
// if let saveButtonText = config["saveButtonText"] as? String, !saveButtonText.isEmpty {
|
|
801
|
-
// self.saveButtonText = saveButtonText
|
|
802
|
-
// }
|
|
803
|
-
|
|
804
|
-
var destPath: URL?
|
|
805
|
-
|
|
806
|
-
if uri.hasPrefix("http://") || uri.hasPrefix("https://") {
|
|
807
|
-
destPath = URL(string: uri)
|
|
808
|
-
} else {
|
|
809
|
-
destPath = renameFile(at: URL(string: uri)!, newName: BEFORE_TRIM_PREFIX)
|
|
810
|
-
}
|
|
714
|
+
let destPath = URL(string: uri)
|
|
715
|
+
print("Destination Path: \(destPath!.absoluteString), path: \(destPath!.path)")
|
|
811
716
|
|
|
812
717
|
guard let destPath = destPath else { return }
|
|
813
718
|
|
|
@@ -849,9 +754,11 @@ extension VideoTrim {
|
|
|
849
754
|
}
|
|
850
755
|
}
|
|
851
756
|
|
|
757
|
+
let isVideoType = (config["type"] as? String ?? "video") == "video"
|
|
758
|
+
|
|
852
759
|
vc.saveBtnClicked = {(selectedRange: CMTimeRange) in
|
|
853
760
|
if !self.enableSaveDialog {
|
|
854
|
-
self.trim(viewController: vc,inputFile: destPath, videoDuration: self.vc!.asset!.duration.seconds, startTime: selectedRange.start.seconds, endTime: selectedRange.end.seconds)
|
|
761
|
+
self.trim(viewController: vc,inputFile: destPath, videoDuration: self.vc!.asset!.duration.seconds, startTime: selectedRange.start.seconds, endTime: selectedRange.end.seconds, isVideoType: isVideoType)
|
|
855
762
|
return
|
|
856
763
|
}
|
|
857
764
|
|
|
@@ -861,7 +768,7 @@ extension VideoTrim {
|
|
|
861
768
|
|
|
862
769
|
// Create OK button with action handler
|
|
863
770
|
let ok = UIAlertAction(title: self.saveDialogConfirmText, style: .default, handler: { (action) -> Void in
|
|
864
|
-
self.trim(viewController: vc,inputFile: destPath, videoDuration: vc.asset!.duration.seconds, startTime: selectedRange.start.seconds, endTime: selectedRange.end.seconds)
|
|
771
|
+
self.trim(viewController: vc,inputFile: destPath, videoDuration: vc.asset!.duration.seconds, startTime: selectedRange.start.seconds, endTime: selectedRange.end.seconds, isVideoType: isVideoType)
|
|
865
772
|
})
|
|
866
773
|
|
|
867
774
|
// Create Cancel button with action handlder
|
|
@@ -892,7 +799,7 @@ extension VideoTrim {
|
|
|
892
799
|
// otherwise it may run too fast for local file and autoplay looks weird
|
|
893
800
|
let assetLoader = AssetLoader()
|
|
894
801
|
assetLoader.delegate = self
|
|
895
|
-
assetLoader.loadAsset(url: destPath, isVideoType:
|
|
802
|
+
assetLoader.loadAsset(url: destPath, isVideoType: isVideoType)
|
|
896
803
|
})
|
|
897
804
|
}
|
|
898
805
|
}
|
|
@@ -978,7 +885,7 @@ extension VideoTrim {
|
|
|
978
885
|
let directoryContents = try FileManager.default.contentsOfDirectory(at: documentsDirectory, includingPropertiesForKeys: nil)
|
|
979
886
|
|
|
980
887
|
for fileURL in directoryContents {
|
|
981
|
-
if fileURL.lastPathComponent.starts(with: FILE_PREFIX)
|
|
888
|
+
if fileURL.lastPathComponent.starts(with: FILE_PREFIX) {
|
|
982
889
|
files.append(fileURL)
|
|
983
890
|
}
|
|
984
891
|
}
|