没有更多的信息,这似乎是您要的是WATERMARK。
不是覆盖。
水印是视频上的标记,将与视频一起保存。
叠加层通常在预览层上显示为子视图,并且不会与视频一起保存。
在此处查看:https://stackoverflow.com/a/47742108/8272698
func addWatermark(inputURL: URL,outputURL: URL,handler:@escaping (_ exportSession: AVAssetExportSession?)-> Void) {
let mixComposition = AVMutableComposition()
let asset = AVAsset(url: inputURL)
let videoTrack = asset.tracks(withMediaType: AVMediaType.video)[0]
let timerange = CMTimeRangeMake(kCMTimeZero,asset.duration)
let compositionVideoTrack:AVMutableCompositionTrack = mixComposition.addMutableTrack(withMediaType: AVMediaType.video,preferredTrackID: CMPersistentTrackID(kCMPersistentTrackID_Invalid))!
do {
try compositionVideoTrack.insertTimeRange(timerange,of: videoTrack,at: kCMTimeZero)
compositionVideoTrack.preferredTransform = videoTrack.preferredTransform
} catch {
print(error)
}
let watermarkFilter = CIFilter(name: "CISourceOverCompositing")!
let watermarkImage = CIImage(image: UIImage(named: "waterMark")!)
let videoComposition = AVVideoComposition(asset: asset) { (filteringRequest) in
let source = filteringRequest.sourceImage.clampedToExtent()
watermarkFilter.setValue(source,forKey: "inputBackgroundImage")
let transform = CGAffineTransform(translationX: filteringRequest.sourceImage.extent.width - (watermarkImage?.extent.width)! - 2,y: 0)
watermarkFilter.setValue(watermarkImage?.transformed(by: transform),forKey: "inputImage")
filteringRequest.finish(with: watermarkFilter.outputImage!,context: nil)
}
guard let exportSession = AVAssetExportSession(asset: asset,presetName: AVAssetExportPreset640x480) else {
handler(nil)
return
}
exportSession.outputURL = outputURL
exportSession.outputFileType = AVFileType.mp4
exportSession.shouldOptimizeForNetworkUse = true
exportSession.videoComposition = videoComposition
exportSession.exportAsynchronously { () -> Void in
handler(exportSession)
}
}
这里介绍了如何调用该函数。
let outputURL = NSURL.fileURL(withPath: "TempPath")
let inputURL = NSURL.fileURL(withPath: "VideoWithWatermarkPath")
addWatermark(inputURL: inputURL,outputURL: outputURL,handler: { (exportSession) in
guard let session = exportSession else {
// Error
return
}
switch session.status {
case .completed:
guard NSData(contentsOf: outputURL) != nil else {
// Error
return
}
// Now you can find the video with the watermark in the location outputURL
default:
// Error
}
})
让我知道此代码是否对您有用。
速度很快,因此需要进行一些更改。
我目前在我的一个应用程序上使用此代码。尚未将其更新为快速5
,
我没有可以利用AVFoundation的Swift实际开发环境。因此,我无法为您提供任何示例代码。
要在录制时将元数据(日期,位置,时间戳,水印,帧频等)添加为视频的叠加层,则必须在录制时逐帧,实时地处理视频源。很有可能,您必须将帧存储在缓冲区中并进行处理,然后才能实际记录它们。
现在,关于元数据,有两种类型,静态和动态。对于诸如水印之类的静态类型,它应该很容易,因为所有帧都将具有相同的效果。
但是,对于动态元数据类型(例如时间戳或GPS位置),需要考虑一些事项。处理视频帧需要计算能力和时间。因此,取决于动态数据的类型以及如何获取它们,有时处理后的值可能不是正确的值。例如,如果您在1:00:01得到一个帧,则对其进行处理并为其添加时间戳。只是假装花费了2秒钟来处理时间戳。您收到的下一帧是在1:00:02,但是直到1:00:03您才能处理它,因为处理前一帧需要2秒钟。因此,取决于您如何获得新帧的新时间戳,该时间戳值可能不是您想要的值。
对于处理动态元数据,您还应该考虑硬件滞后。例如,该软件应该将实时GPS位置数据添加到每个帧,并且在开发或测试方面没有任何滞后。但是,在现实生活中,用户在连接不良的区域中使用了该软件,并且手机在获取GPS位置时出现了滞后现象。他的某些滞后持续了长达5秒钟。在那种情况下你会做什么?您是否设置了GPS位置超时时间并使用了上一个好位置?您报告错误吗?当GPS数据可用时,您是否会推迟处理该帧(这可能会破坏实时记录),并使用昂贵的算法来尝试预测该帧的用户位置?
除了这些要考虑的因素外,我在这里还提供一些参考资料,我认为它们可能会对您有所帮助。我以为medium.com的那个看起来不错。
https://medium.com/ios-os-x-development/ios-camera-frames-extraction-d2c0f80ed05a
Adding watermark to currently recording video and save with watermark
Render dynamic text onto CVPixelBufferRef while recording video
本文链接:https://www.f2er.com/3127560.html