How can I reduce the file size of a video created with UIImagePickerController?

avfoundation, file-upload, ios, objective-c, video

Solution

With `AVCaptureSession` and `AVAssetWriter` you can set the compression settings as such:

NSDictionary *settings = @{AVVideoCodecKey:AVVideoCodecH264,
                           AVVideoWidthKey:@(video_width),
                           AVVideoHeightKey:@(video_height),
                           AVVideoCompressionPropertiesKey:
                               @{AVVideoAverageBitRateKey:@(desired_bitrate),
                                 AVVideoProfileLevelKey:AVVideoProfileLevelH264Main31, /* Or whatever profile & level you wish to use */
                                 AVVideoMaxKeyFrameIntervalKey:@(desired_keyframe_interval)}};

AVAssetWriterInput* writer_input = [AVAssetWriterInput assetWriterInputWithMediaType:AVMediaTypeVideo outputSettings:settings];

Edit: I guess if you insist on using the `UIImagePicker` to create the movie in the first place, you'll have to use `AVAssetReader's` `copyNextSampleBuffer` and `AVAssetWriter's` `appendSampleBuffer` methods to do the transcode.

Problem

I have an app that allows a user to record a video with `UIImagePickerController` and then upload it to YouTube. The problem is that the video file that `UIImagePickerController` creates is HUGE, even when the video is only 5 seconds long. For example, a 5 second long video is 16-20 megabytes. I want to keep the video in 540 or 720 quality, but I want to reduce the file size. I've been experimenting with AVFoundation and `AVAssetExportSession` to try to get a smaller file size. I've tried the following code: ``` AVAsset *video = [AVAsset assetWithURL:videoURL]; AVAssetExportSession *exportSession = [AVAssetExportSession exportSessionWithAsset:video presetName:AVAssetExportPresetPassthrough]; exportSession.shouldOptimizeForNetworkUse = YES; exportSession.outputFileType = AVFileTypeMPEG4; exportSession.outputURL = [pathToSavedVideosDirectory URLByAppendingPathComponent:@"vid1.mp4"]; [exportSession exportAsynchronouslyWithCompletionHandler:^{ NSLog(@"done processing video!"); }]; ``` But this hasn't reduced the file size at all. I know what I'm doing is possible because in Apple's Photos app, when you select "share on YouTube", will automatically process the video file so its small enough to upload. I want to do the same thing in my app. How can I accomplish this?

Original source

Related problems