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 (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |