如何录制视频并将其与 AVPlayer 同步?
How can I record a video and synchronize it with an AVPlayer?
我需要录制视频并同时使用 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 {
[=11=].setRate(atHostTime: hostTime)
}
}
活动播放器结束后,我会在相机上调用 stopRecording,并在另一个播放器中显示生成的录制视频,以及我一直在播放的播放器。
我最终使用记录会话主时钟作为 setRate 方法的主机时间。去同步化现在几乎察觉不到!
在文件输出中(输出:didStartRecordingTo):
cameraDelegate?.startedRecording(clock: CMClockGetTime(self.session.masterClock!))
与玩家一起观看:
private func setRateForAll(clock: CMTime) {
activePlayers.forEach {
[=11=].setRate(atHostTime: clock)
}
}
我需要录制视频并同时使用 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 {
[=11=].setRate(atHostTime: hostTime)
}
}
活动播放器结束后,我会在相机上调用 stopRecording,并在另一个播放器中显示生成的录制视频,以及我一直在播放的播放器。
我最终使用记录会话主时钟作为 setRate 方法的主机时间。去同步化现在几乎察觉不到!
在文件输出中(输出:didStartRecordingTo):
cameraDelegate?.startedRecording(clock: CMClockGetTime(self.session.masterClock!))
与玩家一起观看:
private func setRateForAll(clock: CMTime) {
activePlayers.forEach {
[=11=].setRate(atHostTime: clock)
}
}