I am creating an AVMutableComposition. I need the asset to be flipped horizontally, so I am setting the transform of the composition track like this:
compositionTrack.preferredTransform = assetTrack.preferredTransform.scaledBy(x: -1, y: 1)
If I export this (I use AVAssetPreset960x640 as my preset), this works as expected.
However, I also need to add an AVMutableVideoComposition overlay to be rendered with this copmosition. This overlay shouldn't be flipped horizontally. I specify this like so:
// Create video composition
let videoComposition = AVMutableVideoComposition()
videoComposition.renderSize = videoSize
videoComposition.frameDuration = CMTime(value: 1, timescale: 30)
videoComposition.animationTool = AVVideoCompositionCoreAnimationTool(
postProcessingAsVideoLayer: videoLayer,
in: outputLayer
)
let instruction = AVMutableVideoCompositionInstruction()
instruction.timeRange = CMTimeRange(
start: .zero,
duration: composition.duration
)
let layerInstruction = AVMutableVideoCompositionLayerInstruction(assetTrack: compositionTrack)
layerInstruction.setTransform(assetTrack.preferredTransform, at: .zero)
instruction.layerInstructions = [layerInstruction]
videoComposition.instructions = [instruction]
When I export the video with this, it isn't flipped horizontally. It stops the preferredTransform applied to the composition from being performed. Presumably it's this line that is causing this:
layerInstruction.setTransform(assetTrack.preferredTransform, at: .zero)
If I set the layer transform to instead be assetTrack.preferredTransform.scaledBy(x: -1, y: 1) or compositionTrack.preferredTransform, I'm presented with a black screen on export.
Apple have these docs explaining transforms on an AVVideoComposition. If I understand correctly, they say that I should just be setting the transform of the layer instruction. If I do that – applying a transform to the layer instruction and not the composition - I'm still presented with a black screen.
Why is this and how can I fix this?
Edit: the transform that worked was
So I ran into this issue a while back, following this RayWenderlich tutorial (your code looks extremely familiar too!). The problem was that
assetTrack.preferredTransformwasn't reliable, on some videos it would work, and on others it would be a black screen.Instead of
Try this:
I based this off another answer on SO, can't remember where though.
Here's a helper function, to get
orientationFull usage: