【问题标题】:How can I add display only cifilter on live video capture in swift?如何快速在实时视频捕获中添加仅显示 cifilter?
【发布时间】:2021-06-19 19:27:00
【问题描述】:

我正在开发一个需要创建录像机的功能。我想在实时捕获中显示 cifilter。是的,可以在实时捕获中添加过滤器并使用以下代码保存:

 func captureOutput(_ output: AVCaptureOutput, didOutput sampleBuffer: CMSampleBuffer, from connection: AVCaptureConnection) {
        connection.videoOrientation = orientation
        let videoOutput = AVCaptureVideoDataOutput()
        videoOutput.setSampleBufferDelegate(self, queue: DispatchQueue.main)
        
        let comicEffect = CIFilter(name: "CISepiaTone")
        
        let pixelBuffer = CMSampleBufferGetImageBuffer(sampleBuffer)
        let cameraImage = CIImage(cvImageBuffer: pixelBuffer!)
        
        comicEffect!.setValue(cameraImage, forKey: kCIInputImageKey)
        
        let cgImage = self.context.createCGImage(comicEffect!.outputImage!, from: cameraImage.extent)!
        
        DispatchQueue.main.async {
            let filteredImage = UIImage(cgImage: cgImage)
            self.filteredImage.image = filteredImage
        }
    }

但我的要求不同。我只想显示视频捕获的过滤器。应用的过滤器应仅在捕获时向用户显示,并且不应使用过滤器保存视频。我希望在没有任何过滤器的情况下保存捕获的视频。我可以使用 AVFoundation 来捕捉视频:

    let captureSession = AVCaptureSession()

    let movieOutput = AVCaptureMovieFileOutput()

    var previewLayer: AVCaptureVideoPreviewLayer!

    var activeInput: AVCaptureDeviceInput!
        //Setup 
       previewLayer = AVCaptureVideoPreviewLayer(session: captureSession)
        previewLayer.frame = camPreview.bounds
        previewLayer.videoGravity = AVLayerVideoGravity.resizeAspectFill
        camPreview.layer.addSublayer(previewLayer)

//MARK:- Camera Session
    func startSession() {
    
        if !captureSession.isRunning {
            videoQueue().async {
                self.captureSession.startRunning()
            }
        }
    }

    func stopSession() {
        if captureSession.isRunning {
            videoQueue().async {
                self.captureSession.stopRunning()
            }
        }
    }

    func videoQueue() -> DispatchQueue {
        return DispatchQueue.main
    }
  ///Get output  after stop recording
func fileOutput(_ output: AVCaptureFileOutput, didFinishRecordingTo outputFileURL: URL, from connections: [AVCaptureConnection], error: Error?) {
    
        if (error != nil) {
        
            print("Error recording movie: \(error!.localizedDescription)")
        
        } else {
        
            let videoRecorded = outputURL! as URL
            DispatchQueue.main.async {
    let savedVDOAsset = AVAsset(url: videoRecorded)
    let playerController = AVPlayerViewController()
    let playerItem = AVPlayerItem(asset: savedVDOAsset)
    let player = AVPlayer(playerItem: playerItem)
    playerController.player = player
    self.present(playerController, animated: true, completion: {
        playerController.player!.play()
    })
            }
        }
    }

我的意思是我可以以不同的方式做这两件事(捕捉视频和在视频上显示过滤器)。但是找不到如何同时做这两件事。 再说一遍:我不想用过滤器保存视频。过滤器仅用于显示。同时需要捕获和保存视频。 我怎样才能做到这一点?请给我建议。

【问题讨论】:

    标签: swift avfoundation video-capture cifilter


    【解决方案1】:

    我不是视频捕捉方面的专家,但无论如何我都会尝试回答。

    要使用过滤器显示(实时)视频,您应该在 MTKView 中渲染 CIFilter 的输出。简而言之,您创建一个带有过滤器的 CIImage,并要求 MTKView 使用该图像绘制自己,每次调用 captureOutput(每一帧)。

    您可以在本教程中找到如何在 MTKView 中流式传输实时摄像机源:https://betterprogramming.pub/using-cifilters-metal-to-make-a-custom-camera-in-ios-c76134993316

    请注意,将帧缩放到 MTKView 可绘制对象中可能会出现一些问题,在这种情况下,请参阅此线程: here

    此外,在线程中,您可以找到一些示例代码,这些示例代码取自我刚刚编写的项目。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-06-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多