UIImagePickerController returns H.265 instead of H.264

Viewed 1445

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?

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!
                //
            }
        }];
    }];
}
Related