Advertisement
samkirkiles

Swift 3.0 AVAssetWriter Video Compression

Jun 8th, 2017
6,606
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Swift 4.85 KB | None | 0 0
  1.     func compressFile(urlToCompress: URL, outputURL: URL, completion:@escaping (URL)->Void){
  2.         //video file to make the asset
  3.        
  4.         var audioFinished = false
  5.         var videoFinished = false
  6.        
  7.        
  8.        
  9.         let asset = AVAsset(url: urlToCompress);
  10.        
  11.         //create asset reader
  12.         do{
  13.             assetReader = try AVAssetReader(asset: asset)
  14.         } catch{
  15.             assetReader = nil
  16.         }
  17.        
  18.         guard let reader = assetReader else{
  19.             fatalError("Could not initalize asset reader probably failed its try catch")
  20.         }
  21.        
  22.         let videoTrack = asset.tracks(withMediaType: AVMediaTypeVideo).first!
  23.         let audioTrack = asset.tracks(withMediaType: AVMediaTypeAudio).first!
  24.  
  25.         let videoReaderSettings: [String:Any] =  [kCVPixelBufferPixelFormatTypeKey as String!:kCVPixelFormatType_32ARGB ]
  26.        
  27.         // ADJUST BIT RATE OF VIDEO HERE
  28.        
  29.         let videoSettings:[String:Any] = [
  30.             AVVideoCompressionPropertiesKey: [AVVideoAverageBitRateKey:self.bitrate],
  31.             AVVideoCodecKey: AVVideoCodecH264,
  32.             AVVideoHeightKey: videoTrack.naturalSize.height,
  33.             AVVideoWidthKey: videoTrack.naturalSize.width
  34.         ]
  35.  
  36.        
  37.         let assetReaderVideoOutput = AVAssetReaderTrackOutput(track: videoTrack, outputSettings: videoReaderSettings)
  38.         let assetReaderAudioOutput = AVAssetReaderTrackOutput(track: audioTrack, outputSettings: nil)
  39.        
  40.        
  41.         if reader.canAdd(assetReaderVideoOutput){
  42.             reader.add(assetReaderVideoOutput)
  43.         }else{
  44.             fatalError("Couldn't add video output reader")
  45.         }
  46.        
  47.         if reader.canAdd(assetReaderAudioOutput){
  48.             reader.add(assetReaderAudioOutput)
  49.         }else{
  50.             fatalError("Couldn't add audio output reader")
  51.         }
  52.        
  53.         let audioInput = AVAssetWriterInput(mediaType: AVMediaTypeAudio, outputSettings: nil)
  54.         let videoInput = AVAssetWriterInput(mediaType: AVMediaTypeVideo, outputSettings: videoSettings)
  55.         videoInput.transform = videoTrack.preferredTransform
  56.         //we need to add samples to the video input
  57.        
  58.         let videoInputQueue = DispatchQueue(label: "videoQueue")
  59.         let audioInputQueue = DispatchQueue(label: "audioQueue")
  60.        
  61.         do{
  62.             assetWriter = try AVAssetWriter(outputURL: outputURL, fileType: AVFileTypeQuickTimeMovie)
  63.         }catch{
  64.             assetWriter = nil
  65.         }
  66.         guard let writer = assetWriter else{
  67.             fatalError("assetWriter was nil")
  68.         }
  69.        
  70.         writer.shouldOptimizeForNetworkUse = true
  71.         writer.add(videoInput)
  72.         writer.add(audioInput)
  73.        
  74.        
  75.         writer.startWriting()
  76.         reader.startReading()
  77.         writer.startSession(atSourceTime: kCMTimeZero)
  78.        
  79.        
  80.         let closeWriter:()->Void = {
  81.             if (audioFinished && videoFinished){
  82.                 self.assetWriter?.finishWriting(completionHandler: {
  83.                    
  84.                     self.checkFileSize(sizeUrl: (self.assetWriter?.outputURL)!, message: "The file size of the compressed file is: ")
  85.                    
  86.                     completion((self.assetWriter?.outputURL)!)
  87.                    
  88.                 })
  89.                
  90.                 self.assetReader?.cancelReading()
  91.  
  92.             }
  93.         }
  94.  
  95.        
  96.         audioInput.requestMediaDataWhenReady(on: audioInputQueue) {
  97.             while(audioInput.isReadyForMoreMediaData){
  98.                 let sample = assetReaderAudioOutput.copyNextSampleBuffer()
  99.                 if (sample != nil){
  100.                     audioInput.append(sample!)
  101.                 }else{
  102.                     audioInput.markAsFinished()
  103.                     DispatchQueue.main.async {
  104.                         audioFinished = true
  105.                         closeWriter()
  106.                     }
  107.                     break;
  108.                 }
  109.             }
  110.         }
  111.        
  112.         videoInput.requestMediaDataWhenReady(on: videoInputQueue) {
  113.             //request data here
  114.            
  115.             while(videoInput.isReadyForMoreMediaData){
  116.                 let sample = assetReaderVideoOutput.copyNextSampleBuffer()
  117.                 if (sample != nil){
  118.                     videoInput.append(sample!)
  119.                 }else{
  120.                     videoInput.markAsFinished()
  121.                     DispatchQueue.main.async {
  122.                         videoFinished = true
  123.                         closeWriter()
  124.                     }
  125.                     break;
  126.                 }
  127.             }
  128.  
  129.         }
  130.        
  131.        
  132.     }
  133.    
  134.     func checkFileSize(sizeUrl: URL, message:String){
  135.         let data = NSData(contentsOf: sizeUrl)!
  136.         print(message, (Double(data.length) / 1048576.0), " mb")
  137.     }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement