videoswift中的图像/文本叠加

我正在使用swift使用图像叠加来处理video中的水印效果。我正在使用AVFoundation ,但不知怎的,我没有成功。

以下是我的叠加图像/文字代码

  let path = NSBundle.mainBundle().pathForResource("sample_movie", ofType:"mp4") let fileURL = NSURL(fileURLWithPath: path!) let composition = AVMutableComposition() var vidAsset = AVURLAsset(URL: fileURL, options: nil) // get video track let vtrack = vidAsset.tracksWithMediaType(AVMediaTypeVideo) let videoTrack:AVAssetTrack = vtrack[0] as! AVAssetTrack let vid_duration = videoTrack.timeRange.duration let vid_timerange = CMTimeRangeMake(kCMTimeZero, vidAsset.duration) var error: NSError? let compositionvideoTrack:AVMutableCompositionTrack = composition.addMutableTrackWithMediaType(AVMediaTypeVideo, preferredTrackID: CMPersistentTrackID()) compositionvideoTrack.insertTimeRange(vid_timerange, ofTrack: videoTrack, atTime: kCMTimeZero, error: &error) compositionvideoTrack.preferredTransform = videoTrack.preferredTransform // Watermark Effect let size = videoTrack.naturalSize let imglogo = UIImage(named: "image.png") let imglayer = CALayer() imglayer.contents = imglogo?.CGImage imglayer.frame = CGRectMake(5, 5, 100, 100) imglayer.opacity = 0.6 // create text Layer let titleLayer = CATextLayer() titleLayer.backgroundColor = UIColor.whiteColor().CGColor titleLayer.string = "Dummy text" titleLayer.font = UIFont(name: "Helvetica", size: 28) titleLayer.shadowOpacity = 0.5 titleLayer.alignmentMode = kCAAlignmentCenter titleLayer.frame = CGRectMake(0, 50, size.width, size.height / 6) let videolayer = CALayer() videolayer.frame = CGRectMake(0, 0, size.width, size.height) let parentlayer = CALayer() parentlayer.frame = CGRectMake(0, 0, size.width, size.height) parentlayer.addSublayer(videolayer) parentlayer.addSublayer(imglayer) parentlayer.addSublayer(titleLayer) let layercomposition = AVMutableVideoComposition() layercomposition.frameDuration = CMTimeMake(1, 30) layercomposition.renderSize = size layercomposition.animationTool = AVVideoCompositionCoreAnimationTool(postProcessingAsVideoLayer: videolayer, 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 [AnyObject] layercomposition.instructions = NSArray(object: instruction) as [AnyObject] // create new file to receive data let dirPaths = NSSearchPathForDirectoriesInDomains(.DocumentDirectory, .UserDomainMask, true) let docsDir: AnyObject = dirPaths[0] let movieFilePath = docsDir.stringByAppendingPathComponent("result.mov") let movieDestinationUrl = NSURL(fileURLWithPath: movieFilePath) // 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: println("failed \(assetExport.error)") case AVAssetExportSessionStatus.Cancelled: println("cancelled \(assetExport.error)") default: println("Movie complete") // play video NSOperationQueue.mainQueue().addOperationWithBlock({ () -> Void in self.playVideo(movieDestinationUrl!) }) } }) 

通过这段代码,我没有达到覆盖……我不知道我做错了什么…

问题:

  • 这段代码中有没有丢失的东西? 或者这段代码有什么问题吗?
  • 此代码仅适用于录制的video或所有video,包括来自画廊的video吗?

@El Captain提供的代码可以使用。 它只缺少:

  assetExport.videoComposition = layercomposition 

您可以在AVAssetExportSession实例化后立即添加此项

注意:最初提供的代码仅导出video轨道而不导出音频轨道。 如果您需要音轨,可以在配置compositionvideoTrack后添加类似的内容:

 let compositionAudioTrack:AVMutableCompositionTrack = composition.addMutableTrackWithMediaType(AVMediaTypeAudio, preferredTrackID: CMPersistentTrackID()) for audioTrack in audioTracks { try! compositionAudioTrack.insertTimeRange(audioTrack.timeRange, ofTrack: audioTrack, atTime: kCMTimeZero) } 

对我来说(我在你的代码中看到的),你没有将parentlayer添加到屏幕上。

您创建一个CALayer()以将videolayerimglayertitleLayer添加到新图层中,但不要在屏幕上添加最后一个。

 yourView.layer.addSublayer(parentlayer) 

希望这对你有所帮助

@Rey Hernandez这对我帮助很大! 如果有人想要进一步澄清如何在video中添加音频资产,这里是组合它们的代码

  let vtrack = vidAsset.tracksWithMediaType(AVMediaTypeVideo) let videoTrack:AVAssetTrack = vtrack[0] let vid_duration = videoTrack.timeRange.duration let vid_timerange = CMTimeRangeMake(kCMTimeZero, vidAsset.duration) let atrack = vidAsset.tracksWithMediaType(AVMediaTypeAudio) let audioTrack:AVAssetTrack = atrack[0] let audio_duration = audioTrack.timeRange.duration let audio_timerange = CMTimeRangeMake(kCMTimeZero, vidAsset.duration) do { let compositionvideoTrack:AVMutableCompositionTrack = composition.addMutableTrackWithMediaType(AVMediaTypeVideo, preferredTrackID: CMPersistentTrackID()) try compositionvideoTrack.insertTimeRange(vid_timerange, ofTrack: videoTrack, atTime: kCMTimeZero) compositionvideoTrack.preferredTransform = videoTrack.preferredTransform let compositionAudioTrack:AVMutableCompositionTrack = composition.addMutableTrackWithMediaType(AVMediaTypeAudio, preferredTrackID: CMPersistentTrackID()) try! compositionAudioTrack.insertTimeRange(audio_timerange, ofTrack: audioTrack, atTime: kCMTimeZero) compositionvideoTrack.preferredTransform = audioTrack.preferredTransform } catch { print(error) }