gpt4 book ai didi

ios - AVMutableComposition 以某种方式将纵向视频导出为横向

转载 作者:行者123 更新时间:2023-12-02 03:46:08 24 4
gpt4 key购买 nike

当源视频为纵向时,此功能会将合并的合成导出为横向。我将原始视频以纵向保存到我的文档目录中,然后将其保存到相机胶卷中并且工作正常。然后,我将保存的视频的 URL 传递给该函数,它会以某种方式将其旋转为横向,而不是不应该旋转。我该如何解决这个问题?

func makeVideoOverlay (url : URL) {

print("documents directory url: \(url)")

let composition = AVMutableComposition()
let vidAsset = AVURLAsset(url: url as URL, options: nil)

// get video track

let vtrack = vidAsset.tracks(withMediaType: AVMediaTypeVideo)
let videoTrack:AVAssetTrack = vtrack[0]
let vid_duration = videoTrack.timeRange.duration
let vid_timerange = CMTimeRangeMake(kCMTimeZero, vidAsset.duration)

//var error: NSError?

let compositionvideoTrack:AVMutableCompositionTrack = composition.addMutableTrack(withMediaType: AVMediaTypeVideo, preferredTrackID: CMPersistentTrackID())

do {
try compositionvideoTrack.insertTimeRange(vid_timerange, of: videoTrack, at: kCMTimeZero)
} catch {
// handle error

print("comp video track error: \(error.localizedDescription)")
}

compositionvideoTrack.preferredTransform = videoTrack.preferredTransform

let size = videoTrack.naturalSize

//this prints out to 1920x1080 landscape dimension. i don't know how

print("asset size: \(size)")

// Watermark Effect

let imglogo = UIImage(named: "logo-image")
let imglayer = CALayer()
imglayer.contents = imglogo?.cgImage
imglayer.frame = CGRect.init(x: 5, y: size.height-160, width: 150, height: 150)
imglayer.opacity = 1.0

let videolayer = CALayer()
videolayer.frame = CGRect.init(x: 0, y: 0, width: size.width, height: size.height)

let parentlayer = CALayer()
parentlayer.frame = CGRect.init(x: 0, y: 0, width: size.width, height: size.height)

parentlayer.addSublayer(videolayer)
parentlayer.addSublayer(imglayer)

let layercomposition = AVMutableVideoComposition()
layercomposition.frameDuration = CMTimeMake(1, 30)
layercomposition.renderSize = size
layercomposition.animationTool = AVVideoCompositionCoreAnimationTool(postProcessingAsVideoLayer: videolayer, in: parentlayer)

// instruction for watermark

let instruction = AVMutableVideoCompositionInstruction()
instruction.timeRange = CMTimeRangeMake(kCMTimeZero, composition.duration)

let videotrack = composition.tracks(withMediaType: AVMediaTypeVideo)[0] as AVAssetTrack
let layerinstruction = AVMutableVideoCompositionLayerInstruction(assetTrack: videotrack)

instruction.layerInstructions = NSArray(object: layerinstruction) as [AnyObject] as [AnyObject] as! [AVVideoCompositionLayerInstruction]

layercomposition.instructions = NSArray(object: instruction) as [AnyObject] as [AnyObject] as! [AVVideoCompositionInstructionProtocol]

// create new file to receive data

let dirPaths = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true)
let docsDir: String = dirPaths[0] as String


let movieFilePath = docsDir.appending("/result.mov") as String

movieDestinationUrl = URL(fileURLWithPath: movieFilePath)

print("overlay destination url: \(movieDestinationUrl)")

// use AVAssetExportSession to export video

let assetExport = AVAssetExportSession(asset: composition, presetName:AVAssetExportPresetHighestQuality)

assetExport?.outputFileType = AVFileTypeQuickTimeMovie
assetExport?.outputURL = movieDestinationUrl as URL

assetExport?.videoComposition = layercomposition

assetExport?.exportAsynchronously(completionHandler: {

if assetExport?.status == AVAssetExportSessionStatus.failed
{
print("failed: \(assetExport?.error)")
}
else if assetExport?.status == AVAssetExportSessionStatus.cancelled
{
print("cancelled: \(assetExport?.error)")
}
else
{
print("Movie complete")

OperationQueue.main.addOperation({ () -> Void in

//saves in landscape
self.saveAsset(url: self.movieDestinationUrl)
})
}
})
}

最佳答案

AVMutableVideoCompositionLayerInstruction 有一个方法 setTransform(_:at:)

documentation

Sets a fixed transform to apply from the specified time until the next time at which a transform is set. [...]. Before the first specified time for which a transform is set, the affine transform is held constant at the value of identity ; after the last time for which a transform is set, the affine transform is held constant at that last value.

您应该将 videoTrackpreferredTransform 设置为 layerInstruction

编辑

您需要使用新创建的合成轨道来创建layerinstruction

let layerinstruction = AVMutableVideoCompositionLayerInstruction(assetTrack:compositionvideoTrack)//不是 videoTrack。
layerinstruction.setTransform(videoTrack.preferredTransform, at: kCMTimeZero)

关于ios - AVMutableComposition 以某种方式将纵向视频导出为横向,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44790444/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com