【问题标题】:How can I record a video and synchronize it with an AVPlayer?如何录制视频并将其与 AVPlayer 同步?
【发布时间】:2020-08-07 09:24:25
【问题描述】:

我需要同时录制视频并使用 AVPlayer 播放视频。结果需要同步:如果我正在播放的视频是节拍器,或者有人在拍手,那么录制的视频和播放器应该同时点击或拍手。

我使用 preroll 和 setRate 播放 AVPlayer,并在相机控制器中有一个委托。

使用 AVCaptureMovieFileOutput,我尝试在调用 fileOutput(output:didStartRecordingTo) 后在播放器上调用 setRate,但视频最终不同步,录制的视频在播放器后面。

使用 AssetWriter,我尝试在调用 captureOutput(captureOutput:sampleBuffer) 后在播放器上调用 setRate,并附加第一个缓冲区,但结果相同。

还有其他方法吗?

编辑:添加一些代码来显示我在做什么:

带有 AVCaptureMovieFileOutput 的相机:

func startRecordingVideo() {
        guard let movieFileOutput = self.movieFileOutput else {
            return
        }

        sessionQueue.async {
            if !movieFileOutput.isRecording {

                let movieFileOutputConnection = movieFileOutput.connection(with: .video)

                movieFileOutput.setOutputSettings([AVVideoCodecKey: AVVideoCodecH264], for: movieFileOutputConnection!)

                let outputFileName = NSUUID().uuidString
                let outputFilePath = (NSTemporaryDirectory() as NSString).appendingPathComponent((outputFileName as NSString).appendingPathExtension("mov")!)
                movieFileOutput.startRecording(to: URL(fileURLWithPath: outputFilePath), recordingDelegate: self)
            } else {
                movieFileOutput.stopRecording()
            }
        }
    }

    func fileOutput(_ output: AVCaptureFileOutput, didStartRecordingTo fileURL: URL, from connections: [AVCaptureConnection]) {
        cameraDelegate?.startedRecording()
    }

在viewController中实现delegate的startRecording:

private func setRateForAll() {
        let hostTime = CMClockGetTime(CMClockGetHostTimeClock())
        activePlayers.forEach {
            $0.setRate(atHostTime: hostTime)
        }
    }

一旦活动播放器或播放器结束,我在相机上调用 stopRecording,并在另一个播放器中显示生成的录制视频,以及我一直显示的播放器。

【问题讨论】:

  • 我赞成这个问题,把它送回“0”,因为我认为这是一个很好的问题,但我猜反对票是因为你描述了代码,但是你没有提供sn-p。我知道你可能觉得没有必要,但是对于这种 Apple 提供的框架,经常会发现一些东西。
  • 谢谢!我已经添加了一些代码,我不知道它是否足够。关于会话和输入/输出的配置有很多行,我不知道显示所有这些行是否与问题相关。

标签: ios swift camera avplayer


【解决方案1】:

我最终使用录制会话主时钟作为 setRate 方法的主机时间。现在几乎感觉不到去同步了!

在文件输出中(输出:didStartRecordingTo):

cameraDelegate?.startedRecording(clock: CMClockGetTime(self.session.masterClock!))

在与球员的视野中:

private func setRateForAll(clock: CMTime) {
        activePlayers.forEach {
            $0.setRate(atHostTime: clock)
        }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-10-04
    • 1970-01-01
    • 2011-09-17
    • 2011-09-25
    • 1970-01-01
    • 2018-04-02
    • 2012-02-26
    • 1970-01-01
    相关资源
    最近更新 更多