微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

视频文件有音频,但视频播放器看不到或播放音频

如何解决视频文件有音频,但视频播放器看不到或播放音频

我使用 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()

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。