我試圖使用AVVideoComposition
在視頻頂部添加一些文本並保存視頻。 這是我使用的代碼:Swift 3:如何使用AVVideoComposition導出帶有文本的視頻
我創建AVMutableComposition and AVVideoComposition
var mutableComp = AVMutableComposition()
var mutableVidComp = AVMutableVideoComposition()
var compositionSize : CGSize?
func configureAsset(){
let options = [AVURLAssetPreferPreciseDurationAndTimingKey : "true"]
let videoAsset = AVURLAsset(url: Bundle.main.url(forResource: "Car", withExtension: "mp4")! , options : options)
let videoAssetSourceTrack = videoAsset.tracks(withMediaType: AVMediaTypeVideo).first! as AVAssetTrack
compositionSize = videoAssetSourceTrack.naturalSize
let mutableVidTrack = mutableComp.addMutableTrack(withMediaType: AVMediaTypeVideo, preferredTrackID: kCMPersistentTrackID_Invalid)
let trackRange = CMTimeRangeMake(kCMTimeZero, videoAsset.duration)
do {
try mutableVidTrack.insertTimeRange(trackRange, of: videoAssetSourceTrack, at: kCMTimeZero)
mutableVidTrack.preferredTransform = videoAssetSourceTrack.preferredTransform
}catch { print(error) }
snapshot = mutableComp
mutableVidComp = AVMutableVideoComposition(propertiesOf: videoAsset)
}
II設置各層
func applyVideoEffectsToComposition() {
// 1 - Set up the text layer
let subTitle1Text = CATextLayer()
subTitle1Text.font = "Helvetica-Bold" as CFTypeRef
subTitle1Text.frame = CGRect(x: self.view.frame.midX - 60 , y: self.view.frame.midY - 50, width: 120, height: 100)
subTitle1Text.string = "Bench"
subTitle1Text.foregroundColor = UIColor.black.cgColor
subTitle1Text.alignmentMode = kCAAlignmentCenter
// 2 - The usual overlay
let overlayLayer = CALayer()
overlayLayer.addSublayer(subTitle1Text)
overlayLayer.frame = CGRect(x: 0, y: 0, width: compositionSize!.width, height: compositionSize!.height)
overlayLayer.masksToBounds = true
// 3 - set up the parent layer
let parentLayer = CALayer()
let videoLayer = CALayer()
parentLayer.frame = CGRect(x: 0, y: 0, width: compositionSize!.width, height: compositionSize!.height)
videoLayer.frame = CGRect(x: 0, y: 0, width: compositionSize!.width, height: compositionSize!.height)
parentLayer.addSublayer(videoLayer)
parentLayer.addSublayer(overlayLayer)
mutableVidComp.animationTool = AVVideoCompositionCoreAnimationTool(postProcessingAsVideoLayer: videoLayer, in: parentLayer)
}
III。保存視頻與AVMutbaleVideoComposition
func saveAsset(){
func deleteFile(_ filePath:URL) {
guard FileManager.default.fileExists(atPath: filePath.path) else { return }
do {
try FileManager.default.removeItem(atPath: filePath.path) }
catch {fatalError("Unable to delete file: \(error) : \(#function).")} }
let documentsDirectory = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)[0] as URL
let filePath = documentsDirectory.appendingPathComponent("rendered-audio.mp4")
deleteFile(filePath)
if let exportSession = AVAssetExportSession(asset: mutableComp , presetName: AVAssetExportPresetHighestQuality){
exportSession.videoComposition = mutableVidComp
// exportSession.canPerformMultiplePassesOverSourceMediaData = true
exportSession.outputURL = filePath
exportSession.shouldOptimizeForNetworkUse = true
exportSession.timeRange = CMTimeRangeMake(kCMTimeZero, mutableComp.duration)
exportSession.outputFileType = AVFileTypeQuickTimeMovie
exportSession.exportAsynchronously {
print("finished: \(filePath) : \(exportSession.status.rawValue) ")
if exportSession.status.rawValue == 4 {
print("Export failed -> Reason: \(exportSession.error!.localizedDescription))")
print(exportSession.error!) }}}}
然後我跑在viewDidLoad
法這三種方法進行快速測試。問題是,當我運行應用程序時,導出的結果是沒有標題的原始視頻。我在這裏錯過了什麼?
UPDATE
我注意到,在 部分代碼的II添加subTitle1Text.backgroundColor
特性使得彩色CGRect
相應的出口時,subTitle1Text.frame
出現在視頻的頂部。 (See Image) 當此代碼修改爲使用AVSynchronizedLayer
進行播放時,可以在視頻頂部看到所需的圖層,並在其上顯示文字。 所以也許這是AVFoundation
本身的錯誤。我想我只剩下選擇使用customVideoCompositorClass
。問題在於,渲染視頻需要很長時間。這是一個使用的示例:AVVideoCompositing
: https://github.com/samsonjs/LayerVideoCompositor
感謝您的回答Amrit。我用你的答案更新了我的代碼,但不幸的是,在輸出視頻中仍然沒有字幕。顯然,添加'AVMutableVideoCompositionInstruction'似乎無法解決問題。這令人非常痛心。 – 6994
查看我更新的答案,它會幫助你解決你的問題。 –
我改變了我的代碼以再次匹配您的答案。該視頻在模擬器中輸出正常,但在CATextLayer中沒有任何標題。因此,根據您的建議,我嘗試在設備上運行項目,但視頻根本不導出,並持續等待在調試區域持續打印消息「當前進度== 0」。我也找不到解決這個問題的方法。 – 6994