5

I'm finding it impossible to write a stream of frames (from a webcam) to storage, and then at a later time, read the frame back out. If I write them using an AssetWriter in AVVideoCodecH264, then I can't read them with an AssetReader because I get the following error:

AVAssetReaderOutput does not currently support compressed output

If I try to write uncompressed (remove the AVVIdeoCodecH264 from the outputsettings) then I get the opposite error.

AVAssetWriter does not currently support uncompressed output (paraphrased)

So I can only write in a compressed format and I can only read from an uncompressed format, even though the write/read function belong to the same API!!!

Any ideas?

Below is the code for writing:

    outputSettings = [AVVideoCodecKey : AVVideoCodecH264,
                          AVVideoWidthKey : NSNumber(value: Float(640)), 
                          AVVideoHeightKey : NSNumber(value: Float(480))] 
                      as [String : Any]

    assetWriterInput = AVAssetWriterInput(mediaType: AVMediaTypeVideo,
                                          outputSettings: outputSettings)
    pixelBufferAdaptor = AVAssetWriterInputPixelBufferAdaptor(
             assetWriterInput: assetWriterInput!, 
             sourcePixelBufferAttributes:  [ kCVPixelBufferPixelFormatTypeKey 
             as String : Int(kCVPixelFormatType_420YpCbCr8PlanarFullRange)])


    let paths = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)
    let fileUrl = paths[0].appendingPathComponent("output.mov")
    try? FileManager.default.removeItem(at: fileUrl)

    assetWriter =  try? AVAssetWriter(url: fileUrl, fileType: AVFileTypeMPEG4)
    assetWriter?.add(assetWriterInput!)
    assetWriterInput!.expectsMediaDataInRealTime = true
    assetWriter?.startWriting()
    saving = true;
    assetWriter?.startSession(atSourceTime: kCMTimeZero)

and the code for reading...

    let asset = AVAsset(url: fileUrl)
    self.assetReader = try? AVAssetReader(asset: asset);

    guard let videoTrack = asset.tracks(withMediaType: AVMediaTypeVideo).first 
    else { return }
    self.assetReaderOutput = AVAssetReaderTrackOutput(
              track: videoTrack, 
              outputSettings:[String(kCVPixelBufferPixelFormatTypeKey): 
                            NSNumber(value: kCVPixelFormatType_420YpCbCr8PlanarFullRange)])

    self.assetReader!.add(self.assetReaderOutput!)
    self.assetReader!.startReading()
Harry Mexican
  • 1,514
  • 1
  • 21
  • 51
  • 1
    Hope this points you in the right direction; Google "outputSettings:decompressionVideoSettings" and take a look at Will's blog: http://gewill.org/2016/05/03/AVFoundation-Programming-Guide-Export/ and review AVVideoComposition – Sorceri Dec 26 '17 at 20:28
  • @sorceri that’s a great resource. Better than anything I’ve been able to find so far. Thank you for sharing it. I’m hopeful I can resolve my issue. If I do I will come back here and ask you to post an answer so I can give you the bounty. Thank you. – Harry Mexican Dec 27 '17 at 00:30

0 Answers0