加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

swift – 媒体类型的样本缓冲区必须与接收者的媒体类型(“soun”

发布时间:2020-12-14 04:53:58 所属栏目:百科 来源:网络整理
导读:基于这个答案 https://stackoverflow.com/a/16035330/1615183我在Swift中创建了以下用于压缩视频的代码: var videoWriter:AVAssetWriter!var videoWriterInput:AVAssetWriterInput!var processingQueue:dispatch_queue_t = dispatch_queue_create("processi
基于这个答案 https://stackoverflow.com/a/16035330/1615183我在Swift中创建了以下用于压缩视频的代码:

var videoWriter:AVAssetWriter!
var videoWriterInput:AVAssetWriterInput!
var processingQueue:dispatch_queue_t  = dispatch_queue_create("processingQueue1",nil)
var processingQueue2:dispatch_queue_t = dispatch_queue_create("processingQueue2",nil)
var audioWriterInput:AVAssetWriterInput!

func encode(){

    NSFileManager.defaultManager().removeItemAtURL(self.outputFile,error: nil)

    let videoCleanApertureSettings = [AVVideoCleanApertureHeightKey: 720,AVVideoCleanApertureWidthKey: 1280,AVVideoCleanApertureHorizontalOffsetKey: 2,AVVideoCleanApertureVerticalOffsetKey: 2
    ]
    let codecSettings  = [AVVideoAverageBitRateKey: 1024000,AVVideoCleanApertureKey: videoCleanApertureSettings
    ]

    let videoSettings = [AVVideoCodecKey: AVVideoCodecKey,AVVideoCompressionPropertiesKey: codecSettings,AVVideoHeightKey: 720,AVVideoWidthKey: 1280]


    //setup video writer
    var error:NSError?
    let asset = AVURLAsset(URL: self.inputFile,options: nil)

    let videoTrack:AVAssetTrack = asset.tracksWithMediaType(AVMediaTypeVideo)[0] as AVAssetTrack
    let videoSize:CGSize = videoTrack.naturalSize

    videoWriterInput = AVAssetWriterInput(mediaType: AVMediaTypeVideo,outputSettings: videoSettings)
    videoWriterInput.expectsMediaDataInRealTime = false
    videoWriterInput.transform = videoTrack.preferredTransform
    videoWriter = AVAssetWriter(URL: self.outputFile,fileType: AVFileTypeQuickTimeMovie,error: &error)

    if videoWriter.canAddInput(videoWriterInput) {
        videoWriter.addInput(videoWriterInput)
    }else{
        println("cant add video writer input")
        return
    }

    //setup video reader

    let videoReaderSettings = [ kCVPixelBufferPixelFormatTypeKey as String : kCVPixelFormatType_420YpCbCr8BiPlanarVideoRange]

    let videoReaderOutput:AVAssetReaderTrackOutput = AVAssetReaderTrackOutput(track: videoTrack,outputSettings: videoReaderSettings) // should it be videoReaderSettings?

    let videoReader:AVAssetReader = AVAssetReader(asset: asset,error: &error)
    if videoReader.canAddOutput(videoReaderOutput) {
        videoReader.addOutput(videoReaderOutput)
    }

    //setup audio writer
    audioWriterInput = AVAssetWriterInput(mediaType: AVMediaTypeAudio,outputSettings: nil)

    audioWriterInput.expectsMediaDataInRealTime = false
    if videoWriter.canAddInput(audioWriterInput){
        videoWriter.addInput(audioWriterInput)
    }

    //setup audio reader
    let audioTrack:AVAssetTrack = asset.tracksWithMediaType(AVMediaTypeVideo)[0] as AVAssetTrack
    let audioReaderOutput:AVAssetReaderOutput = AVAssetReaderTrackOutput(track: audioTrack,outputSettings: nil)
    let audioReader:AVAssetReader = AVAssetReader(asset: asset,error: &error)

    if audioReader.canAddOutput(audioReaderOutput) {
        audioReader.addOutput(audioReaderOutput)
    }else {
        println("cant add audio reader")
        return
    }


    videoWriter.startWriting()
    videoReader.startReading()

    videoWriter.startSessionAtSourceTime(kCMTimeZero)




    videoWriterInput.requestMediaDataWhenReadyOnQueue(processingQueue) {
        while self.videoWriterInput.readyForMoreMediaData {
            println("First loop")
            var sampleBuffer = videoReaderOutput.copyNextSampleBuffer()
            if videoReader.status == .Reading && sampleBuffer != nil {
                println("Appending")
                self.videoWriterInput.appendSampleBuffer(sampleBuffer)
            }else {
                self.videoWriterInput.markAsFinished()
                if videoReader.status == .Completed {

                    audioReader.startReading()
                    self.videoWriter.startSessionAtSourceTime(kCMTimeZero)

                    self.audioWriterInput.requestMediaDataWhenReadyOnQueue(self.processingQueue2) {
                        while self.audioWriterInput.readyForMoreMediaData {
                            println("Second loop")
                            var sampleBuffer2:CMSampleBufferRef? = audioReaderOutput.copyNextSampleBuffer()
                            if audioReader.status == .Reading && sampleBuffer2 != nil {
                                self.audioWriterInput.appendSampleBuffer(sampleBuffer2)
                            }else {
                                self.audioWriterInput.markAsFinished()
                                println("Audio finish")
                                self.videoWriter.finishWritingWithCompletionHandler { println("Done") }
                            }
                        }

                    }


                }
                else {
                    println("Video Reader not completed")
                }
                println("Finished")
                break
            }// else vidoSampleBuffer
        }
    }

 }

但是,如果我删除音频部分,我只得到一个空文件.如果我在第二次循环运行时第一次按原样运行它没有问题,但在第二次迭代时它崩溃并出现以下错误:

*** Terminating app due to uncaught exception 'NSInvalidArgumentException',reason: '*** -[AVAssetWriterInput appendSampleBuffer:] Media type of sample buffer must match receiver's media type ("soun")'

有没有人有同样的问题?

解决方法

将AVMediaTypeVideo更改为音频:

let audioTrack:AVAssetTrack = asset.tracksWithMediaType(AVMediaTypeVideo)[0] as AVAssetTrack

应该

let audioTrack:AVAssetTrack = asset.tracksWithMediaType(AVMediaTypeAudio)[0] as AVAssetTrack

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读