简体   繁体   中英

Avoid Video Compression when Selecting Movie with UIImagePickerController?

I'm using UIImagePickerController to allow my user to select a video from the asset library.

When the user selects the "Choose" button on the second screen, the view displays a progress bar and a "Compressing Video..." message.

Why is this happening?

Is there some way I can avoid this compression operation?

Answer: There is currently no way to control how UIImagePickerController compresses the picked video.

I just did some quick tests. Using a test app I created, I picked the same video two times -- once with the videoQuality property set to UIImagePickerControllerQualityTypeHigh and once with it set to UIImagePickerControllerQualityTypeLow . The resulting files that were copied over are exactly the same size, 15.1MB with a frame size of 360x480. The original was 72.5MB with a frame size of 480x640. Apparently this property doesn't affect the compression used at all.

Set the videoQuality property of the UIImagePickerController to "High" (UIImagePickerControllerQualityTypeHigh = 0)

From the SDK documentation: "If displaying a recorded movie in the image picker, specifies that you do not want to reduce the video quality of the movie."

http://developer.apple.com/iphone/library/documentation/uikit/reference/UIImagePickerController_Class/UIImagePickerController/UIImagePickerController.html#//apple_ref/doc/c_ref/UIImagePickerControllerQualityType

Since there is no way yet to avoid compression using UIImagePickerController, I wanted to include some ideas of how you can create your own image picker that will avoid compression.

This will allow access to the raw video files:

iOS 8

PHFetchResult *assetsFetchResult = [PHAsset fetchAssetsWithMediaType:PHAssetMediaTypeVideo options:nil];
for (PHAsset *asset in assetsFetchResult) {
    PHVideoRequestOptions *videoRequestOptions = [[PHVideoRequestOptions alloc] init];
    videoRequestOptions.version = PHVideoRequestOptionsVersionOriginal;

    [[PHImageManager defaultManager] requestAVAssetForVideo:asset options:videoRequestOptions resultHandler:^(AVAsset *asset, AVAudioMix *audioMix, NSDictionary *info) {
        // the AVAsset object represents the original video file
    }];
}

Look at the PhotoKit documentation for accessing collections (moments) and other options.

Here is a sample app from Apple using PhotoKit that could be modified to be a photo picker: https://developer.apple.com/library/ios/samplecode/UsingPhotosFramework/Introduction/Intro.html

Here is a photo picker library on GitHub that uses PhotoKit that looks promising since it gives you the PHAsset objects for all the selected images/videos: https://github.com/guillermomuntaner/GMImagePicker

iOS 7 and below

ALAssetsLibrary *library = [[ALAssetsLibrary alloc] init];

[library enumerateGroupsWithTypes:ALAssetsGroupAll usingBlock:^(ALAssetsGroup *group, BOOL *stop) {
    if (group) {
        // If you want, you can filter just pictures or videos
        // I just need videos so I do this:
        [group setAssetsFilter:[ALAssetsFilter allVideos]];

        [group enumerateAssetsUsingBlock:^(ALAsset *asset, NSUInteger index, BOOL *stop){
            if (asset){
                // You can now add this ALAsset in your own video picker.
                // Note that you can only access the ALAsset as long as 
                // you maintain a reference to the ALAssetsLibrary

                // Or if you want to process the video, you can create an AVAsset:
                NSURL *url = asset.defaultRepresentation.url;
                AVAsset *videoAsset = [AVAsset assetWithURL:url];
            }
        }];
    }
} failureBlock:^(NSError *error) {
    NSLog(@"error enumerating AssetLibrary groups %@\n", error);
}];

Starting from iOS 11, you can specify the videoExportPreset and set it to AVAssetExportPresetPassthrough :

picker.videoExportPreset = AVAssetExportPresetPassthrough

This will still show the "compressing" progress bar though, but will be much faster, especially for smaller videos.

For those giving the advice to use the videoQuality property, documentation is clearly stating that it is a video capture option, not a picker option.

As Jack is mentioning it below, it is also for transcoding. Looks like I read the doc too quickly because I didn't notice the transcoding mention.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM