react-native-video-trim 7.1.0 → 7.1.1

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.
@@ -0,0 +1,75 @@
1
+ import UIKit
2
+
3
+ /// Custom UIView that draws an audio waveform as a row of vertical rounded-rect bars.
4
+ ///
5
+ /// Each bar's height is driven by a normalized amplitude value in [0, 1].
6
+ /// The view recalculates bar count from its own width and maps the amplitudes
7
+ /// array proportionally, so it works correctly regardless of whether the
8
+ /// amplitudes array has more or fewer entries than the visible bar count.
9
+ ///
10
+ /// The `backgroundColor` provides the waveform track color; bars are drawn
11
+ /// on top with `barColor`.
12
+ class AudioWaveformView: UIView {
13
+ var amplitudes: [CGFloat] = [] {
14
+ didSet { setNeedsDisplay() }
15
+ }
16
+
17
+ var barColor: UIColor = .white {
18
+ didSet { setNeedsDisplay() }
19
+ }
20
+
21
+ var barWidth: CGFloat = 3 {
22
+ didSet { setNeedsDisplay() }
23
+ }
24
+
25
+ var barGap: CGFloat = 2 {
26
+ didSet { setNeedsDisplay() }
27
+ }
28
+
29
+ var barCornerRadius: CGFloat = 1.5 {
30
+ didSet { setNeedsDisplay() }
31
+ }
32
+
33
+ override init(frame: CGRect) {
34
+ super.init(frame: frame)
35
+ isOpaque = false
36
+ contentMode = .redraw
37
+ }
38
+
39
+ required init?(coder: NSCoder) {
40
+ super.init(coder: coder)
41
+ isOpaque = false
42
+ contentMode = .redraw
43
+ }
44
+
45
+ override func draw(_ rect: CGRect) {
46
+ guard !amplitudes.isEmpty else { return }
47
+ guard let ctx = UIGraphicsGetCurrentContext() else { return }
48
+
49
+ let totalHeight = rect.height
50
+ let step = barWidth + barGap
51
+ let barCount = Int(floor(rect.width / step))
52
+ guard barCount > 0 else { return }
53
+
54
+ // Keep bars from touching the container edges
55
+ let verticalPadding = barWidth * 1.5
56
+ let drawableHeight = totalHeight - verticalPadding * 2
57
+ guard drawableHeight > 0 else { return }
58
+ let minBarHeight = barWidth
59
+
60
+ ctx.setFillColor(barColor.cgColor)
61
+
62
+ for i in 0..<barCount {
63
+ let ampIndex = i * amplitudes.count / barCount
64
+ let amp = amplitudes[min(ampIndex, amplitudes.count - 1)]
65
+ let barHeight = max(minBarHeight, amp * drawableHeight)
66
+ let x = CGFloat(i) * step
67
+ let y = verticalPadding + (drawableHeight - barHeight) / 2.0
68
+ let barRect = CGRect(x: x, y: y, width: barWidth, height: barHeight)
69
+ let path = UIBezierPath(roundedRect: barRect, cornerRadius: barCornerRadius)
70
+ ctx.addPath(path.cgPath)
71
+ }
72
+
73
+ ctx.fillPath()
74
+ }
75
+ }
package/ios/VideoTrim.mm CHANGED
@@ -155,6 +155,31 @@ RCT_EXPORT_MODULE()
155
155
  dict[@"handleIconColor"] = @(handleIconColorOpt.value());
156
156
  }
157
157
 
158
+ auto waveformColorOpt = config.waveformColor();
159
+ if (waveformColorOpt.has_value()) {
160
+ dict[@"waveformColor"] = @(waveformColorOpt.value());
161
+ }
162
+
163
+ auto waveformBackgroundColorOpt = config.waveformBackgroundColor();
164
+ if (waveformBackgroundColorOpt.has_value()) {
165
+ dict[@"waveformBackgroundColor"] = @(waveformBackgroundColorOpt.value());
166
+ }
167
+
168
+ auto waveformBarWidthOpt = config.waveformBarWidth();
169
+ if (waveformBarWidthOpt.has_value()) {
170
+ dict[@"waveformBarWidth"] = @(waveformBarWidthOpt.value());
171
+ }
172
+
173
+ auto waveformBarGapOpt = config.waveformBarGap();
174
+ if (waveformBarGapOpt.has_value()) {
175
+ dict[@"waveformBarGap"] = @(waveformBarGapOpt.value());
176
+ }
177
+
178
+ auto waveformBarCornerRadiusOpt = config.waveformBarCornerRadius();
179
+ if (waveformBarCornerRadiusOpt.has_value()) {
180
+ dict[@"waveformBarCornerRadius"] = @(waveformBarCornerRadiusOpt.value());
181
+ }
182
+
158
183
  auto zoomOnWaitingDurationOpt = config.zoomOnWaitingDuration();
159
184
  if (zoomOnWaitingDurationOpt.has_value()) {
160
185
  dict[@"zoomOnWaitingDuration"] = @(zoomOnWaitingDurationOpt.value());
@@ -135,12 +135,25 @@ import AVFoundation
135
135
 
136
136
  var asset: AVAsset? {
137
137
  didSet {
138
+ // Clean up *all* async resources unconditionally — even when
139
+ // asset is set to nil (e.g. editor dismissal triggers this via
140
+ // VideoTrimmerViewController.viewWillDisappear).
141
+ generator?.cancelAllCGImageGeneration()
142
+ currentAssetReader?.cancelReading()
143
+ currentAssetReader = nil
144
+ audioDownloadTask?.cancel()
145
+ audioDownloadTask = nil
146
+ cleanupLocalAudioFile()
147
+ localAudioAsset = nil
148
+
138
149
  if let asset = asset {
139
150
  applyThemeColors()
140
151
  let duration = asset.duration
141
152
  range = CMTimeRange(start: .zero, duration: duration)
142
153
  selectedRange = range
143
154
  lastKnownViewSizeForThumbnailGeneration = .zero
155
+ lastKnownWaveformSize = .zero
156
+ lastKnownWaveformRange = .zero
144
157
  setNeedsLayout()
145
158
  }
146
159
  }
@@ -160,6 +173,34 @@ import AVFoundation
160
173
  var enableHapticFeedback = true
161
174
  var zoomOnWaitingDuration: Double = 5.0 // Default: 5 seconds
162
175
  var isLightTheme = false
176
+ /// Explicitly set from JS config (`type != "video"`).
177
+ /// Using a dedicated flag instead of inspecting AVAsset tracks avoids
178
+ /// false negatives — some audio files (e.g. M4A with album art) report
179
+ /// a video track, which caused the original `.video` track guard to
180
+ /// skip waveform generation entirely.
181
+ var isAudioOnly = false {
182
+ didSet {
183
+ lastKnownWaveformSize = .zero
184
+ setNeedsLayout()
185
+ }
186
+ }
187
+
188
+ // MARK: - Waveform customisation (forwarded to AudioWaveformView)
189
+ var waveformBarColor: UIColor = .white {
190
+ didSet { waveformView.barColor = waveformBarColor }
191
+ }
192
+ var waveformBgColor: UIColor = UIColor(red: 0.204, green: 0.471, blue: 0.965, alpha: 1) {
193
+ didSet { waveformView.backgroundColor = waveformBgColor }
194
+ }
195
+ var waveformBarWidth: CGFloat = 3 {
196
+ didSet { waveformView.barWidth = waveformBarWidth }
197
+ }
198
+ var waveformBarGap: CGFloat = 2 {
199
+ didSet { waveformView.barGap = waveformBarGap }
200
+ }
201
+ var waveformBarCornerRadius: CGFloat = 1.5 {
202
+ didSet { waveformView.barCornerRadius = waveformBarCornerRadius }
203
+ }
163
204
 
164
205
  // the available range of the asset.
165
206
  // Will be set to the full duration of the asset when assigning a new asset
@@ -270,10 +311,35 @@ import AVFoundation
270
311
  private var thumbnails = Array<Thumbnail>()
271
312
  private var generator: AVAssetImageGenerator?
272
313
 
314
+ // MARK: - Audio waveform state
315
+ //
316
+ // AVAssetReader cannot read from remote URLs, so for remote audio we
317
+ // download to a temporary local file first (via URLSession.downloadTask).
318
+ // The local AVURLAsset is reused for zoom re-extractions, and the temp
319
+ // file is deleted in cleanupLocalAudioFile() on dismiss.
320
+ private let waveformView = AudioWaveformView()
321
+ private var lastKnownWaveformSize: CGSize = .zero
322
+ private var lastKnownWaveformRange: CMTimeRange = .zero
323
+ private var currentAssetReader: AVAssetReader?
324
+ /** AVURLAsset pointing to the downloaded local file (nil for local sources). */
325
+ private var localAudioAsset: AVURLAsset?
326
+ /** File URL of the temporary download, for deletion on cleanup. */
327
+ private var localAudioFileURL: URL?
328
+ private var audioDownloadTask: URLSessionDownloadTask?
329
+
273
330
  private var impactFeedbackGenerator: UIImpactFeedbackGenerator?
274
331
  private var didClampWhilePanning = false
275
332
 
276
333
 
334
+ /// Cancel all in-flight async work and delete temporary files.
335
+ /// This fires both on normal dismiss and on immediate close.
336
+ deinit {
337
+ generator?.cancelAllCGImageGeneration()
338
+ audioDownloadTask?.cancel()
339
+ currentAssetReader?.cancelReading()
340
+ cleanupLocalAudioFile()
341
+ }
342
+
277
343
  // MARK: - Private
278
344
  private func applyThemeColors() {
279
345
  let bg: UIColor = isLightTheme ? .white : .black
@@ -291,6 +357,17 @@ import AVFoundation
291
357
  thumbnailWrapperView.addSubview(leadingThumbRest)
292
358
  thumbnailWrapperView.addSubview(trailingThumbRest)
293
359
  thumbnailWrapperView.addSubview(thumbnailTrackView)
360
+
361
+ // Waveform view sits inside the thumbnail track but starts hidden;
362
+ // it's shown only for audio files once data is available.
363
+ waveformView.backgroundColor = waveformBgColor
364
+ waveformView.barColor = waveformBarColor
365
+ waveformView.barWidth = waveformBarWidth
366
+ waveformView.barGap = waveformBarGap
367
+ waveformView.barCornerRadius = waveformBarCornerRadius
368
+ waveformView.isHidden = true
369
+ thumbnailTrackView.addSubview(waveformView)
370
+
294
371
  thumbnailWrapperView.addSubview(thumbnailLeadingCoverView)
295
372
  thumbnailWrapperView.addSubview(thumbnailTrailingCoverView)
296
373
 
@@ -419,6 +496,7 @@ import AVFoundation
419
496
  let transform = track.preferredTransform
420
497
  let fixedSize = naturalSize.applyingVideoTransform(transform)
421
498
 
499
+ self.generator?.cancelAllCGImageGeneration()
422
500
  let generator = AVAssetImageGenerator(asset: asset)
423
501
  generator.apertureMode = .cleanAperture
424
502
  generator.videoComposition = videoComposition
@@ -472,6 +550,223 @@ import AVFoundation
472
550
  }
473
551
  }
474
552
 
553
+ /// Called from layoutSubviews whenever the view size or visible time range changes.
554
+ ///
555
+ /// For remote URLs, the first call triggers a download; once the local
556
+ /// file is cached, subsequent calls (e.g. zoom) skip straight to reading.
557
+ private func regenerateWaveformIfNeeded() {
558
+ guard isAudioOnly else { return }
559
+ let size = bounds.size
560
+ guard size.width > 0 && size.height > 0 else { return }
561
+ guard lastKnownWaveformSize != size || !CMTimeRangeEqual(lastKnownWaveformRange, visibleRange) else { return }
562
+ guard let asset = asset else { return }
563
+
564
+ // Remote URL path: download once, then reuse localAudioAsset for reads
565
+ if let urlAsset = asset as? AVURLAsset, !urlAsset.url.isFileURL {
566
+ if let localAsset = localAudioAsset {
567
+ guard let audioTrack = localAsset.tracks(withMediaType: .audio).first else { return }
568
+ readWaveformSamples(from: localAsset, audioTrack: audioTrack, size: size)
569
+ } else if audioDownloadTask == nil {
570
+ downloadAudioForWaveform(from: urlAsset.url)
571
+ }
572
+ return
573
+ }
574
+
575
+ // Local file path: read directly
576
+ guard let audioTrack = asset.tracks(withMediaType: .audio).first else { return }
577
+ readWaveformSamples(from: asset, audioTrack: audioTrack, size: size)
578
+ }
579
+
580
+ /// Download remote audio to a temporary local file so AVAssetReader can read it.
581
+ ///
582
+ /// The file extension is inferred from the HTTP response (Content-Disposition,
583
+ /// MIME type) or the original URL, because AVURLAsset on iOS relies on
584
+ /// the extension to identify the audio codec — a generic `.tmp` extension
585
+ /// would cause silent failures.
586
+ private func downloadAudioForWaveform(from url: URL) {
587
+ let task = URLSession.shared.downloadTask(with: url) { [weak self] tempURL, response, error in
588
+ guard let self = self, let tempURL = tempURL else {
589
+ print("AudioWaveform: Download failed: \(error?.localizedDescription ?? "unknown")")
590
+ DispatchQueue.main.async { self?.audioDownloadTask = nil }
591
+ return
592
+ }
593
+
594
+ let ext = Self.audioFileExtension(from: response, originalURL: url)
595
+ let destURL = FileManager.default.temporaryDirectory
596
+ .appendingPathComponent("waveform_\(UUID().uuidString).\(ext)")
597
+ do {
598
+ try FileManager.default.moveItem(at: tempURL, to: destURL)
599
+ let localAsset = AVURLAsset(url: destURL, options: [AVURLAssetPreferPreciseDurationAndTimingKey: true])
600
+ localAsset.loadValuesAsynchronously(forKeys: ["tracks"]) {
601
+ var trackError: NSError?
602
+ let status = localAsset.statusOfValue(forKey: "tracks", error: &trackError)
603
+ guard status == .loaded else {
604
+ print("AudioWaveform: Failed to load tracks from downloaded file: \(trackError?.localizedDescription ?? "unknown")")
605
+ try? FileManager.default.removeItem(at: destURL)
606
+ DispatchQueue.main.async { self.audioDownloadTask = nil }
607
+ return
608
+ }
609
+ DispatchQueue.main.async {
610
+ self.localAudioFileURL = destURL
611
+ self.localAudioAsset = localAsset
612
+ self.audioDownloadTask = nil
613
+ self.lastKnownWaveformSize = .zero
614
+ self.setNeedsLayout()
615
+ }
616
+ }
617
+ } catch {
618
+ print("AudioWaveform: Failed to move downloaded file: \(error)")
619
+ DispatchQueue.main.async { self.audioDownloadTask = nil }
620
+ }
621
+ }
622
+ audioDownloadTask = task
623
+ task.resume()
624
+ }
625
+
626
+ /// Determine the correct audio file extension from the HTTP response.
627
+ /// Priority: Content-Disposition → MIME type → URL path extension → "m4a" fallback.
628
+ private static func audioFileExtension(from response: URLResponse?, originalURL: URL) -> String {
629
+ if let suggested = response?.suggestedFilename, !suggested.isEmpty {
630
+ let ext = (suggested as NSString).pathExtension
631
+ if !ext.isEmpty { return ext }
632
+ }
633
+
634
+ if let mimeType = response?.mimeType?.lowercased() {
635
+ switch mimeType {
636
+ case "audio/mpeg", "audio/mp3": return "mp3"
637
+ case "audio/mp4", "audio/x-m4a", "audio/aac": return "m4a"
638
+ case "audio/wav", "audio/x-wav", "audio/wave": return "wav"
639
+ case "audio/flac": return "flac"
640
+ case "audio/ogg", "audio/vorbis": return "ogg"
641
+ case "audio/aiff", "audio/x-aiff": return "aiff"
642
+ default: break
643
+ }
644
+ }
645
+
646
+ let urlExt = originalURL.pathExtension
647
+ if !urlExt.isEmpty { return urlExt }
648
+
649
+ return "m4a"
650
+ }
651
+
652
+ /// Decode PCM samples from the given asset's audio track and compute
653
+ /// per-bar RMS amplitudes normalised to [0, 1].
654
+ ///
655
+ /// Runs the heavy decode on a background queue and posts the result
656
+ /// back to the main thread. The AVAssetReader is stored in
657
+ /// `currentAssetReader` so it can be cancelled if the editor is closed
658
+ /// or the view resizes mid-read.
659
+ private func readWaveformSamples(from asset: AVAsset, audioTrack: AVAssetTrack, size: CGSize) {
660
+ lastKnownWaveformSize = size
661
+ lastKnownWaveformRange = visibleRange
662
+
663
+ waveformView.isHidden = false
664
+
665
+ currentAssetReader?.cancelReading()
666
+ currentAssetReader = nil
667
+
668
+ let timeRange = visibleRange
669
+ let step = waveformBarWidth + waveformBarGap
670
+ let barCount = max(1, Int(floor(size.width / step)))
671
+
672
+ DispatchQueue.global(qos: .userInitiated).async { [weak self] in
673
+ guard let self = self else { return }
674
+
675
+ let reader: AVAssetReader
676
+ do {
677
+ reader = try AVAssetReader(asset: asset)
678
+ } catch {
679
+ print("AudioWaveform: Failed to create AVAssetReader: \(error)")
680
+ return
681
+ }
682
+
683
+ reader.timeRange = timeRange
684
+
685
+ let outputSettings: [String: Any] = [
686
+ AVFormatIDKey: kAudioFormatLinearPCM,
687
+ AVLinearPCMIsFloatKey: true,
688
+ AVLinearPCMBitDepthKey: 32,
689
+ AVNumberOfChannelsKey: 1,
690
+ ]
691
+ let output = AVAssetReaderTrackOutput(track: audioTrack, outputSettings: outputSettings)
692
+
693
+ guard reader.canAdd(output) else {
694
+ print("AudioWaveform: Cannot add output to reader")
695
+ return
696
+ }
697
+ reader.add(output)
698
+
699
+ DispatchQueue.main.sync {
700
+ self.currentAssetReader = reader
701
+ }
702
+
703
+ guard reader.startReading() else {
704
+ print("AudioWaveform: Failed to start reading: \(String(describing: reader.error))")
705
+ return
706
+ }
707
+
708
+ var allSamples = [Float]()
709
+ allSamples.reserveCapacity(barCount * 512)
710
+
711
+ while reader.status == .reading {
712
+ guard let sampleBuffer = output.copyNextSampleBuffer() else { break }
713
+ guard let blockBuffer = CMSampleBufferGetDataBuffer(sampleBuffer) else { continue }
714
+
715
+ let length = CMBlockBufferGetDataLength(blockBuffer)
716
+ let sampleCount = length / MemoryLayout<Float>.size
717
+ guard sampleCount > 0 else { continue }
718
+
719
+ var data = [Float](repeating: 0, count: sampleCount)
720
+ CMBlockBufferCopyDataBytes(blockBuffer, atOffset: 0, dataLength: length, destination: &data)
721
+ allSamples.append(contentsOf: data)
722
+ }
723
+
724
+ guard !allSamples.isEmpty else {
725
+ DispatchQueue.main.async {
726
+ self.waveformView.amplitudes = []
727
+ }
728
+ return
729
+ }
730
+
731
+ let samplesPerBar = max(1, allSamples.count / barCount)
732
+ var amplitudes = [CGFloat]()
733
+ amplitudes.reserveCapacity(barCount)
734
+
735
+ for i in 0..<barCount {
736
+ let start = i * samplesPerBar
737
+ let end = min(start + samplesPerBar, allSamples.count)
738
+ guard start < allSamples.count else {
739
+ amplitudes.append(0)
740
+ continue
741
+ }
742
+
743
+ var sumSquares: Float = 0
744
+ for j in start..<end {
745
+ let s = allSamples[j]
746
+ sumSquares += s * s
747
+ }
748
+ let rms = sqrt(sumSquares / Float(end - start))
749
+ amplitudes.append(CGFloat(rms))
750
+ }
751
+
752
+ let maxAmp = amplitudes.max() ?? 1
753
+ let normalizer: CGFloat = maxAmp > 0 ? 1.0 / maxAmp : 1.0
754
+ let normalized = amplitudes.map { min($0 * normalizer, 1.0) }
755
+
756
+ DispatchQueue.main.async {
757
+ self.waveformView.amplitudes = normalized
758
+ }
759
+ }
760
+ }
761
+
762
+ /// Delete the temporary local audio file created by downloadAudioForWaveform.
763
+ private func cleanupLocalAudioFile() {
764
+ if let url = localAudioFileURL {
765
+ try? FileManager.default.removeItem(at: url)
766
+ localAudioFileURL = nil
767
+ }
768
+ }
769
+
475
770
  private func timeForLocation(_ x: CGFloat) -> CMTime {
476
771
  let size = bounds.size
477
772
  let inset = thumbView.chevronWidth + horizontalInset
@@ -942,6 +1237,11 @@ import AVFoundation
942
1237
  }
943
1238
 
944
1239
  regenerateThumbnailsIfNeeded()
1240
+ regenerateWaveformIfNeeded()
1241
+ // Inset waveformView by the leading handle's chevron width so its
1242
+ // background doesn't bleed underneath the translucent handle area.
1243
+ let waveformLeft = thumbView.chevronWidth
1244
+ waveformView.frame = CGRect(x: waveformLeft, y: 0, width: max(0, thumbnailTrackView.bounds.width - waveformLeft), height: thumbnailTrackView.bounds.height)
945
1245
 
946
1246
  for thumbnail in thumbnails {
947
1247
  let position = locationForTime(thumbnail.time) - horizontalInset + thumbnailOffset
@@ -52,6 +52,11 @@ class VideoTrimmerViewController: UIViewController {
52
52
  private var trimmerColor: UIColor = UIColor.systemYellow
53
53
  private var handleIconColor: UIColor = UIColor.black
54
54
  private var isLightTheme = false
55
+ private var waveformBarColor: UIColor = .white
56
+ private var waveformBgColor: UIColor = UIColor(red: 0.204, green: 0.471, blue: 0.965, alpha: 1)
57
+ private var waveformBarWidth: CGFloat = 3
58
+ private var waveformBarGap: CGFloat = 2
59
+ private var waveformBarCornerRadius: CGFloat = 1.5
55
60
  private var iconColor: UIColor { isLightTheme ? .black : .white }
56
61
  private var dimmedIconColor: UIColor { iconColor.withAlphaComponent(0.5) }
57
62
 
@@ -243,6 +248,11 @@ class VideoTrimmerViewController: UIViewController {
243
248
 
244
249
  playerController.player = nil
245
250
  playerController.dismiss(animated: false, completion: nil)
251
+
252
+ // Setting asset to nil triggers VideoTrimmer.asset.didSet, which
253
+ // cancels all in-flight work (thumbnail generation, waveform reader,
254
+ // audio download) and deletes temporary files.
255
+ trimmer?.asset = nil
246
256
  }
247
257
 
248
258
  public func pausePlayer() {
@@ -389,6 +399,12 @@ class VideoTrimmerViewController: UIViewController {
389
399
  private func setupVideoTrimmer() {
390
400
  trimmer = VideoTrimmer()
391
401
  trimmer.isLightTheme = isLightTheme
402
+ trimmer.waveformBarColor = waveformBarColor
403
+ trimmer.waveformBgColor = waveformBgColor
404
+ trimmer.waveformBarWidth = waveformBarWidth
405
+ trimmer.waveformBarGap = waveformBarGap
406
+ trimmer.waveformBarCornerRadius = waveformBarCornerRadius
407
+ trimmer.isAudioOnly = !isVideoType
392
408
  trimmer.asset = asset
393
409
  trimmer.minimumDuration = CMTime(seconds: 1, preferredTimescale: 600)
394
410
  trimmer.enableHapticFeedback = enableHapticFeedback
@@ -972,6 +988,21 @@ class VideoTrimmerViewController: UIViewController {
972
988
  if let handleIconColorValue = config["handleIconColor"] as? Double {
973
989
  handleIconColor = RCTConvert.uiColor(handleIconColorValue) ?? (isLightTheme ? .white : .black)
974
990
  }
991
+ if let v = config["waveformColor"] as? Double {
992
+ waveformBarColor = RCTConvert.uiColor(v) ?? .white
993
+ }
994
+ if let v = config["waveformBackgroundColor"] as? Double {
995
+ waveformBgColor = RCTConvert.uiColor(v) ?? UIColor(red: 0.204, green: 0.471, blue: 0.965, alpha: 1)
996
+ }
997
+ if let v = config["waveformBarWidth"] as? Double, v > 0 {
998
+ waveformBarWidth = CGFloat(v)
999
+ }
1000
+ if let v = config["waveformBarGap"] as? Double, v >= 0 {
1001
+ waveformBarGap = CGFloat(v)
1002
+ }
1003
+ if let v = config["waveformBarCornerRadius"] as? Double, v >= 0 {
1004
+ waveformBarCornerRadius = CGFloat(v)
1005
+ }
975
1006
  }
976
1007
 
977
1008
  private func onPlayerReady() {
@@ -992,7 +1023,8 @@ class VideoTrimmerViewController: UIViewController {
992
1023
 
993
1024
  if jumpToPositionOnLoad > 0 {
994
1025
  let duration = (asset?.duration.seconds ?? 0) * 1000
995
- let time = jumpToPositionOnLoad > duration ? duration : jumpToPositionOnLoad
1026
+ let endMs = trimmer.selectedRange.end.seconds * 1000
1027
+ let time = min(jumpToPositionOnLoad, min(duration, endMs))
996
1028
  let cmtime = CMTime(value: CMTimeValue(time), timescale: 1000)
997
1029
 
998
1030
  self.seek(to: cmtime)
@@ -1 +1 @@
1
- {"version":3,"names":["TurboModuleRegistry","getEnforcing"],"sourceRoot":"../../src","sources":["NativeVideoTrim.ts"],"mappings":";;AACA,SAASA,mBAAmB,QAAQ,cAAc;;AAGlD;AACA;AACA;;AAwBA;AACA;AACA;;AAqGA;AACA;AACA;;AAQA;AACA;AACA;;AAUA;AACA;AACA;;AAcA;AACA;AACA;;AAmEA,eAAeA,mBAAmB,CAACC,YAAY,CAAO,WAAW,CAAC","ignoreList":[]}
1
+ {"version":3,"names":["TurboModuleRegistry","getEnforcing"],"sourceRoot":"../../src","sources":["NativeVideoTrim.ts"],"mappings":";;AACA,SAASA,mBAAmB,QAAQ,cAAc;;AAGlD;AACA;AACA;;AAwBA;AACA;AACA;;AA+GA;AACA;AACA;;AAQA;AACA;AACA;;AAUA;AACA;AACA;;AAcA;AACA;AACA;;AAmEA,eAAeA,mBAAmB,CAACC,YAAY,CAAO,WAAW,CAAC","ignoreList":[]}
@@ -63,6 +63,11 @@ function createEditorConfig(overrides = {}) {
63
63
  alertOnFailTitle: 'Error',
64
64
  alertOnFailMessage: 'Fail to load media. Possibly invalid file or no network connection',
65
65
  alertOnFailCloseText: 'Close',
66
+ waveformColor: processColor('white'),
67
+ waveformBackgroundColor: processColor('#3478F6'),
68
+ waveformBarWidth: 3,
69
+ waveformBarGap: 2,
70
+ waveformBarCornerRadius: 1.5,
66
71
  ...createBaseOptions(overrides),
67
72
  ...overrides
68
73
  };
@@ -88,17 +93,23 @@ export function showEditor(filePath, config) {
88
93
  const {
89
94
  headerTextColor,
90
95
  trimmerColor,
91
- handleIconColor
96
+ handleIconColor,
97
+ waveformColor,
98
+ waveformBackgroundColor
92
99
  } = config;
93
100
  const isLight = config.theme === 'light';
94
101
  const _headerTextColor = processColor(headerTextColor || (isLight ? 'black' : 'white'));
95
102
  const _trimmerColor = processColor(trimmerColor || '#f1d247');
96
103
  const _handleIconColor = processColor(handleIconColor || (isLight ? 'white' : 'black'));
104
+ const _waveformColor = processColor(waveformColor || 'white');
105
+ const _waveformBackgroundColor = processColor(waveformBackgroundColor || '#3478F6');
97
106
  VideoTrim.showEditor(filePath, createEditorConfig({
98
107
  ...config,
99
108
  headerTextColor: _headerTextColor,
100
109
  trimmerColor: _trimmerColor,
101
- handleIconColor: _handleIconColor
110
+ handleIconColor: _handleIconColor,
111
+ waveformColor: _waveformColor,
112
+ waveformBackgroundColor: _waveformBackgroundColor
102
113
  }));
103
114
  }
104
115
 
@@ -1 +1 @@
1
- {"version":3,"names":["VideoTrimNewArch","VideoTrimOldArch","processColor","isFabric","global","nativeFabricUIManager","VideoTrim","createBaseOptions","overrides","saveToPhoto","type","outputExt","removeAfterSavedToPhoto","removeAfterFailedToSavePhoto","enablePreciseTrimming","createEditorConfig","enableHapticFeedback","maxDuration","minDuration","openDocumentsOnFinish","openShareSheetOnFinish","removeAfterSavedToDocuments","removeAfterFailedToSaveDocuments","removeAfterShared","removeAfterFailedToShare","cancelButtonText","saveButtonText","enableCancelDialog","cancelDialogTitle","cancelDialogMessage","cancelDialogCancelText","cancelDialogConfirmText","enableSaveDialog","saveDialogTitle","saveDialogMessage","saveDialogCancelText","saveDialogConfirmText","trimmingText","fullScreenModalIOS","autoplay","jumpToPositionOnLoad","closeWhenFinish","enableCancelTrimming","cancelTrimmingButtonText","enableCancelTrimmingDialog","cancelTrimmingDialogTitle","cancelTrimmingDialogMessage","cancelTrimmingDialogCancelText","cancelTrimmingDialogConfirmText","headerText","headerTextSize","headerTextColor","trimmerColor","handleIconColor","zoomOnWaitingDuration","alertOnFailToLoad","alertOnFailTitle","alertOnFailMessage","alertOnFailCloseText","createTrimOptions","startTime","endTime","showEditor","filePath","config","isLight","theme","_headerTextColor","_trimmerColor","_handleIconColor","listFiles","cleanFiles","deleteFile","trim","length","Error","closeEditor","isValidFile","url","options"],"sourceRoot":"../../src","sources":["index.tsx"],"mappings":"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","ignoreList":[]}
1
+ {"version":3,"names":["VideoTrimNewArch","VideoTrimOldArch","processColor","isFabric","global","nativeFabricUIManager","VideoTrim","createBaseOptions","overrides","saveToPhoto","type","outputExt","removeAfterSavedToPhoto","removeAfterFailedToSavePhoto","enablePreciseTrimming","createEditorConfig","enableHapticFeedback","maxDuration","minDuration","openDocumentsOnFinish","openShareSheetOnFinish","removeAfterSavedToDocuments","removeAfterFailedToSaveDocuments","removeAfterShared","removeAfterFailedToShare","cancelButtonText","saveButtonText","enableCancelDialog","cancelDialogTitle","cancelDialogMessage","cancelDialogCancelText","cancelDialogConfirmText","enableSaveDialog","saveDialogTitle","saveDialogMessage","saveDialogCancelText","saveDialogConfirmText","trimmingText","fullScreenModalIOS","autoplay","jumpToPositionOnLoad","closeWhenFinish","enableCancelTrimming","cancelTrimmingButtonText","enableCancelTrimmingDialog","cancelTrimmingDialogTitle","cancelTrimmingDialogMessage","cancelTrimmingDialogCancelText","cancelTrimmingDialogConfirmText","headerText","headerTextSize","headerTextColor","trimmerColor","handleIconColor","zoomOnWaitingDuration","alertOnFailToLoad","alertOnFailTitle","alertOnFailMessage","alertOnFailCloseText","waveformColor","waveformBackgroundColor","waveformBarWidth","waveformBarGap","waveformBarCornerRadius","createTrimOptions","startTime","endTime","showEditor","filePath","config","isLight","theme","_headerTextColor","_trimmerColor","_handleIconColor","_waveformColor","_waveformBackgroundColor","listFiles","cleanFiles","deleteFile","trim","length","Error","closeEditor","isValidFile","url","options"],"sourceRoot":"../../src","sources":["index.tsx"],"mappings":"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","ignoreList":[]}
@@ -126,6 +126,16 @@ export interface EditorConfig extends BaseOptions {
126
126
  * `"light"` uses a white background with black icons/text and white trimmer-handle chevrons.
127
127
  */
128
128
  theme?: string;
129
+ /** Color of the audio waveform bars as a `processColor` value. */
130
+ waveformColor?: number;
131
+ /** Background color behind the audio waveform bars as a `processColor` value. */
132
+ waveformBackgroundColor?: number;
133
+ /** Width of each waveform bar in dp/pt (default: `3`). */
134
+ waveformBarWidth?: number;
135
+ /** Gap between waveform bars in dp/pt (default: `2`). */
136
+ waveformBarGap?: number;
137
+ /** Corner radius of waveform bars in dp/pt (default: `1.5`). */
138
+ waveformBarCornerRadius?: number;
129
139
  }
130
140
  /**
131
141
  * Options for headless (non-UI) trim operations.
@@ -1 +1 @@
1
- {"version":3,"file":"NativeVideoTrim.d.ts","sourceRoot":"","sources":["../../../src/NativeVideoTrim.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"NativeVideoTrim.d.ts","sourceRoot":"","sources":["../../../src/NativeVideoTrim.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAEhD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,2CAA2C,CAAC;AAE9E;;GAEG;AACH,MAAM,WAAW,WAAW;IAC1B,qEAAqE;IACrE,WAAW,EAAE,OAAO,CAAC;IACrB,0CAA0C;IAC1C,IAAI,EAAE,MAAM,CAAC;IACb,qDAAqD;IACrD,SAAS,EAAE,MAAM,CAAC;IAClB,sFAAsF;IACtF,uBAAuB,EAAE,OAAO,CAAC;IACjC,8EAA8E;IAC9E,4BAA4B,EAAE,OAAO,CAAC;IACtC;;;;;;;;OAQG;IACH,qBAAqB,EAAE,OAAO,CAAC;CAChC;AAED;;GAEG;AACH,MAAM,WAAW,YAAa,SAAQ,WAAW;IAC/C,2EAA2E;IAC3E,oBAAoB,EAAE,OAAO,CAAC;IAC9B,+FAA+F;IAC/F,WAAW,EAAE,MAAM,CAAC;IACpB,+FAA+F;IAC/F,WAAW,EAAE,MAAM,CAAC;IACpB,8EAA8E;IAC9E,qBAAqB,EAAE,OAAO,CAAC;IAC/B,+DAA+D;IAC/D,sBAAsB,EAAE,OAAO,CAAC;IAChC,8EAA8E;IAC9E,2BAA2B,EAAE,OAAO,CAAC;IACrC,sEAAsE;IACtE,gCAAgC,EAAE,OAAO,CAAC;IAC1C,kEAAkE;IAClE,iBAAiB,EAAE,OAAO,CAAC;IAC3B,0DAA0D;IAC1D,wBAAwB,EAAE,OAAO,CAAC;IAClC,kCAAkC;IAClC,gBAAgB,EAAE,MAAM,CAAC;IACzB,gCAAgC;IAChC,cAAc,EAAE,MAAM,CAAC;IACvB,+EAA+E;IAC/E,kBAAkB,EAAE,OAAO,CAAC;IAC5B,+CAA+C;IAC/C,iBAAiB,EAAE,MAAM,CAAC;IAC1B,iDAAiD;IACjD,mBAAmB,EAAE,MAAM,CAAC;IAC5B,qEAAqE;IACrE,sBAAsB,EAAE,MAAM,CAAC;IAC/B,qEAAqE;IACrE,uBAAuB,EAAE,MAAM,CAAC;IAChC,6EAA6E;IAC7E,gBAAgB,EAAE,OAAO,CAAC;IAC1B,6CAA6C;IAC7C,eAAe,EAAE,MAAM,CAAC;IACxB,+CAA+C;IAC/C,iBAAiB,EAAE,MAAM,CAAC;IAC1B,mEAAmE;IACnE,oBAAoB,EAAE,MAAM,CAAC;IAC7B,mEAAmE;IACnE,qBAAqB,EAAE,MAAM,CAAC;IAC9B,oFAAoF;IACpF,YAAY,EAAE,MAAM,CAAC;IACrB,sEAAsE;IACtE,kBAAkB,EAAE,OAAO,CAAC;IAC5B,4DAA4D;IAC5D,QAAQ,EAAE,OAAO,CAAC;IAClB,yFAAyF;IACzF,oBAAoB,EAAE,MAAM,CAAC;IAC7B,wEAAwE;IACxE,eAAe,EAAE,OAAO,CAAC;IACzB,yEAAyE;IACzE,oBAAoB,EAAE,OAAO,CAAC;IAC9B,2CAA2C;IAC3C,wBAAwB,EAAE,MAAM,CAAC;IACjC,iFAAiF;IACjF,0BAA0B,EAAE,OAAO,CAAC;IACpC,wDAAwD;IACxD,yBAAyB,EAAE,MAAM,CAAC;IAClC,0DAA0D;IAC1D,2BAA2B,EAAE,MAAM,CAAC;IACpC,iEAAiE;IACjE,8BAA8B,EAAE,MAAM,CAAC;IACvC,iEAAiE;IACjE,+BAA+B,EAAE,MAAM,CAAC;IACxC,6DAA6D;IAC7D,UAAU,EAAE,MAAM,CAAC;IACnB,6CAA6C;IAC7C,cAAc,EAAE,MAAM,CAAC;IACvB,0DAA0D;IAC1D,eAAe,EAAE,MAAM,CAAC;IACxB,yEAAyE;IACzE,iBAAiB,EAAE,OAAO,CAAC;IAC3B,uCAAuC;IACvC,gBAAgB,EAAE,MAAM,CAAC;IACzB,yCAAyC;IACzC,kBAAkB,EAAE,MAAM,CAAC;IAC3B,2DAA2D;IAC3D,oBAAoB,EAAE,MAAM,CAAC;IAC7B,kGAAkG;IAClG,0BAA0B,CAAC,EAAE,OAAO,CAAC;IACrC,0DAA0D;IAC1D,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,8EAA8E;IAC9E,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB;;;;OAIG;IACH,qBAAqB,CAAC,EAAE,MAAM,CAAC;IAC/B;;;OAGG;IACH,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,kEAAkE;IAClE,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,iFAAiF;IACjF,uBAAuB,CAAC,EAAE,MAAM,CAAC;IACjC,0DAA0D;IAC1D,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,yDAAyD;IACzD,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,gEAAgE;IAChE,uBAAuB,CAAC,EAAE,MAAM,CAAC;CAClC;AAED;;GAEG;AACH,MAAM,WAAW,WAAY,SAAQ,WAAW;IAC9C,oDAAoD;IACpD,SAAS,EAAE,MAAM,CAAC;IAClB,kDAAkD;IAClD,OAAO,EAAE,MAAM,CAAC;CACjB;AAED;;GAEG;AACH,MAAM,WAAW,oBAAoB;IACnC,uDAAuD;IACvD,OAAO,EAAE,OAAO,CAAC;IACjB,mEAAmE;IACnE,QAAQ,EAAE,MAAM,CAAC;IACjB,sEAAsE;IACtE,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED;;GAEG;AACH,MAAM,WAAW,UAAU;IACzB,uDAAuD;IACvD,SAAS,EAAE,MAAM,CAAC;IAClB,qDAAqD;IACrD,OAAO,EAAE,MAAM,CAAC;IAChB,oDAAoD;IACpD,QAAQ,EAAE,MAAM,CAAC;IACjB,gDAAgD;IAChD,UAAU,EAAE,MAAM,CAAC;IACnB,yDAAyD;IACzD,OAAO,EAAE,OAAO,CAAC;CAClB;AAED;;GAEG;AACH,MAAM,WAAW,IAAK,SAAQ,WAAW;IACvC,wDAAwD;IACxD,UAAU,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,YAAY,GAAG,IAAI,CAAC;IACzD,+DAA+D;IAC/D,SAAS,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC;IAC/B,sGAAsG;IACtG,UAAU,IAAI,OAAO,CAAC,MAAM,CAAC,CAAC;IAC9B,0EAA0E;IAC1E,UAAU,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IAC/C,iEAAiE;IACjE,WAAW,IAAI,IAAI,CAAC;IACpB,yEAAyE;IACzE,WAAW,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,oBAAoB,CAAC,CAAC;IACxD,mFAAmF;IACnF,IAAI,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,EAAE,WAAW,GAAG,OAAO,CAAC,UAAU,CAAC,CAAC;IAE7D,8CAA8C;IAC9C,QAAQ,CAAC,eAAe,EAAE,YAAY,CAAC,IAAI,CAAC,CAAC;IAC7C,mEAAmE;IACnE,QAAQ,CAAC,gBAAgB,EAAE,YAAY,CAAC,IAAI,CAAC,CAAC;IAC9C,mEAAmE;IACnE,QAAQ,CAAC,QAAQ,EAAE,YAAY,CAAC,IAAI,CAAC,CAAC;IACtC,yCAAyC;IACzC,QAAQ,CAAC,MAAM,EAAE,YAAY,CAAC,IAAI,CAAC,CAAC;IACpC,wCAAwC;IACxC,QAAQ,CAAC,MAAM,EAAE,YAAY,CAAC,IAAI,CAAC,CAAC;IACpC,yFAAyF;IACzF,QAAQ,CAAC,gBAAgB,EAAE,YAAY,CAAC;QACtC,gDAAgD;QAChD,UAAU,EAAE,MAAM,CAAC;QACnB,uDAAuD;QACvD,SAAS,EAAE,MAAM,CAAC;QAClB,qDAAqD;QACrD,OAAO,EAAE,MAAM,CAAC;QAChB,oDAAoD;QACpD,QAAQ,EAAE,MAAM,CAAC;KAClB,CAAC,CAAC;IACH,sDAAsD;IACtD,QAAQ,CAAC,KAAK,EAAE,YAAY,CAAC;QAC3B,KAAK,EAAE,MAAM,CAAC;QACd,OAAO,EAAE,MAAM,CAAC;QAChB,SAAS,EAAE,MAAM,CAAC;KACnB,CAAC,CAAC;IACH,+DAA+D;IAC/D,QAAQ,CAAC,YAAY,EAAE,YAAY,CAAC;QAClC,SAAS,EAAE,MAAM,CAAC;QAClB,gBAAgB,EAAE,MAAM,CAAC;QACzB,QAAQ,EAAE,MAAM,CAAC;QACjB,YAAY,EAAE,MAAM,CAAC;QACrB,IAAI,EAAE,MAAM,CAAC;QACb,IAAI,EAAE,MAAM,CAAC;QACb,OAAO,EAAE,MAAM,CAAC;QAChB,KAAK,EAAE,MAAM,CAAC;KACf,CAAC,CAAC;IACH,oEAAoE;IACpE,QAAQ,CAAC,OAAO,EAAE,YAAY,CAAC;QAC7B,OAAO,EAAE,MAAM,CAAC;QAChB,SAAS,EAAE,MAAM,CAAC;KACnB,CAAC,CAAC;IACH,sEAAsE;IACtE,QAAQ,CAAC,MAAM,EAAE,YAAY,CAAC;QAC5B,oDAAoD;QACpD,QAAQ,EAAE,MAAM,CAAC;KAClB,CAAC,CAAC;CACJ;;AAED,wBAAmE"}
@@ -8,10 +8,12 @@ declare const VideoTrim: any;
8
8
  * @param {Function} onEvent: event callback
9
9
  * @returns {void}
10
10
  */
11
- export declare function showEditor(filePath: string, config: Partial<Omit<EditorConfig, 'headerTextColor' | 'trimmerColor' | 'handleIconColor'>> & {
11
+ export declare function showEditor(filePath: string, config: Partial<Omit<EditorConfig, 'headerTextColor' | 'trimmerColor' | 'handleIconColor' | 'waveformColor' | 'waveformBackgroundColor'>> & {
12
12
  headerTextColor?: string;
13
13
  trimmerColor?: string;
14
14
  handleIconColor?: string;
15
+ waveformColor?: string;
16
+ waveformBackgroundColor?: string;
15
17
  }): void;
16
18
  /**
17
19
  * List output files generated at all time