AVVideoComposition
を使用して動画の上にテキストを追加して動画を保存しようとしています。 これは私が使用するコードである:Swift 3:AVVideoCompositionを使用してテキストで動画を書き出す方法
Iはは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を作成します。その後、私は簡単なテストのためにviewDidLoad
方法のすべての3つのメソッドを実行し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!) }}}}
で動画を保存します。問題は、私がアプリを実行すると、エクスポートの結果は、それにタイトルがない元のビデオです。私はここで何が欠けていますか?私はコードの 一部IIにsubTitle1Text.backgroundColor
プロパティを追加することを確認
UPDATE
エクスポート場合subTitle1Text.frame
に対応する着色CGRect
がビデオの上に表示させます。 (See Image) AVSynchronizedLayer
を使用して再生するためにこのコードを変更すると、テキストの上に目的のレイヤーが表示されます。 これはおそらくAVFoundation
のバグです。
customVideoCompositorClass
を使用するオプションが残っているとします。その問題は、ビデオのレンダリングに多くの時間がかかることです。ここでAVVideoCompositing
を使用する例です: https://github.com/samsonjs/LayerVideoCompositor
Amritさんのお返事ありがとうございます。あなたの答えで私のコードを更新しましたが、残念ながら出力ビデオに字幕はありません。明らかに 'AVMutableVideoCompositionInstruction 'を追加しても問題は解決しないようです。これは非常に悲惨です。 – 6994
あなたの問題を解決するのに役立つ私の更新された答えをチェックしてください。 –
あなたの答えを再度一致させるためにコードを変更しました。ビデオはシミュレータで正常にエクスポートされますが、 'CATextLayer'にはタイトルはありません。あなたのお勧めによれば、私はデバイス上でプロジェクトを実行しようとしましたが、ビデオはまったくエクスポートされず、 '現在の進行== 0 'というメッセージがデバッグ領域に連続して出力されるのを待っています。私はこの問題を回避する方法も見つけられませんでした。 – 6994