Skip to content

Instantly share code, notes, and snippets.

@toddhopkinson
Last active January 28, 2019 22:13
Show Gist options
  • Save toddhopkinson/70ecd00fb2508613e7bc26b0ad3e8d05 to your computer and use it in GitHub Desktop.
Save toddhopkinson/70ecd00fb2508613e7bc26b0ad3e8d05 to your computer and use it in GitHub Desktop.
// NOTE: important to be aware that your reporting that your async is on is not on main thread
// see also https://developer.apple.com/library/content/samplecode/avexporter/Listings/Swift_AVFoundationExporter_main_swift.html
// An Interested party such as a UIViewController (the call site of embedWatermark, for example) can register as delegate
// and update progress indicators (like a UIProgressView or UILabel).
protocol VideoProcessingProgressDelegate {
func watermarkProgressUpdated(progress: Float)
}
class VideoProcessingProgressExample {
public func embedWatermark(progressDelegate: VideoProcessingProgressDelegate, success: @escaping (() -> Void)?) {
DispatchQueue.init(label: "watermarkDispatchQueue").async {
let mixComposition = AVMutableComposition()
//...
guard let exporter = AVAssetExportSession(asset: mixComposition, presetName: AVAssetExportPresetHighestQuality) else { return }
// configuration work preppring watermark embedding into video ...
// Kick off export asynchronous operation & use dispatch group to facilitate wait and progress reporting during processing
let group = DispatchGroup()
group.enter()
exporter.exportAsynchronously(completionHandler: {
group.leave()
})
self.reportProgressForAsyncExportSessionAndWait(exportSession: exporter, group: group, progressDelegate: watermarkProgressDelegate)
if exporter.status == AVAssetExportSessionStatus.completed {
let outputURL = exporter.outputURL
success?() // output params could be passed here
// success?(AVAssetExportSessionStatus.completed, exporter, outputURL!)
} else {
// Error
if let systemError = exporter.error {
print("Error: \(systemError)")
}
} // end if/else
} // end dispatch async
} // end embedWatermark
// facilitates progress updates
private class func reportProgressForAsyncExportSessionAndWait(exportSession: AVAssetExportSession, group: DispatchGroup, progressDelegate: VideoProcessingProgressDelegate?) {
while exportSession.status == .waiting || exportSession.status == .exporting {
progressDelegate?.watermarkProgressUpdated(progressFloat: exportSession.progress)
group.wait(timeout: DispatchTime(uptimeNanoseconds: 1000 * NSEC_PER_MSEC))
}
print("WATERMARK COMPLETED!")
}
}
// Call Site Example
// =====================================
// MEANWHILE & ELSEWHERE IN ANOTHER FILE
// =====================================
Class VideoEditViewController: UIViewController {
// ...
@IBOutlet weak var progressView: UIProgressView!
// call site
func addWatermarkToVideo() {
VideoProcessingProgressExample.embedWatermark(progressDelegate: self, success: {
// processing completed successfully
})
}
}
extention VideoEditViewController: VideoProcessingProgressDelegate {
func watermarkProgressUpdated(progress: Float) {
DispatchQueue.main.async {
self.progressView.setProgress(progress, animated: true)
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment