Skip to content

Instantly share code, notes, and snippets.

@christianselig
Last active March 21, 2020 00:44
Show Gist options
  • Save christianselig/ff7922bb6993202848de43e91fe1dac1 to your computer and use it in GitHub Desktop.
Save christianselig/ff7922bb6993202848de43e91fe1dac1 to your computer and use it in GitHub Desktop.
let startTime = CFAbsoluteTimeGetCurrent()
let totalFrames = 882
// `url` is a locally saved MP4
let asset = AVURLAsset(url: url)
let reader = try! AVAssetReader(asset: asset)
let videoTrack = asset.tracks(withMediaType: .video).first!
let outputSettings: [String: Any] = [
kCVPixelBufferPixelFormatTypeKey as String: kCVPixelFormatType_32ARGB
]
let readerOutput = AVAssetReaderTrackOutput(track: videoTrack, outputSettings: outputSettings)
reader.add(readerOutput)
reader.startReading()
var sample: CMSampleBuffer? = readerOutput.copyNextSampleBuffer()
let context = CIContext(options: nil)
let delayBetweenFrames: CGFloat = 0.03030303
let fileProperties: [String: Any] = [
kCGImagePropertyGIFDictionary as String: [
kCGImagePropertyGIFLoopCount as String: 0
]
]
let frameProperties: [String: Any] = [
kCGImagePropertyGIFDictionary as String: [
kCGImagePropertyGIFDelayTime: delayBetweenFrames
]
]
let resultingFilename = String(format: "%@_%@", ProcessInfo.processInfo.globallyUniqueString, "html5gif.gif")
let resultingFileURL = URL(fileURLWithPath: NSTemporaryDirectory()).appendingPathComponent(resultingFilename)
let destination = CGImageDestinationCreateWithURL(resultingFileURL as CFURL, kUTTypeGIF, totalFrames, nil)!
CGImageDestinationSetProperties(destination, fileProperties as CFDictionary)
let operationQueue = OperationQueue()
operationQueue.maxConcurrentOperationCount = 1
while (sample != nil) {
if let newSample = sample {
let pixelBuffer = CMSampleBufferGetImageBuffer(newSample)!
let ciImage = CIImage(cvImageBuffer: pixelBuffer).transformed(by: CGAffineTransform(scaleX: 0.6, y: 0.6))
let cgImage = context.createCGImage(ciImage, from: ciImage.extent)!
operationQueue.addOperation {
CGImageDestinationAddImage(destination, cgImage, frameProperties as CFDictionary)
}
}
sample = readerOutput.copyNextSampleBuffer()
}
operationQueue.waitUntilAllOperationsAreFinished()
let result = CGImageDestinationFinalize(destination)
print("Did it succeed?", result)
PHPhotoLibrary.shared().performChanges({
PHAssetCreationRequest.creationRequestForAssetFromImage(atFileURL: resultingFileURL)
}) { (saved, err) in
print("Saved?", saved)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment