我有一个视频,我要在上面添加图像叠加层。视频是纵向的,但是当我导出视频时,它是旋转的(但是我叠加的图像却没有旋转)。导出的视频也进行了超级放大,但是我认为这是因为我的resizeAspectFill以及它以横向导出的事实。
我尝试过旋转videoLayerInstruction,但无法使其工作
let overlayImage = mediaView.asImage()
// Create main composition & its tracks
let mainComposition = AVMutableComposition()
let compositionVideoTrack = mainComposition.addMutableTrack(withMediaType: AVMediaType.video, preferredTrackID: CMPersistentTrackID(kCMPersistentTrackID_Invalid))
let compositionAudioTrack = mainComposition.addMutableTrack(withMediaType: AVMediaType.audio, preferredTrackID: CMPersistentTrackID(kCMPersistentTrackID_Invalid))
// Get source video & audio tracks
let videoAsset = AVURLAsset(url: videoURL, options: nil)
let sourceVideoTrack = videoAsset.tracks(withMediaType: AVMediaType.video)[0]
let sourceAudioTrack = videoAsset.tracks(withMediaType: AVMediaType.audio)[0]
// Add source tracks to composition
do {
try compositionVideoTrack?.insertTimeRange(CMTimeRange(start: CMTime.zero, duration: videoAsset.duration), of: sourceVideoTrack, at: CMTime.zero)
compositionVideoTrack?.preferredTransform = sourceVideoTrack.preferredTransform
try compositionAudioTrack?.insertTimeRange(CMTimeRange(start: CMTime.zero, duration: videoAsset.duration), of: sourceAudioTrack, at: CMTime.zero)
} catch {
print("Error with insertTimeRange while exporting video: \(error)")
}
// Create video composition
let videoComposition = AVMutableVideoComposition()
// -- Set parent layer & set size equal to device bounds
let parentLayer = CALayer()
parentLayer.frame = CGRect(x: 0, y: 0, width: view.bounds.width, height: view.bounds.height)
parentLayer.backgroundColor = UIColor.red.cgColor
parentLayer.contentsGravity = CALayerContentsGravity.resizeAspectFill
// -- Set composition equal to capture settings
videoComposition.renderSize = CGSize(width: view.frame.width, height: view.frame.width)
videoComposition.frameDuration = CMTime(value: 1, timescale: Int32(sourceVideoTrack.nominalFrameRate))
// -- Add instruction to video composition object
let instruction = AVMutableVideoCompositionInstruction()
instruction.timeRange = CMTimeRange(start: CMTime.zero, duration: (compositionVideoTrack?.asset!.duration)!)
let videoLayerInstruction = AVMutableVideoCompositionLayerInstruction(assetTrack: compositionVideoTrack!)
instruction.layerInstructions = [videoLayerInstruction]
videoComposition.instructions = [instruction]
// -- Create video layer
let videoLayer = CALayer()
videoLayer.frame = parentLayer.frame
videoLayer.contentsGravity = CALayerContentsGravity.resizeAspectFill
// -- Create overlay layer
let overlayLayer = CALayer()
overlayLayer.frame = parentLayer.frame
overlayLayer.contentsGravity = CALayerContentsGravity.resizeAspectFill
overlayLayer.contents = overlayImage.cgImage
overlayLayer.contentsScale = overlayImage.scale
overlayLayer.rasterizationScale = 2.0
// -- Add sublayers to parent layer
parentLayer.addSublayer(videoLayer)
parentLayer.addSublayer(overlayLayer)
overlayLayer.shouldRasterize = true
// -- Set animation tool
videoComposition.animationTool = AVVideoCompositionCoreAnimationTool(postProcessingAsVideoLayer: videoLayer, in: parentLayer)
// Create output file
// Get Path
let documentsURL = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first
let outputPath = documentsURL?.appendingPathComponent("newVideoWithLabel.mp4")
if FileManager.default.fileExists(atPath: (outputPath?.path)!) {
do {
try FileManager.default.removeItem(atPath: (outputPath?.path)!)
}
catch {
print ("Error deleting file")
}
}
// Create exporter
let exporter = AVAssetExportSession(asset: mainComposition, presetName: AVAssetExportPresetHighestQuality)!
exporter.outputURL = outputPath//URL(string: "test111")//videoURL
exporter.outputFileType = AVFileType.mp4
exporter.videoComposition = videoComposition
exporter.shouldOptimizeForNetworkUse = true
exporter.exportAsynchronously(completionHandler: {
switch exporter.status{
case AVAssetExportSession.Status.failed:
print("failed \(exporter.error)")
case AVAssetExportSession.Status.cancelled:
print("cancelled \(exporter.error)")
default:
print("Movie complete")
// play video
OperationQueue.main.addOperation({ () -> Void in
self.present(VideoTestVC(videoURL: exporter.outputURL!), animated: true, completion: nil)
})
}
})