Как избежать сжатия после выбора видео с UIImagePickerController в ios

Я использую UIImagePickerController для выбора видео из галереи и сжатия этого видео. Я хочу отключить компрессию, но я не нашел способ сделать это. Я также пробовал с ELCImagePickerController, что он показывает видео, но он похож на изображение, только нет значка видео или продолжительности времени, как показано в UIImagePickercontroller. Как я могу это сделать?

Спасибо.

Ответ 1

Невозможно избежать сжатия с помощью UIImagePickerController. См. Ответ:

fooobar.com/questions/299760/...

Я пробовал использовать imagePicker.videoQuality = UIImagePickerControllerQualityTypeHigh;, но он все еще выполняет сжатие. Тьфу.

EDIT:

Тем не менее, вы можете сворачивать свои собственные. Это позволит получить доступ к необработанным видеофайлам:

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
    }];
}

Посмотрите документацию PhotoKit для доступа к коллекциям (моменту) и другим параметрам.

Вот пример приложения от Apple, использующего PhotoKit, который можно было бы изменить как сборщик фотографий: https://developer.apple.com/library/ios/samplecode/UsingPhotosFramework/Introduction/Intro.html

Вот библиотека выбора фотографий на GitHub, которая использует PhotoKit, которая выглядит многообещающей, поскольку она предоставляет объекты PHAsset для всех выбранных изображений/видео: https://github.com/guillermomuntaner/GMImagePicker

iOS 7 и ниже

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

Собственно, вы можете получить исходный URL-адрес видео, не сжатую версию, с помощью следующего кода:

- (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.
            }   
        }]; 
    }
}

В качестве напоминания вызов requestAVAssetForVideo является асинхронным, поэтому будьте осторожны, если вы хотите сохранить URL-адрес с заблокированной переменной вне блока вызова метода.

Ответ 3

С iOS 11 вы можете использовать свойство "videoExportPreset". Это не оригинал, но по крайней мере я могу получить более 1280x720...

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

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

Ответ 4

С iOS 11 вы можете установить свойство videoExportPreset на AVAssetExportPresetPassthrough, чтобы получить оригинал:

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

Метка "Video compression..." просто мигает в течение нескольких миллисекунд, а затем экспорт выполняется.

@Diego Renau почти правильно ответил.