如何在iOS Swift中为CMSampleBufferGetFormatDescription创建anAudioSampleBuffer

问题描述 投票:2回答:1

我一直在iOS Swift中进行视频压缩,并遵循this SO的回答。在我将这段代码的文件格式更改为。mp4

之前,它工作正常。
    let videoWriter = try! AVAssetWriter(outputURL: outputURL as URL, fileType: AVFileType.mov)

出于某些原因,我需要使用[[.mp4文件格式的输出。因此,当我这样做时,它会使应用程序崩溃。并给我这个错误,

2020-04-27 18:20:52.573614+0500 BrightCaster[7847:1513728] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '*** -[AVAssetWriter addInput:] In order to perform passthrough to file type public.mpeg-4, please provide a format hint in the AVAssetWriterInput initializer' *** First throw call stack: (0x1b331d5f0 0x1b303fbcc 0x1bd53b2b0 0x102383c0c 0x102382164 0x1021897cc 0x1b6ca73bc 0x1b6caba7c 0x1b6daec94 0x1b7835080 0x1b7834d30 0x1e9d077b4 0x1b786a764 0x1b783eb68 0x1b783f070 0x1e9d468f4 0x1b783f1c0 0x1e9d468f4 0x1b9e21d9c 0x105173730 0x105181710 0x1b329b748 0x1b329661c 0x1b3295c34 0x1bd3df38c 0x1b73c822c 0x10230f8a0 0x1b311d800) libc++abi.dylib: terminating with uncaught exception of type NSException
所以我搜索了SO,发现与我的问题相关的this问题。但是现在的问题是,当我尝试将其answer添加到函数中时,它给了我错误[[anAudioSampleBuffer not defined。由于我是音频/视频领域的新手,所以我无法理解为什么它给了我这个。以及如何解决这个问题。我在我的函数中添加的答案中的代码如下。

//setup audio writer //let formatDesc = CMSampleBufferGetFormatDescription(anAudioSampleBuffer) //let audioWriterInput = AVAssetWriterInput(mediaType: AVMediaType.audio, outputSettings: nil, sourceFormatHint: formatDesc) let audioWriterInput = AVAssetWriterInput(mediaType: AVMediaType.audio, outputSettings: nil) audioWriterInput.expectsMediaDataInRealTime = false videoWriter.add(audioWriterInput)

评论的部分不起作用。任何帮助,将不胜感激谢谢。
以下是用于转换的整个功能

func convertVideoToLowQuailtyWithInputURL(inputURL: URL, outputURL: URL, completion: @escaping (Bool , _ url: String) -> Void) { let videoAsset = AVURLAsset(url: inputURL as URL, options: nil) let videoTrack = videoAsset.tracks(withMediaType: AVMediaType.video)[0] let videoSize = videoTrack.naturalSize let videoWriterCompressionSettings = [ AVVideoAverageBitRateKey : Int(125000) ] let videoWriterSettings:[String : AnyObject] = [ AVVideoCodecKey : AVVideoCodecH264 as AnyObject, AVVideoCompressionPropertiesKey : videoWriterCompressionSettings as AnyObject, AVVideoWidthKey : Int(videoSize.width) as AnyObject, AVVideoHeightKey : Int(videoSize.height) as AnyObject ] let videoWriterInput = AVAssetWriterInput(mediaType: AVMediaType.video, outputSettings: videoWriterSettings) videoWriterInput.expectsMediaDataInRealTime = true videoWriterInput.transform = videoTrack.preferredTransform let videoWriter = try! AVAssetWriter(outputURL: outputURL as URL, fileType: AVFileType.mov) // for now its converting in .mov I THINK SO. videoWriter.add(videoWriterInput) //setup video reader let videoReaderSettings:[String : AnyObject] = [ kCVPixelBufferPixelFormatTypeKey as String: Int(kCVPixelFormatType_420YpCbCr8BiPlanarVideoRange) as AnyObject ] let videoReaderOutput = AVAssetReaderTrackOutput(track: videoTrack, outputSettings: videoReaderSettings) var videoReader: AVAssetReader! do{ videoReader = try AVAssetReader(asset: videoAsset) } catch { print("video reader error: \(error)") completion(false, "") } videoReader.add(videoReaderOutput) //setup audio writer //let formatDesc = CMSampleBufferGetFormatDescription(anAudioSampleBuffer) // this is giving me error here of un initilize, which I didn't I know. //let audioWriterInput = AVAssetWriterInput(mediaType: AVMediaType.audio, outputSettings: nil, sourceFormatHint: formatDesc) let audioWriterInput = AVAssetWriterInput(mediaType: AVMediaType.audio, outputSettings: nil) audioWriterInput.expectsMediaDataInRealTime = false videoWriter.add(audioWriterInput) //setup audio reader let audioTrack = videoAsset.tracks(withMediaType: AVMediaType.audio)[0] let audioReaderOutput = AVAssetReaderTrackOutput(track: audioTrack, outputSettings: nil) let audioReader = try! AVAssetReader(asset: videoAsset) audioReader.add(audioReaderOutput) videoWriter.startWriting() //start writing from video reader videoReader.startReading() videoWriter.startSession(atSourceTime: CMTime.zero) let processingQueue = DispatchQueue(label: "processingQueue1") videoWriterInput.requestMediaDataWhenReady(on: processingQueue, using: {() -> Void in while videoWriterInput.isReadyForMoreMediaData { let sampleBuffer:CMSampleBuffer? = videoReaderOutput.copyNextSampleBuffer(); if videoReader.status == .reading && sampleBuffer != nil { videoWriterInput.append(sampleBuffer!) } else { videoWriterInput.markAsFinished() if videoReader.status == .completed { //start writing from audio reader audioReader.startReading() videoWriter.startSession(atSourceTime: CMTime.zero) let processingQueue = DispatchQueue(label: "processingQueue2") audioWriterInput.requestMediaDataWhenReady(on: processingQueue, using: {() -> Void in while audioWriterInput.isReadyForMoreMediaData { let sampleBuffer:CMSampleBuffer? = audioReaderOutput.copyNextSampleBuffer() if audioReader.status == .reading && sampleBuffer != nil { audioWriterInput.append(sampleBuffer!) } else { audioWriterInput.markAsFinished() if audioReader.status == .completed { videoWriter.finishWriting(completionHandler: {() -> Void in completion(true, "\(videoWriter.outputURL)") }) } } } }) } } } }) }

ios swift avfoundation avassetwriter video-compression
1个回答
0
投票
let audioTrack = videoAsset.tracks(withMediaType: AVMediaType.audio)[0] let audioWriterInput = AVAssetWriterInput(mediaType: AVMediaType.audio, outputSettings: nil, sourceFormatHint: audioTrack.formatDescriptions[0] as! CMFormatDescription)

注意audioTrack定义的新位置

© www.soinside.com 2019 - 2024. All rights reserved.