How to avoid compression after selecting video fro

2019-01-23 04:55发布

问题:

I am using UIImagePickerController to select video from Gallery and it compress that video.I want to disable Compression but I don't find the way to do this. I also tried with ELCImagePickerController it is showing video but it is looking like an image only there is no video icon or time duration like it shows in UIImagePickercontroller.How can I do it?

Thanks.

回答1:

It doesn't look like it's possible to avoid compression using the UIImagePickerController. See this answer:

https://stackoverflow.com/a/5893066/406152

I've tried using imagePicker.videoQuality = UIImagePickerControllerQualityTypeHigh; but it still does compression. Ugh.

EDIT:

However, you can roll your own. 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);
}];


回答2:

With iOS 11 you can set the property videoExportPreset to AVAssetExportPresetPassthrough to get the original:

if #available(iOS 11.0, *) {
    picker.videoExportPreset = AVAssetExportPresetPassthrough
}

The "Video compression..." label just flashes for a few milliseconds and then the export is done.

@Diego Renau almost had the correct answer.



回答3:

Actually, you can get the original video URL, non-compressed version, via the following code:

- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info { 
    NSString *mediaType = info[UIImagePickerControllerMediaType];
    NSString *videoString = (NSString *)kUTTypeVideo;
    NSString *movieString = (NSString *)kUTTypeMovie;

    if ([mediaType isEqualToString:videoString] || [mediaType isEqualToString:movieString]) {
        NSURL *videoRef = info[UIImagePickerControllerReferenceURL];
        PHFetchResult *refResult = [PHAsset fetchAssetsWithALAssetURLs:@[videoRef] options:nil];                                                                                                                                        
        PHVideoRequestOptions *videoRequestOptions = [[PHVideoRequestOptions alloc] init];
        videoRequestOptions.version = PHVideoRequestOptionsVersionOriginal;
        [[PHImageManager defaultManager] requestAVAssetForVideo:[refResult firstObject] options:videoRequestOptions resultHandler:^(AVAsset *asset, AVAudioMix *audioMix, NSDictionary *info) {
            if ([asset isKindOfClass:[AVURLAsset class]]) {
                  NSURL *originURL = [(AVURLAsset *)asset URL];
                  // Now you have the URL of the original video.
            }   
        }]; 
    }
}

As a reminder, the requestAVAssetForVideo call is asynchronous, so be careful when you want to store the url with a blocked variable outside the method calling block.



回答4:

With iOS 11 you can use the property "videoExportPreset". It's not the original but at least I can get more than 1280x720...

if #available(iOS 11.0, *) {
         picker.videoExportPreset = AVAssetExportPreset1920x1080
} else {
            // Fallback on earlier versions 
}

//AVAssetExportPreset640x480
//AVAssetExportPreset960x540
//AVAssetExportPreset1280x720
//AVAssetExportPreset1920x1080
//AVAssetExportPreset3840x2160