AVCaptureFileOutputRecordingDelegate返回URL无法用AVPlayer播放问题排查
问题分析与解决方案
核心问题出在录制输出的文件没有指定正确的扩展名,这导致AVPlayer无法识别视频的容器格式,所以本地播放失败;但上传到Firebase后,文件本身的编码是正常的,下载后就能正常播放了。
具体原因
在你的takeVideo方法中,生成输出路径时只写了"temp"作为文件名,没有添加视频文件的扩展名:
let filePath = documentsURL.appendingPathComponent("temp")
AVCaptureMovieFileOutput默认输出QuickTime格式的视频(.mov容器),如果没有扩展名,AVPlayer无法正确解析文件的格式信息,自然无法播放。
修复步骤
修改takeVideo方法中的文件路径,添加.mov扩展名,同时增加旧文件删除逻辑(避免同名文件导致录制失败):
@objc func takeVideo() { let recordingDelegate:AVCaptureFileOutputRecordingDelegate? = self if captureSession?.outputs != nil && videoFileOutput != nil { captureSession?.removeOutput(videoFileOutput!) } videoFileOutput = AVCaptureMovieFileOutput() self.captureSession?.addOutput(videoFileOutput!) let documentsURL = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)[0] // 添加.mov扩展名,明确视频容器格式 let filePath = documentsURL.appendingPathComponent("temp.mov") // 若路径已存在同名文件,先删除避免录制失败 if FileManager.default.fileExists(atPath: filePath.path) { try? FileManager.default.removeItem(at: filePath) } videoFileOutput?.startRecording(to: filePath, recordingDelegate: recordingDelegate!) }
额外验证建议
- 在
fileOutput回调中打印文件路径,确认文件存在且扩展名正确:
func fileOutput(_ output: AVCaptureFileOutput, didFinishRecordingTo outputFileURL: URL, from connections: [AVCaptureConnection], error: Error?) { if error == nil { print("录制完成,文件路径:\(outputFileURL.path)") // 检查路径是否带.mov videoURL = outputFileURL flipHiddenViews() // playback video player = AVPlayer(url: outputFileURL) playerLayer = AVPlayerLayer(player: player) playerLayer?.frame = self.view.bounds self.view.layer.addSublayer(playerLayer!) player?.play() } else { print(error?.localizedDescription) } }
- 确保
captureSession已正确配置摄像头/音频输入,且调用了captureSession?.startRunning()启动会话。
这样修改后,AVPlayer就能正确识别并播放本地录制的视频了。
内容的提问来源于stack exchange,提问作者kbunarjo
相关产品推荐
相关产品推荐

