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.preferredTransform
wasn'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
orientation
Full usage: