压缩视频文件大小

时间:2018-10-14 19:40:52

标签: ios swift avassetwriter avassetreader

我想压缩视频文件并发送到服务器,我尝试使用1080p HD的iPhone 7Plus设备以60 fps的速度录制视频1分钟,此视频大小为122.1 MB,压缩后的视频压缩大小为32 MG,现在我尝试更改比特率大小,视频大小但压缩大小不变。如何压缩更多视频大小。

func compress(fileName:String,videoPath : String, exportVideoPath : String, renderSize : CGSize, completion : @escaping (Bool) -> ()) {

    let videoUrl = URL(fileURLWithPath: videoPath)
    let videoAssetUrl = AVURLAsset(url: videoUrl)
    let videoTrackArray = videoAssetUrl.tracks(withMediaType: AVMediaTypeVideo)

    if videoTrackArray.count < 1 {
      completion(false)
      return
    }
    let videoAssetTrack = videoTrackArray[0]
    let audioTrackArray = videoAssetUrl.tracks(withMediaType: AVMediaTypeAudio)

    if audioTrackArray.count < 1 {
      completion(false)
      return
    }
    let audioAssetTrack = audioTrackArray[0]
    let outputUrl = URL(fileURLWithPath: exportVideoPath)
    var videoWriter = try? AVAssetWriter(url: outputUrl, fileType: AVFileTypeQuickTimeMovie)
    videoWriter?.shouldOptimizeForNetworkUse = true

    let vSetting = videoSettings(size: renderSize)
    let videoWriterInput = AVAssetWriterInput(mediaType: AVMediaTypeVideo, outputSettings: vSetting)
    videoWriterInput.expectsMediaDataInRealTime = false
    videoWriterInput.transform = videoAssetTrack.preferredTransform
    videoWriter?.add(videoWriterInput)

    let aSettings = audioSettings()
    let audioWriterInput = AVAssetWriterInput(mediaType: AVMediaTypeAudio, outputSettings: aSettings)
    audioWriterInput.expectsMediaDataInRealTime = false
    audioWriterInput.transform = audioAssetTrack.preferredTransform
    videoWriter?.add(audioWriterInput)

    let videoReaderSettings : [String : Int] = [kCVPixelBufferPixelFormatTypeKey as String : Int(kCVPixelFormatType_420YpCbCr8BiPlanarVideoRange)]
    let videoReaderOutput = AVAssetReaderTrackOutput(track: videoAssetTrack, outputSettings: videoReaderSettings)
    let videoReader = try! AVAssetReader(asset: videoAssetUrl)
    videoReader.add(videoReaderOutput)
    var settings = [String : AnyObject]()
    settings[AVFormatIDKey] = Int(kAudioUnitRange) as AnyObject
    let audioReaderOutput = AVAssetReaderTrackOutput(track: videoAssetTrack, outputSettings: nil)
    let audioReader = try! AVAssetReader(asset: videoAssetUrl)
    audioReader.add(audioReaderOutput)

    videoWriter?.startWriting()
    videoReader.startReading()
    videoWriter?.startSession(atSourceTime: kCMTimeZero)

    let processingVideoQueue = DispatchQueue(label: "processingVideoCompressionQueue")
    videoWriterInput.requestMediaDataWhenReady(on: processingVideoQueue, using: {
      while(videoWriterInput.isReadyForMoreMediaData){
        let sampleVideoBuffer = videoReaderOutput.copyNextSampleBuffer()
        if (videoReader.status == .reading && sampleVideoBuffer != nil) {
          videoWriterInput.append(sampleVideoBuffer!)
        }else {
          videoWriterInput.markAsFinished()
          if (videoReader.status == .completed) {

                    videoWriter?.finishWriting(completionHandler: {
                      videoWriter = nil
                      self.export = true
                      completion(true)

                    })

          }
        }
        if self.export {
          break
        }
      }
    })
  }

  func videoSettings(size : CGSize) -> [String : AnyObject] {

    var compressionSettings = [String : AnyObject]()
    compressionSettings[AVVideoAverageBitRateKey] = 425000 as AnyObject

    var settings = [String : AnyObject]()
    settings[AVVideoCompressionPropertiesKey] = compressionSettings as AnyObject
    if #available(iOS 11.0, *) {
      settings[AVVideoCodecKey] = AVVideoCodecHEVC as AnyObject?
    } else {
      settings[AVVideoCodecKey] = AVVideoCodecH264 as AnyObject?
    }
    settings[AVVideoHeightKey] = size.height as AnyObject?
    settings[AVVideoWidthKey] = size.width as AnyObject?

    return settings
  }

0 个答案:

没有答案