我需要录制视频并同时使用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中实现委托的startRecording:
private func setRateForAll() {
let hostTime = CMClockGetTime(CMClockGetHostTimeClock())
activePlayers.forEach {
$0.setRate(atHostTime: hostTime)
}
}
[活动的播放器或播放器结束后,我会在相机上调用stopRecording,并将显示的录制视频与我一直显示的播放器一起显示在另一个播放器中。
我最终将录制会话主时钟用作setRate方法的hostTime。现在几乎看不到去同步了!
在fileOutput(output:didStartRecordingTo):
cameraDelegate?.startedRecording(clock: CMClockGetTime(self.session.masterClock!))
在玩家看来:
private func setRateForAll(clock: CMTime) {
activePlayers.forEach {
$0.setRate(atHostTime: clock)
}
}