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?
The first is to make your video shorter. If you can trim footage off of the beginning or end, that will reduce the size of the file. The second method is by removing the audio from your video. Most videos will probably benefit from having audio and background music included, but if it's unnecessary, you can remove it.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With