Swift AVAssetWriter-如果呼叫次数过多,则不会';行不通
我想压缩一下我的视频。为此,我编写了一个@escaping函数。我从要压缩的数据中传入URL,然后从压缩文件中检索新的URL。问题是:当4项->1项损坏时,3项工作正常,当更多项损坏时:许多项损坏。输入的URL是正确的,并且有数据,那么我在这里做错了什么Swift AVAssetWriter-如果呼叫次数过多,则不会';行不通,swift,avassetwriter,avasset,Swift,Avassetwriter,Avasset,我想压缩一下我的视频。为此,我编写了一个@escaping函数。我从要压缩的数据中传入URL,然后从压缩文件中检索新的URL。问题是:当4项->1项损坏时,3项工作正常,当更多项损坏时:许多项损坏。输入的URL是正确的,并且有数据,那么我在这里做错了什么 class Compress() { ...code below } 我的压缩功能 var bitrate: NSNumber = 50000 func compressFile(url
class Compress() {
...code below
}
我的压缩功能
var bitrate: NSNumber = 50000
func compressFile(urlToCompress: URL, outputURL: URL, completion:@escaping (URL)->Void) {
var assetWriter:AVAssetWriter?
var assetReader:AVAssetReader?
var audioFinished = false
var videoFinished = false
let asset = AVAsset(url: urlToCompress);
do {
assetReader = try AVAssetReader(asset: asset)
} catch {
assetReader = nil
}
guard let reader = assetReader else {
fatalError("Could not initalize asset reader probably failed its try catch")
}
let videoTrack = asset.tracks(withMediaType: AVMediaType.video).first!
let audioTrack = asset.tracks(withMediaType: AVMediaType.audio).first!
let videoReaderSettings: [String:Any] = [kCVPixelBufferPixelFormatTypeKey as String:kCVPixelFormatType_32ARGB ]
// ADJUST BIT RATE OF VIDEO HERE
let videoSettings:[String:Any] = [
AVVideoCompressionPropertiesKey: [AVVideoAverageBitRateKey:self.bitrate],
AVVideoCodecKey: AVVideoCodecType.h264,
AVVideoHeightKey: videoTrack.naturalSize.height,
AVVideoWidthKey: videoTrack.naturalSize.width
]
let assetReaderVideoOutput = AVAssetReaderTrackOutput(track: videoTrack, outputSettings: videoReaderSettings)
let assetReaderAudioOutput = AVAssetReaderTrackOutput(track: audioTrack, outputSettings: nil)
if reader.canAdd(assetReaderVideoOutput){
reader.add(assetReaderVideoOutput)
}else{
fatalError("Couldn't add video output reader")
}
if reader.canAdd(assetReaderAudioOutput){
reader.add(assetReaderAudioOutput)
}else{
fatalError("Couldn't add audio output reader")
}
let audioInput = AVAssetWriterInput(mediaType: AVMediaType.audio, outputSettings: nil)
let videoInput = AVAssetWriterInput(mediaType: AVMediaType.video, outputSettings: videoSettings)
videoInput.transform = videoTrack.preferredTransform
let videoInputQueue = DispatchQueue(label: "videoQueue")
let audioInputQueue = DispatchQueue(label: "audioQueue")
do {
assetWriter = try AVAssetWriter(outputURL: outputURL, fileType: AVFileType.mov)
} catch {
assetWriter = nil
}
guard let writer = assetWriter else {
fatalError("assetWriter was nil")
}
writer.shouldOptimizeForNetworkUse = true
writer.add(videoInput)
writer.add(audioInput)
writer.startWriting()
reader.startReading()
writer.startSession(atSourceTime: CMTime.zero)
let closeWriter:()->Void = {
if (audioFinished && videoFinished){
assetWriter?.finishWriting(completionHandler: {
completion((assetWriter?.outputURL)!)
})
assetReader?.cancelReading()
}
}
audioInput.requestMediaDataWhenReady(on: audioInputQueue) {
while(audioInput.isReadyForMoreMediaData){
let sample = assetReaderAudioOutput.copyNextSampleBuffer()
if (sample != nil){
audioInput.append(sample!)
}else{
audioInput.markAsFinished()
DispatchQueue.main.async {
audioFinished = true
closeWriter()
}
break;
}
}
}
videoInput.requestMediaDataWhenReady(on: videoInputQueue) {
//request data here
while(videoInput.isReadyForMoreMediaData){
let sample = assetReaderVideoOutput.copyNextSampleBuffer()
if (sample != nil){
videoInput.append(sample!)
}else{
videoInput.markAsFinished()
DispatchQueue.main.async {
videoFinished = true
closeWriter()
}
break;
}
}
}
}
我如何调用函数
let group = DispatchGroup()
for video in videos {
group.enter()
let formatter = DateFormatter()
formatter.dateFormat = "yyyy'-'MM'-'dd'T'HH':'mm':'ss'Z'"
let date = Date()
let documentsPath = NSTemporaryDirectory()
let outputPath = "\(documentsPath)/\(formatter.string(from: date))\(video.id).mp4"
let newOutputUrl = URL(fileURLWithPath: outputPath)
var videoData = Data()
self.compressFile(urlToCompress: video.assetURL, outputURL: newOutputUrl) { (URL) in
videoData = try! NSData(contentsOf: newOutputUrl, options: .mappedIfSafe) as Data
finishedVideoArray.append(videoData as Data)
group.leave()
}
}