1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465 |
- import Foundation
- import AVKit
- extension URL {
- enum ConversionError: Error {
- case runtimeError(String)
- }
- public var queryParameters: [String: String]? {
- guard
- let components = URLComponents(url: self, resolvingAgainstBaseURL: true),
- let queryItems = components.queryItems else { return nil }
- return queryItems.reduce(into: [String: String]()) { result, item in
- result[item.name] = item.value
- }
- }
- public func convertToMp4(completionHandler: ((URL?, Error?) -> Void)?) {
- let avAsset = AVURLAsset(url: self, options: nil)
- AVAssetExportSession.determineCompatibility(ofExportPreset: AVAssetExportPresetPassthrough,
- with: avAsset,
- outputFileType: .mp4,
- completionHandler: { (isCompatible) in
- if !isCompatible {
- completionHandler?(nil, ConversionError.runtimeError("File has incompatible file format for mp4 conversion"))
- return
- }
- guard let exportSession = AVAssetExportSession(asset: avAsset, presetName: AVAssetExportPresetPassthrough) else {
- completionHandler?(nil, ConversionError.runtimeError("Could not initiate AVAssertExportSession"))
- return
- }
- let filename = self.deletingPathExtension().lastPathComponent.replacingOccurrences(of: ".", with: "-").appending(".mp4")
- let outputURL = FileManager.default.temporaryDirectory.appendingPathComponent(filename)
- if FileManager.default.fileExists(atPath: outputURL.path) {
- do {
- try FileManager.default.removeItem(at: outputURL)
- } catch {
- completionHandler?(nil, error)
- }
- }
- exportSession.outputURL = outputURL
- exportSession.outputFileType = AVFileType.mp4
- exportSession.shouldOptimizeForNetworkUse = true
- let start = CMTimeMakeWithSeconds(0.0, preferredTimescale: 0)
- let range = CMTimeRangeMake(start: start, duration: avAsset.duration)
- exportSession.timeRange = range
- exportSession.exportAsynchronously(completionHandler: {() -> Void in
- switch exportSession.status {
- case .failed:
- completionHandler?(nil, exportSession.error)
- case .cancelled:
- completionHandler?(nil, nil)
- case .completed:
- completionHandler?(exportSession.outputURL, nil)
- default: break
- }
- })
- })
- }
- }
|