rgo*_*alv 5 iphone calayer uiview ios swift
我问了这个问题:拍摄 UIView 的快照,除了一些按钮,以了解如何导出带有 UIViews 的图片。
现在,我想知道如何导出带有 UIView 的视频。这是我正在使用的代码:
func createFinalVideo(){
let composition = AVMutableComposition()
let vidAsset = AVURLAsset(URL: myURL, options: nil)
// get video track
let vtrack = vidAsset.tracksWithMediaType(AVMediaTypeVideo)
let videoTrack:AVAssetTrack = vtrack[0]
let vid_timerange = CMTimeRangeMake(kCMTimeZero, vidAsset.duration)
let audioTrack = vidAsset.tracksWithMediaType(AVMediaTypeAudio)[0]
let compositionVideoTrack:AVMutableCompositionTrack = composition.addMutableTrackWithMediaType(AVMediaTypeVideo, preferredTrackID: CMPersistentTrackID())
let compositionAudioTrack = composition.addMutableTrackWithMediaType(AVMediaTypeAudio, preferredTrackID: CMPersistentTrackID(kCMPersistentTrackID_Invalid))
do {
try compositionVideoTrack.insertTimeRange(vid_timerange, ofTrack: videoTrack, atTime: kCMTimeZero)
try compositionAudioTrack.insertTimeRange(vid_timerange, ofTrack: audioTrack, atTime: kCMTimeZero)
}
catch let error as NSError{
print("THERE SHOULD BE ERROR DIFFERENT THAN NIL")
print(error)
return;
}
compositionVideoTrack.preferredTransform = videoTrack.preferredTransform
// Watermark Effect
let contentLayer = CALayer()
contentLayer.addSublayer(self.myTextView.layer)
contentLayer.frame = CGRectMake(0, 0, self.view.bounds.width, self.view.bounds.height)
let titleLayer = CATextLayer()
titleLayer.string = "DO YOU HEAR THE PEOPLE SING?"
titleLayer.fontSize = 18
titleLayer.foregroundColor = UIColor.redColor().CGColor
titleLayer.alignmentMode = kCAAlignmentCenter
titleLayer.frame = CGRectMake(20, 10, self.view.bounds.width - 40, 20);
titleLayer.displayIfNeeded()
let parentlayer = CALayer()
parentlayer.frame = CGRectMake(0, 0, self.view.bounds.width, self.view.bounds.height)
parentlayer.addSublayer(self.playerLayer)
parentlayer.addSublayer(titleLayer)
self.view.layer.addSublayer(parentlayer)
let layercomposition = AVMutableVideoComposition()
layercomposition.frameDuration = CMTimeMake(1, 30)
layercomposition.renderSize = CGSize(width: self.view.bounds.width, height: self.view.bounds.height)
layercomposition.animationTool = AVVideoCompositionCoreAnimationTool(postProcessingAsVideoLayer: playerLayer, inLayer: parentlayer)
// instruction for watermark
let instruction = AVMutableVideoCompositionInstruction()
instruction.timeRange = CMTimeRangeMake(kCMTimeZero, composition.duration)
let videotrack = composition.tracksWithMediaType(AVMediaTypeVideo)[0] as AVAssetTrack
let layerinstruction = AVMutableVideoCompositionLayerInstruction(assetTrack: videotrack)
instruction.layerInstructions = NSArray(object: layerinstruction) as! [AVVideoCompositionLayerInstruction]
layercomposition.instructions = NSArray(object: instruction) as! [AVVideoCompositionInstructionProtocol]
// create new file to receive data
let dirPaths = NSSearchPathForDirectoriesInDomains(.DocumentDirectory, .UserDomainMask, true)
let docsDir: AnyObject = dirPaths[0]
let movieFilePath = docsDir.stringByAppendingPathComponent("completeFinalMovie.mov")
let movieDestinationUrl = NSURL(fileURLWithPath: movieFilePath)
do{
try NSFileManager.defaultManager().removeItemAtPath(movieFilePath)
}
catch let error as NSError{
print(error)
return;
}
// use AVAssetExportSession to export video
let assetExport = AVAssetExportSession(asset: composition, presetName:AVAssetExportPresetHighestQuality)!
assetExport.outputFileType = AVFileTypeQuickTimeMovie
assetExport.outputURL = movieDestinationUrl
assetExport.exportAsynchronouslyWithCompletionHandler({
switch assetExport.status{
case AVAssetExportSessionStatus.Failed:
print("failed \(assetExport.error)")
case AVAssetExportSessionStatus.Cancelled:
print("cancelled \(assetExport.error)")
default:
print("Movie complete")
// play video
NSOperationQueue.mainQueue().addOperationWithBlock({ () -> Void in
// self.playVideo(movieDestinationUrl!)
UISaveVideoAtPathToSavedPhotosAlbum(movieFilePath, self,#selector(self.handleCompletionOfVideoToGallery), nil)
})
}
})
}
Run Code Online (Sandbox Code Playgroud)
所以,在关于 firstResponder 的最后我遇到了崩溃,但这不是重要的事情,因为我创建的这个 titleLayer 只是为了测试。
我的主要问题是 UIViews 和 CALayer 如何解决我的问题。据我所知,我必须有一个 parentLayer,videoLayer(在这种情况下是我的 playerLayer,一个当前正在播放视频的 AVPlayerLayer)和一个 contentLayer,它是应该包含当前位于顶部的 UIViews 的层视频(如 Snapchat 的表情符号和录制视频顶部的文字)。如果我只是这样做,contentLayer.addSubLayer(self.emoji.layer) or contentLayer.addSubLayer(self.myTextView.layer)我会将录制的视频保存在我的画廊中,但上面没有任何内容(就像您录制 Snapchat 视频并放置表情符号、文本和其他任何内容一样,但是在尝试将视频保存到您设备的画廊时,最终保存的视频与录制的视频相同,上面没有任何表情符号和文字)。所以,有什么想法吗?
我知道 Swift 和 Objective-C,所以可以随意发布它们中的任何一个代码。