项目作者: SergeyPetrachkov

项目描述 :
Export videos from library, compress, crop! iOS, Swift
高级语言: Swift
项目地址: git://github.com/SergeyPetrachkov/SwiftyVideoExporter.git
创建时间: 2018-08-19T09:32:57Z
项目社区:https://github.com/SergeyPetrachkov/SwiftyVideoExporter

开源协议:MIT License

下载


SwiftyVideoExporter

Here is a some raw code that will help you export video from gallery, compress it, crop, change aspect ratio if needed and set new bitrate using this package.
Sample code might not be compilable, but you get the idea :)

  1. let videoSettings = [
  2. AVVideoCodecKey: AVVideoCodecType.h264,
  3. AVVideoWidthKey: targetSize.width,
  4. AVVideoHeightKey: targetSize.height,
  5. AVVideoCompressionPropertiesKey: [
  6. AVVideoAverageBitRateKey: 1024_000,
  7. AVVideoProfileLevelKey: AVVideoProfileLevelH264High40
  8. ]
  9. ]
  10. let audioSettings = [
  11. AVFormatIDKey: kAudioFormatMPEG4AAC,
  12. AVNumberOfChannelsKey: 1,
  13. AVSampleRateKey: 44100,
  14. AVEncoderBitRateKey: 96_000
  15. ]
  16. protocol EpisodeUploaderDelegate: AnyObject {
  17. func didFail(with error: Error)
  18. func didFinishUploading(videoInfo: VideoInfo, callback: @escaping () -> Void)
  19. }
  20. final class EpisodeUploader: NSObject, UIImagePickerControllerDelegate, UINavigationControllerDelegate {
  21. weak var delegate: EpisodeUploaderDelegate?
  22. let exporterService: VideoProcessingServiceProtocol = VideoProcessingService()
  23. let imagePickerController: UIImagePickerController = {
  24. let controller = UIImagePickerController()
  25. controller.sourceType = .photoLibrary
  26. controller.mediaTypes = ["public.movie"]
  27. controller.allowsEditing = false
  28. controller.videoExportPreset = AVAssetExportPreset1280x720
  29. return controller
  30. }()
  31. override init() {
  32. super.init()
  33. self.imagePickerController.delegate = self
  34. }
  35. private var presentingView: UIViewController?
  36. func exportVideo(presentingView: UIViewController) {
  37. self.presentingView = presentingView
  38. self.presentingView?.present(self.imagePickerController, animated: true, completion: nil)
  39. }
  40. func authorizeToAlbum(completion: @escaping (Bool) -> Void) {
  41. if PHPhotoLibrary.authorizationStatus() != .authorized {
  42. NSLog("Will request authorization")
  43. PHPhotoLibrary.requestAuthorization({ (status) in
  44. if status == .authorized {
  45. DispatchQueue.main.async {
  46. completion(true)
  47. }
  48. } else {
  49. DispatchQueue.main.async {
  50. completion(false)
  51. }
  52. }
  53. })
  54. } else {
  55. DispatchQueue.main.async {
  56. completion(true)
  57. }
  58. }
  59. }
  60. func getUniqueFileUrl() -> URL {
  61. let tempDirectory = NSTemporaryDirectory()
  62. let tempVideoName = "/\(UUID().uuidString)"
  63. let processedURL = URL(fileURLWithPath: tempDirectory.appending(tempVideoName).appending(".mp4"))
  64. return processedURL
  65. }
  66. func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]) {
  67. if let videoURL = info[UIImagePickerController.InfoKey.mediaURL] as? URL {
  68. let tempDirectory = NSTemporaryDirectory()
  69. let tempVideoName = UUID().uuidString
  70. let processedURL = URL(fileURLWithPath: tempDirectory.appending(tempVideoName).appending(".mp4"))
  71. DispatchQueue(label: "video uploader queue").async {
  72. do {
  73. var processingParams = try VideoProcessingParameters(
  74. sourceURL: videoURL,
  75. outputURL: processedURL,
  76. targetFrameSize: CGSize(width: 600, height: 400),
  77. outputFileType: .mp4,
  78. audioSettings: audioSettings,
  79. videoSettings: videoSettings
  80. )!
  81. do {
  82. let fixedAspectRatio = try self.exporterService.changeAspectRatioIfNeeded(processingParameters: processingParams)
  83. if let error = fixedAspectRatio.error {
  84. throw error
  85. }
  86. processingParams.updateSourceUrl(fixedAspectRatio.inputParams.outputUrl)
  87. processingParams.updateOutputUrl(self.getUniqueFileUrl())
  88. } catch let aspectRatioProcessError {
  89. switch aspectRatioProcessError {
  90. case VideoAssetExportError.aspectRatioOk:
  91. break
  92. default:
  93. throw aspectRatioProcessError
  94. }
  95. }
  96. let output = try self.exporterService.processVideo(processingParameters: processingParams)
  97. if let error = output.error {
  98. throw error
  99. }
  100. // uncomment these lines to save processed and cropped video in gallery
  101. // DispatchQueue.main.async {
  102. // //Call when finished
  103. // PHPhotoLibrary.shared().performChanges({
  104. // PHAssetChangeRequest.creationRequestForAssetFromVideo(atFileURL: output.inputParams.outputUrl)
  105. // }) { saved, error in
  106. // if saved {
  107. // debugPrint("video has been saved to gallery")
  108. // }
  109. // }
  110. // }
  111. try? FileManager.default.removeItem(at: processedURL)
  112. DispatchQueue.main.async {
  113. self.delegate?.didFinishUploading(videoInfo: result, callback: {
  114. picker.dismiss(animated: true, completion: nil)
  115. })
  116. }
  117. } catch let error {
  118. switch error {
  119. case VideoAssetExportError.nilVideoTrack:
  120. fallthrough
  121. case VideoAssetExportError.portraitVideoNotSupported:
  122. fallthrough
  123. default:
  124. try? FileManager.default.removeItem(at: processedURL)
  125. DispatchQueue.main.async {
  126. picker.dismiss(animated: true, completion: nil)
  127. self.delegate?.didFail(with: error)
  128. }
  129. }
  130. }
  131. }
  132. func imagePickerControllerDidCancel(_ picker: UIImagePickerController) {
  133. }
  134. }