Guest User

Untitled

a guest
Dec 13th, 2018
92
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 3.37 KB | None | 0 0
  1. Swift 4 version:
  2.  
  3. import AVFoundation
  4. import Foundation
  5. import UIKit
  6.  
  7. class VideoTrimmer {
  8. typealias TrimCompletion = (Error?) -> ()
  9. typealias TrimPoints = [(CMTime, CMTime)]
  10.  
  11. func verifyPresetForAsset(preset: String, asset: AVAsset) -> Bool {
  12. let compatiblePresets = AVAssetExportSession.exportPresets(compatibleWith: asset)
  13. let filteredPresets = compatiblePresets.filter { $0 == preset }
  14. return filteredPresets.count > 0 || preset == AVAssetExportPresetPassthrough
  15. }
  16.  
  17. func removeFileAtURLIfExists(url: URL) {
  18.  
  19. let fileManager = FileManager.default
  20.  
  21. guard fileManager.fileExists(atPath: url.path) else { return }
  22.  
  23. do {
  24. try fileManager.removeItem(at: url)
  25. }
  26. catch let error {
  27. print("TrimVideo - Couldn't remove existing destination file: \(String(describing: error))")
  28. }
  29. }
  30.  
  31. func trimVideo(sourceURL: URL, destinationURL: URL, trimPoints: TrimPoints, completion: TrimCompletion?) {
  32.  
  33. guard sourceURL.isFileURL else { return }
  34. guard destinationURL.isFileURL else { return }
  35.  
  36. let options = [
  37. AVURLAssetPreferPreciseDurationAndTimingKey: true
  38. ]
  39.  
  40. let asset = AVURLAsset(url: sourceURL, options: options)
  41. let preferredPreset = AVAssetExportPresetPassthrough
  42.  
  43. if verifyPresetForAsset(preset: preferredPreset, asset: asset) {
  44.  
  45. let composition = AVMutableComposition()
  46. let videoCompTrack = composition.addMutableTrack(withMediaType: .video, preferredTrackID: CMPersistentTrackID())
  47. let audioCompTrack = composition.addMutableTrack(withMediaType: .audio, preferredTrackID: CMPersistentTrackID())
  48.  
  49. guard let assetVideoTrack: AVAssetTrack = asset.tracks(withMediaType: .video).first else { return }
  50. guard let assetAudioTrack: AVAssetTrack = asset.tracks(withMediaType: .audio).first else { return }
  51.  
  52. var accumulatedTime = kCMTimeZero
  53. for (startTimeForCurrentSlice, endTimeForCurrentSlice) in trimPoints {
  54. let durationOfCurrentSlice = CMTimeSubtract(endTimeForCurrentSlice, startTimeForCurrentSlice)
  55. let timeRangeForCurrentSlice = CMTimeRangeMake(startTimeForCurrentSlice, durationOfCurrentSlice)
  56.  
  57. do {
  58. try videoCompTrack!.insertTimeRange(timeRangeForCurrentSlice, of: assetVideoTrack, at: accumulatedTime)
  59. try audioCompTrack!.insertTimeRange(timeRangeForCurrentSlice, of: assetAudioTrack, at: accumulatedTime)
  60. accumulatedTime = CMTimeAdd(accumulatedTime, durationOfCurrentSlice)
  61. }
  62. catch let compError {
  63. print("TrimVideo: error during composition: \(compError)")
  64. completion?(compError)
  65. }
  66. }
  67.  
  68. guard let exportSession = AVAssetExportSession(asset: composition, presetName: preferredPreset) else { return }
  69.  
  70. exportSession.outputURL = destinationURL as URL
  71. exportSession.outputFileType = AVFileType.m4v
  72. exportSession.shouldOptimizeForNetworkUse = true
  73.  
  74. removeFileAtURLIfExists(url: destinationURL as URL)
  75.  
  76. exportSession.exportAsynchronously {
  77. completion?(exportSession.error)
  78. }
  79. }
  80. else {
  81. print("TrimVideo - Could not find a suitable export preset for the input video")
  82. let error = NSError(domain: "com.bighug.ios", code: -1, userInfo: nil)
  83. completion?(error)
  84. }
  85. }
  86. }
Add Comment
Please, Sign In to add comment