Я пытаюсь сжать видео, изменив битрейт видео. Я использую 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