ios - 视频文件有音频,但视频播放器看不到或播放音频
问题描述
我使用 AVAssetWriter、AVAssetWriterInput 等从 iPhone 的相机/麦克风创建了一个视频文件,当我在 iMovie、QuickTime 播放器和 Davinci Resolve 中播放生成的视频时,似乎没有音频。iMovie 的音频波形为空,尽管 QuickTime 检查器显示存在音轨。
但是,我使用 Ocenaudio 打开了相同的视频文件,它可以完全正常地读取和播放音频。所以我知道音频在某个地方。
我使用了广泛可用的代码来使用 AVAssetWriter,例如:
previewVideoWriterInput = AVAssetWriterInput(mediaType: AVMediaType.video, outputSettings: videoOutputSettings)
previewVideoWriterInput.expectsMediaDataInRealTime = true
previewAudioWriterInput = AVAssetWriterInput(mediaType: AVMediaType.audio, outputSettings: audioOutputSettings)
previewAudioWriterInput.expectsMediaDataInRealTime = true
if previewVideoWriter.canAdd(previewVideoWriterInput) == true { previewVideoWriter.add(previewVideoWriterInput) }
if previewVideoWriter.canAdd(previewAudioWriterInput) == true { previewVideoWriter.add(previewAudioWriterInput) }
主要区别在于我在 captureOutput() 函数中对视频数据使用 CIFilter。这是我的 captureOutout() 代码的简化版本:
func captureOutput(_ output: AVCaptureOutput, didOutput sampleBuffer: CMSampleBuffer, from connection: AVCaptureConnection) {
recordingQueue.async {
autoreleasepool {
if output == self.previewVideoOutput {
let pixelBuffer = CMSampleBufferGetImageBuffer(sampleBuffer)
let cameraImage = CIImage(cvPixelBuffer: pixelBuffer!)
if self.currentFilter != nil { self.currentFilter.setValue(cameraImage, forKey: kCIInputImageKey) }
let filteredImage = UIImage(ciImage: self.currentFilter != nil ? self.currentFilter.value(forKey: kCIOutputImageKey) as! CIImage : cameraImage)
let timeStampie = CMSampleBufferGetPresentationTimeStamp(sampleBuffer)
self.previewProgressTimeStamp = timeStampie
if self.previewFirstFrameTimeStamp == CMTime.zero {
self.previewFirstFrameTimeStamp = self.previewProgressTimeStamp
}
self.previewProgressTimeStamp = CMTimeSubtract(self.previewProgressTimeStamp, self.previewFirstFrameTimeStamp)
if self.previewVideoWriterInput.isReadyForMoreMediaData {
let appendSuccess = self.previewVideoAdapter.append(self.pixelBufferFromImage(filteredImage)!, withPresentationTime: self.previewProgressTimeStamp)
}
}
else if output == self.previewAudioOutput {
if self.previewAudioWriterInput.isReadyForMoreMediaData {
let appendSuccess = self.previewAudioWriterInput.append(sampleBuffer)
}
}
}
}
}
这是我在完成录制时使用的代码:
if previewVideoWriterInput != nil {
previewVideoWriterInput.markAsFinished()
previewAudioWriterInput.markAsFinished()
}
if previewVideoWriter != nil {
previewVideoWriter.endSession(atSourceTime: previewProgressTimeStamp)
previewVideoWriter.finishWriting { () -> Void in
self.recordingCompletedHandler?()
}
}
任何想法为什么视频播放器看不到正在写入视频文件的音频?我将如何解决这个问题?
编辑:
这是我用来按要求设置 AVCapture 输出的代码。
captureSession = AVCaptureSession()
captureSession.beginConfiguration()
captureSession.sessionPreset = .vga640x480
captureSession.usesApplicationAudioSession = true
if frontCameraInput != nil && captureSession.canAddInput(frontCameraInput) == true { captureSession.addInput(frontCameraInput) }
if let audioCaptureDeviceInput = AVCaptureDevice.default(for: .audio) { audioCaptureDevice = audioCaptureDeviceInput }
if audioCaptureDevice != nil {
do {
audioCaptureDeviceInput = try AVCaptureDeviceInput(device: audioCaptureDevice)
} catch let error {
print("\(error.localizedDescription)")
}
}
if audioCaptureDeviceInput != nil && captureSession.canAddInput(audioCaptureDeviceInput) == true { captureSession.addInput(audioCaptureDeviceInput) }
previewVideoOutput.setSampleBufferDelegate(self, queue: recordingQueue)
previewAudioOutput.setSampleBufferDelegate(self, queue: recordingQueue)
if captureSession.canAddOutput(previewVideoOutput) { captureSession.addOutput(previewVideoOutput) }
if captureSession.canAddOutput(previewAudioOutput) { captureSession.addOutput(previewAudioOutput) }
captureSession.commitConfiguration()
解决方案
推荐阅读
- java - 比较列表时迭代非法状态异常
- apache-nifi - 在 nifi 自定义处理器中抛出传输关系未指定异常
- java - 通过电子邮件共享位图图像,无需 Uri
- html - 当输入类型设置为电子邮件时,带有 CSS 的浮动标签不起作用
- java - java代码可以在war文件部署上启动并在wildfly服务器的后台运行吗?
- android - 布局中的数据绑定 onTouch
- reactjs - 部署反应应用程序后,图像未显示在 gh 页面上
- c# - Outlook 加载项开发 - VSTO 与 Web,是否可以更改表单?
- php - 如何使用 php 隐藏浏览器位置权限弹出窗口?
- node.js - 废弃但正在运行的 Vue 项目中的 Sass 加载程序问题