Created
January 24, 2017 08:55
-
-
Save budidino/b5f412001cf6e6a62405e2c25fc951d1 to your computer and use it in GitHub Desktop.
compress and optionally mute video in Swift 2
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
func compressVideo(inputURL: NSURL, outputURL: NSURL, bitRate: Int, muteSound: Bool, onDone: () -> ()) { | |
let videoAsset = AVURLAsset(URL: inputURL, options: nil) | |
let videoTrack = videoAsset.tracksWithMediaType(AVMediaTypeVideo)[0] | |
let videoSize = videoTrack.naturalSize | |
let videoWriterCompressionSettings = [ | |
AVVideoAverageBitRateKey: bitRate | |
] | |
let videoWriterSettings:[String : AnyObject] = [ | |
AVVideoCodecKey : AVVideoCodecH264, | |
AVVideoCompressionPropertiesKey : videoWriterCompressionSettings, | |
AVVideoWidthKey : Int(videoSize.width), | |
AVVideoHeightKey : Int(videoSize.height) | |
] | |
let videoWriterInput = AVAssetWriterInput(mediaType: AVMediaTypeVideo, outputSettings: videoWriterSettings) | |
videoWriterInput.expectsMediaDataInRealTime = true | |
videoWriterInput.transform = videoTrack.preferredTransform | |
let videoWriter = try! AVAssetWriter(URL: outputURL, fileType: AVFileTypeQuickTimeMovie) | |
videoWriter.addInput(videoWriterInput) | |
let videoReaderSettings:[String : AnyObject] = [ | |
kCVPixelBufferPixelFormatTypeKey as String: Int(kCVPixelFormatType_420YpCbCr8BiPlanarVideoRange) | |
] | |
let videoReaderOutput = AVAssetReaderTrackOutput(track: videoTrack, outputSettings: videoReaderSettings) | |
let videoReader = try! AVAssetReader(asset: videoAsset) | |
videoReader.addOutput(videoReaderOutput) | |
let audioWriterInput = AVAssetWriterInput(mediaType: AVMediaTypeAudio, outputSettings: nil) | |
audioWriterInput.expectsMediaDataInRealTime = false | |
videoWriter.addInput(audioWriterInput) | |
let audioTrack = videoAsset.tracksWithMediaType(AVMediaTypeAudio)[0] | |
let audioReaderOutput = AVAssetReaderTrackOutput(track: audioTrack, outputSettings: nil) | |
let audioReader = try! AVAssetReader(asset: videoAsset) | |
if muteSound == false { | |
audioReader.addOutput(audioReaderOutput) | |
} | |
videoWriter.startWriting() | |
videoReader.startReading() | |
videoWriter.startSessionAtSourceTime(kCMTimeZero) | |
let processingQueue = dispatch_queue_create("processingQueue1", nil) | |
videoWriterInput.requestMediaDataWhenReadyOnQueue(processingQueue, usingBlock: {() -> Void in | |
while videoWriterInput.readyForMoreMediaData { | |
let sampleBuffer:CMSampleBuffer? = videoReaderOutput.copyNextSampleBuffer() | |
if videoReader.status == .Reading && sampleBuffer != nil { | |
videoWriterInput.appendSampleBuffer(sampleBuffer!) | |
} else { | |
videoWriterInput.markAsFinished() | |
if videoReader.status == .Completed { | |
if muteSound { | |
// return without sound | |
videoWriter.finishWritingWithCompletionHandler({() -> Void in | |
onDone() | |
}) | |
} else { | |
audioReader.startReading() | |
videoWriter.startSessionAtSourceTime(kCMTimeZero) | |
let processingQueue = dispatch_queue_create("processingQueue2", nil) | |
audioWriterInput.requestMediaDataWhenReadyOnQueue(processingQueue, usingBlock: {() -> Void in | |
while audioWriterInput.readyForMoreMediaData { | |
let sampleBuffer:CMSampleBufferRef? = audioReaderOutput.copyNextSampleBuffer() | |
if audioReader.status == .Reading && sampleBuffer != nil { | |
audioWriterInput.appendSampleBuffer(sampleBuffer!) | |
} else { | |
audioWriterInput.markAsFinished() | |
if audioReader.status == .Completed { | |
videoWriter.finishWritingWithCompletionHandler({() -> Void in | |
onDone() | |
}) | |
} | |
} | |
} | |
}) | |
} | |
} | |
} | |
} | |
}) | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment