在Swift中录制视频时如何添加叠加层?

我正在尝试使用AVFoundation在Swift中录制然后保存视频。这可行。我还尝试向视频添加一个叠加层,例如包含日期的文本标签。

例如:保存的视频不仅是摄像机看到的,而且还包括时间戳。

这是我保存视频的方式:

func fileOutput(_ output: AVCaptureFileOutput,didFinishRecordingTo outputFileURL: URL,from connections: [AVCaptureConnection],error: Error?) {
    saveVideo(toURL: movieURL!)
  }

  private func saveVideo(toURL url: URL) {
    PHPhotolibrary.shared().performChanges({
      PHAssetChangeRequest.creationRequestForAssetfromVideo(atFileURL: url)
    }) { (success,error) in
      if(success) {
        print("Video saved to Camera Roll.")
      } else {
        print("Video failed to save.")
      }
    }
  }

我有一个movieOuput的{​​{1}}。我的预览层不包含任何子层。我尝试将时间戳标签的图层添加到PreviewLayer,但这没有成功。

我已经尝试过Ray Wenderlich's examplethis stack overflow question。最后,我还尝试了this tutorial,但都无济于事。

如何在摄像机胶卷中已保存的视频中为视频添加覆盖?

aqswdefr8888 回答:在Swift中录制视频时如何添加叠加层?

没有更多的信息,这似乎是您要的是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

大家都在问