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?
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.
In a nutshell, H. 265+ can save approximate 50% bitrate than H. 265, which means it can lower bandwidth and storage consumption further.
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.
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!
//
}
}];
}];
}
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