Какао - видеофайл, созданный с использованием AVAssetWriter & AVAssetReader, не содержит данных - PullRequest
0 голосов
/ 26 марта 2020

Я пытаюсь сжать видео, изменив битрейт видео. Я использую AVAssetReader & AVAssetWriter, чтобы прочитать примеры буферов из выходного файла и добавить их с настройками сжатия в новый файл. Файл создается, но не содержит никаких данных. Ниже мой код:

import Cocoa
import AVFoundation

class ViewController: NSViewController {

    @IBOutlet weak var openButton: NSButton!

    var assetReader: AVAssetReader?
    var assetWriter:AVAssetWriter?

    override func viewDidLoad() {
        super.viewDidLoad()

        // Do any additional setup after loading the view.
    }

    @IBAction func openAction(_ sender: Any) {
        self.openPanel { (inputURL) in
            if let inputURL = inputURL {
                let outputURL = self.outputFileURL(at: inputURL)
                self.compressVideo(at: inputURL, outputURL: outputURL)
            }
        }
    }

    private func openPanel(completionHandler: @escaping (_ url: URL?) -> ()) {
        let openPanel = NSOpenPanel.init()
        openPanel.canChooseFiles = true
        openPanel.canChooseDirectories = false
        openPanel.allowsMultipleSelection = false

        openPanel.begin { (panelResponse) in
            if panelResponse == .OK {
                completionHandler(openPanel.url)
            }
        }
    }

    private func outputFileURL(at inputURL: URL) -> URL {
        var outputURL = inputURL.deletingPathExtension()
        outputURL.deleteLastPathComponent()
        outputURL.appendPathComponent("compressed")
        outputURL.appendPathExtension("mov")
        return outputURL
    }


    private func compressVideo(at inputURL: URL, outputURL: URL) {

        let videoAsset = AVAsset.init(url: inputURL)


        do {
            assetReader = try AVAssetReader.init(asset: videoAsset)
        } catch let error {
            print(error.localizedDescription)
        }

        guard let reader = assetReader else {
            return print("assetReader is nil")
        }


        guard let videoTrack = videoAsset.tracks(withMediaType: .video).first else {
            return print("videoTrack is nil")
        }

        let videoOutputSettings = [kCVPixelBufferPixelFormatTypeKey as String :kCVPixelFormatType_32ARGB ]

        let readerOutput = AVAssetReaderTrackOutput.init(track: videoTrack, outputSettings: videoOutputSettings)

        if reader.canAdd(readerOutput) {
            reader.add(readerOutput)
        }

        let videoSettings:[String:Any] = [
            AVVideoCompressionPropertiesKey: [AVVideoAverageBitRateKey:NSNumber(value:250000)],
            AVVideoCodecKey: AVVideoCodecType.h264,
            AVVideoHeightKey: videoTrack.naturalSize.height,
            AVVideoWidthKey: videoTrack.naturalSize.width
        ]

        let videoInput = AVAssetWriterInput(mediaType: .video, outputSettings: videoSettings)
        videoInput.transform = videoTrack.preferredTransform

        do {
            assetWriter = try AVAssetWriter(outputURL: outputURL, fileType: AVFileType.mov)
        } catch {
            assetWriter = nil
        }

        guard let writer = assetWriter else{
            return print("assetWriter was nil")
        }

        writer.add(videoInput)

        writer.startWriting()
        reader.startReading()
        writer.startSession(atSourceTime: CMTime.zero)

        while videoInput.isReadyForMoreMediaData {
            let sampleBuffer = readerOutput.copyNextSampleBuffer()
            if sampleBuffer == nil {
                videoInput.markAsFinished()
                reader.cancelReading()
                DispatchQueue.main.async {
                    writer.finishWriting {
                        print("writing finished")
                    }
                }
                break
            } else {

                videoInput.append(sampleBuffer!)
            }
        }
    }
}

Я что-то здесь не так делаю? Я также прилагаю видео файл, который я пытаюсь сжать для вашей справки. Буду признателен за любую оказанную помощь.

ссылка для видео:

https://vimeo.com/400925916

...