在Swift3 iOS中为捕获的视频添加过滤效果后,音频丢失

时间:2018-04-04 10:54:43

标签: ios swift avfoundation video-processing cifilter

我正在开发基于视频的应用程序,我需要将CIFilter添加到从设备库中选择的捕获视频。为此我在VideoEffects库下面使用:

https://github.com/FlexMonkey/VideoEffects

使用此功能,我可以为视频添加过滤器,但问题是最终视频输出中缺少音频。我尝试下面的代码来添加音频资产但不起作用:

videoOutputURL = documentDirectory.appendingPathComponent("Output_\(timeDateFormatter.string(from: Date())).mp4")

    do {
      videoWriter = try AVAssetWriter(outputURL: videoOutputURL!, fileType: AVFileTypeMPEG4)
    }
    catch {
      fatalError("** unable to create asset writer **")
    }

    let outputSettings: [String : AnyObject] = [
      AVVideoCodecKey: AVVideoCodecH264 as AnyObject,
      AVVideoWidthKey: currentItem.presentationSize.width as AnyObject,
      AVVideoHeightKey: currentItem.presentationSize.height as AnyObject]

    guard videoWriter!.canApply(outputSettings: outputSettings, forMediaType: AVMediaTypeVideo) else {
      fatalError("** unable to apply video settings ** ")
    }


    videoWriterInput = AVAssetWriterInput(
      mediaType: AVMediaTypeVideo,
      outputSettings: outputSettings)


    //setup audio writer
    let audioOutputSettings: Dictionary<String, AnyObject> = [
        AVFormatIDKey : Int(kAudioFormatMPEG4AAC) as AnyObject,
        AVSampleRateKey:48000.0 as AnyObject,
        AVNumberOfChannelsKey:NSNumber(value: 1),
        AVEncoderBitRateKey : 128000 as AnyObject
    ]

    guard videoWriter!.canApply(outputSettings: audioOutputSettings, forMediaType: AVMediaTypeAudio) else {
        fatalError("** unable to apply Audio settings ** ")
    }

    audioWriterInput = AVAssetWriterInput(
        mediaType: AVMediaTypeAudio,
        outputSettings: audioOutputSettings)


    if videoWriter!.canAdd(videoWriterInput!) {
      videoWriter!.add(videoWriterInput!)
      videoWriter!.add(audioWriterInput!)
    }
    else {
      fatalError ("** unable to add input **")
    }

有没有其他方法可以为视频添加过滤器?请建议我。

此外,我尝试使用GPUImage添加CIFilter,但这仅适用于实时视频,而非捕获的视频。

1 个答案:

答案 0 :(得分:1)

从iOS 9.0开始,您可以使用AVVideoComposition逐帧应用核心图像过滤器。

let filter = CIFilter(name: "CIGaussianBlur")!
let composition = AVVideoComposition(asset: asset, applyingCIFiltersWithHandler: { request in
        // Clamp to avoid blurring transparent pixels at the image edges
        let source = request.sourceImage.imageByClampingToExtent()
        filter.setValue(source, forKey: kCIInputImageKey)

        // Vary filter parameters based on video timing
        let seconds = CMTimeGetSeconds(request.compositionTime)
        filter.setValue(seconds * 10.0, forKey: kCIInputRadiusKey)

        // Crop the blurred output to the bounds of the original image
        let output = filter.outputImage!.imageByCroppingToRect(request.sourceImage.extent)

        request.finish(with: output, context: nil)
})

现在我们可以使用之前创建的资产创建AVPlayerItem并使用AVPlayer

播放它
let playerItem = AVPlayerItem(asset: asset)
playerItem.videoComposition = composition
let player = AVPlayer(playerItem: playerItem)
player.play()

核心图像过滤器逐帧实时添加。您还可以使用AVAssetExportSession类导出视频。

这里是WWDC 2015的精彩介绍:Link