Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

UIImagePickerController returns H.265 instead of H.264

Tags:

ios

swift

ios11

I have an app that uses a UIImagePickerController object to get a video file for sharing.

I'm setting the media types (picker.mediaTypes = [kUTTypeMovie as String]) and using the field UIImagePickerControllerMediaURL to fetch either the video details. This works properly and there are no issues when all devices are either H.264 live encoding, or when all devices are H.265 live decoding.

The issue is that I need to support devices which cannot playback H.265 content. I would like to take the "create a single compatible file" route. How can I tell UIImagePickerController to give me a H.264 video regardless of recording device's capabilities?

like image 705
Ezekiel Avatar asked Aug 03 '17 19:08

Ezekiel


People also ask

Is H 265 better than h264?

265 is newer and more advanced than H. 264 in several ways. H. 265 (also called HEVC, or High Efficiency Video Coding) allows for further reduced file size, and therefore reduced required bandwidth, of your live video streams.

What is the difference between H 265 and H 265?

In a nutshell, H. 265+ can save approximate 50% bitrate than H. 265, which means it can lower bandwidth and storage consumption further.

What is the difference between HEVC and x264?

x264 is the most established open-source software encoder for H. 264/AVC. HEVC is the successor to H. 264/AVC and results reported from standardization showed about 50% bitrate savings for the same quality compared to H.


1 Answers

This is what worked for me. I used an AVAssetExportSession to get a H.265 video exported in H.264 format.

Maybe the above solution would work by choosing AVAssetExportPresetHighestQuality as the videoExportPreset property to UIImagePickerController. The bonus of my approach is iOS 9/10 compatibility. And maybe a snappier UI because you can do the export on a background thread.

I can't use UIImagePickerController because the same picker workflow in my app allows the user to select multiples, so I'm using CTAssetsPickerController, which requires the use of PHAsset for the returned media objects.

Ezekiel and nathan's discussion led me to this solution, so sharing it here.

PHAsset *phasset = <fetched-asset>;
NSURL *assetURL = <where-to-store-exported-asset>;

if(PHAssetMediaTypeVideo == phasset.mediaType) {
    [[PHImageManager defaultManager] requestAVAssetForVideo: phasset
        options: nil resultHandler:^(AVAsset * _Nullable avasset, AVAudioMix * _Nullable audioMix, NSDictionary * _Nullable info) {
        AVAssetExportSession *exportSession =
            [AVAssetExportSession exportSessionWithAsset: avasset presetName: AVAssetExportPresetHighestQuality];
        exportSession.outputURL = assetURL;
        exportSession.outputFileType = AVFileTypeMPEG4;
        [exportSession exportAsynchronouslyWithCompletionHandler:^{
            if(exportSession.status == AVAssetExportSessionStatusCompleted) {
                //
                // success!
                //
            }
        }];
    }];
}
like image 66
CodeWriter23 Avatar answered Nov 03 '22 22:11

CodeWriter23