1

Is there a way to export a video with resolution 480 x 960 ? I know there are libraries for this but I'd rather do it without installing more pods on my project if possible.

I am converting a captured video in .MOV to .MP4. I used the method suggested on this thread.

The available options from AVAssetExport are these:

AVAssetExportPresetLowQuality  
AVAssetExportPresetMediumQuality 
AVAssetExportPresetHighestQuality 
AVAssetExportPresetHEVCHighestQuality  
AVAssetExportPreset640x480 
AVAssetExportPreset960x540  
AVAssetExportPreset1280x720 
AVAssetExportPreset1920x1080  
AVAssetExportPreset3840x2160

Is this the correct approach if the exported video is MP4? The documentation for AVAssetExportSession says this is for quicktime movies so I am a bit confused about this.

    func exportVideo(inputurl: URL,
                 presetName: String = AVAssetExportPresetHighestQuality,
                 outputFileType: AVFileType = .mp4,
                 fileExtension: String = "mp4",
                 then completion: @escaping (URL?) -> Void)
{
    let asset = AVAsset(url: inputurl)


    let filename = filePath.deletingPathExtension().appendingPathExtension(fileExtension).lastPathComponent
    outputURL = FileManager.default.temporaryDirectory.appendingPathComponent(filename)

    if let session = AVAssetExportSession(asset: asset, presetName: presetName) {
        session.outputURL = outputURL
        session.outputFileType = outputFileType

        session.shouldOptimizeForNetworkUse = true
        session.exportAsynchronously {
            switch session.status {
            case .completed:
                completion(self.outputURL)
            case .cancelled:
                debugPrint("Video export cancelled.")
                completion(nil)
            case .failed:
                let errorMessage = session.error?.localizedDescription ?? "n/a"
                debugPrint("Video export failed with error: \(errorMessage)")
                completion(nil)
            default:
                break
            }
        }
    } else {
        completion(nil)
    }
}
Maruta
  • 917
  • 8
  • 19

1 Answers1

0

You must transform video tranck and video composition to your export session...

You have to do something like this:

    //transform video
    let rotationTransform = CGAffineTransform(rotationAngle: .pi)
    videoTrack.preferredTransform = rotationTransform;

    let layerInstruction = AVMutableVideoCompositionLayerInstruction(assetTrack: videoTrack)
    layerInstruction.setTransform(videoAssetTrack.preferredTransform, at: kCMTimeZero)

    let videoCompositionInstruction = AVMutableVideoCompositionInstruction()
    videoCompositionInstruction.timeRange = CMTimeRangeMake(kCMTimeZero, videoAsset.duration)
    videoCompositionInstruction.layerInstructions = [layerInstruction]

    let videoComposition = AVMutableVideoComposition()
    videoComposition.instructions = [videoCompositionInstruction]
    videoComposition.frameDuration = CMTime(value: 1, timescale: 30)
    videoComposition.renderSize = videoSize

    //saving...
    guard let exportSession = AVAssetExportSession(asset: composition, presetName: AVAssetExportPresetMediumQuality) else { return }
    //exportSession.outputURL = your output url
    exportSession.videoComposition = videoComposition
Jabson
  • 1,336
  • 1
  • 9
  • 16
  • thank you! I used this method but for some reason it only changes the size of the canvas but not the video – Maruta Sep 03 '19 at 08:46
  • ok, than try to change layerInstruction transform like this: layerInstruction.setTransform(rotationTransform, at: kCMTimeZero) this code is not tested, because i need extra job to test... play around it. – Jabson Sep 03 '19 at 09:56