expo-pro-video-editor 0.2.11 → 0.2.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.
@@ -106,8 +106,33 @@ enum PhotoLibraryVideoExporter {
106
106
  let instruction = AVMutableVideoCompositionInstruction()
107
107
  instruction.timeRange = CMTimeRange(start: .zero, duration: sourceAsset.duration)
108
108
 
109
+ // `preferredTransform` alone rotates the frame about (0, 0) — the rotated bounding
110
+ // box can land anywhere relative to `renderSize` depending on the *actual* tx/ty
111
+ // baked into this specific asset's transform (not just its rotation angle). This
112
+ // was observed on a real device-recorded portrait asset whose preferredTransform's
113
+ // tx was 1088 — neither the natural width nor height — which put the rotated frame
114
+ // at x ∈ [512, 1088], entirely outside a 576-wide renderSize. A translation derived
115
+ // from naturalSize/renderSize assuming a "clean" rotation (as an earlier version of
116
+ // this fix did) computes zero correction in that case and leaves the frame
117
+ // off-canvas, producing a video track that composites to black while audio
118
+ // (untouched by this composition) plays fine.
119
+ //
120
+ // The robust fix doesn't assume anything about tx/ty: apply the raw transform to
121
+ // the track's actual corners, find the resulting bounding box, and translate that
122
+ // box's origin back to (0, 0) — this corrects the frame into `renderSize` no matter
123
+ // what translation the source transform happens to carry.
124
+ let corners = [
125
+ CGPoint(x: 0, y: 0),
126
+ CGPoint(x: naturalSize.width, y: 0),
127
+ CGPoint(x: 0, y: naturalSize.height),
128
+ CGPoint(x: naturalSize.width, y: naturalSize.height),
129
+ ].map { $0.applying(transform) }
130
+ let minX = corners.map(\.x).min() ?? 0
131
+ let minY = corners.map(\.y).min() ?? 0
132
+ let finalTransform = transform.concatenating(CGAffineTransform(translationX: -minX, y: -minY))
133
+
109
134
  let layerInstruction = AVMutableVideoCompositionLayerInstruction(assetTrack: videoTrack)
110
- layerInstruction.setTransform(transform, at: .zero)
135
+ layerInstruction.setTransform(finalTransform, at: .zero)
111
136
  instruction.layerInstructions = [layerInstruction]
112
137
  composition.instructions = [instruction]
113
138
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "expo-pro-video-editor",
3
- "version": "0.2.11",
3
+ "version": "0.2.13",
4
4
  "description": "Native video composition (trim, filters, text/image overlays, audio mixing) for Expo/React Native, adapted from pro_video_editor's AVFoundation and Media3 Transformer implementation.",
5
5
  "main": "build/index.js",
6
6
  "types": "build/index.d.ts",