Skip to content
This repository was archived by the owner on Feb 22, 2023. It is now read-only.

[image_picker]returned value should be of original video on iOS. #3457

Closed
wants to merge 13 commits into from
Closed
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -99,11 +99,16 @@ - (void)handleMethodCall:(FlutterMethodCall *)call result:(FlutterResult)result
_imagePickerController.modalPresentationStyle = UIModalPresentationCurrentContext;
_imagePickerController.delegate = self;
_imagePickerController.mediaTypes = @[
(NSString *)kUTTypeMovie, (NSString *)kUTTypeAVIMovie, (NSString *)kUTTypeVideo,
(NSString *)kUTTypeMPEG4
(NSString *)kUTTypeMovie,
(NSString *)kUTTypeAVIMovie,
(NSString *)kUTTypeVideo,
(NSString *)kUTTypeMPEG4,
];
_imagePickerController.videoQuality = UIImagePickerControllerQualityTypeHigh;

if (@available(iOS 11.0, *)) {
// Enable passthrough mode in video-picking mode.
_imagePickerController.videoExportPreset = AVAssetExportPresetPassthrough;
}
self.result = result;
_arguments = call.arguments;

Expand Down Expand Up @@ -256,7 +261,16 @@ - (void)showPhotoLibrary {

- (void)imagePickerController:(UIImagePickerController *)picker
didFinishPickingMediaWithInfo:(NSDictionary<NSString *, id> *)info {
NSURL *videoURL = [info objectForKey:UIImagePickerControllerMediaURL];
NSString *mediaType = info[UIImagePickerControllerMediaType];
NSURL *videoURL = nil;

if (CFStringCompare((__bridge CFStringRef)mediaType, kUTTypeMovie, 0) == kCFCompareEqualTo) {
videoURL = [info objectForKey:UIImagePickerControllerMediaURL];

if (videoURL == nil) {
videoURL = (NSURL *)info[UIImagePickerControllerReferenceURL];
}
}
[_imagePickerController dismissViewControllerAnimated:YES completion:nil];
// The method dismissViewControllerAnimated does not immediately prevent
// further didFinishPickingMediaWithInfo invocations. A nil check is necessary
Expand All @@ -266,11 +280,19 @@ - (void)imagePickerController:(UIImagePickerController *)picker
return;
}
if (videoURL != nil) {
if (@available(iOS 13.0, *)) {
if (@available(iOS 11.0, *)) {
NSString *fileName = [videoURL lastPathComponent];
NSURL *destination =
[NSURL fileURLWithPath:[NSTemporaryDirectory() stringByAppendingPathComponent:fileName]];

// Two different code paths exist for getting accessible real file path,
// even with the same OS version( on iOS 14.3).
//
// The first half is for newer devices(tested with iPhone Xs, 11 and 12),
// in which "videoURL" is prefixed with "file://".
//
// The second half is for older devices(tested with iPhone 7), in which
// "videoURL" is prefixed with "assets-library://".
if ([[NSFileManager defaultManager] isReadableFileAtPath:[videoURL path]]) {
NSError *error;
if (![[videoURL path] isEqualToString:[destination path]]) {
Expand All @@ -285,8 +307,45 @@ - (void)imagePickerController:(UIImagePickerController *)picker
}
}
videoURL = destination;
} else {
// PhotoKit for "assets-library://" schema handling.

PHAsset *originalAsset = [FLTImagePickerPhotoAssetUtil getAssetFromImagePickerInfo:info];

PHVideoRequestOptions *options = [PHVideoRequestOptions new];
options.version = PHVideoRequestOptionsVersionOriginal;

__weak typeof(self) weakSelf = self;
[[PHImageManager defaultManager]
requestAVAssetForVideo:originalAsset
options:options
resultHandler:^(AVAsset *_Nullable avasset, AVAudioMix *_Nullable audioMix,
NSDictionary *_Nullable info) {
NSError *error;
AVURLAsset *avAsset = (AVURLAsset *)avasset;

// Destination is a tmp file, reset/drop it before copy operation anyway.
[[NSFileManager defaultManager] removeItemAtURL:destination error:&error];
// Write to app tmp folder.
if ([[NSFileManager defaultManager] copyItemAtURL:avAsset.URL
toURL:destination
error:&error]) {
weakSelf.result(destination.path);
weakSelf.result = nil;
} else {
self.result([FlutterError
errorWithCode:@"flutter_image_picker_copy_video_error"
message:@"Could not cache the video file."
details:nil]);
self.result = nil;
return;
}
}];

return;
}
}

self.result(videoURL.path);
self.result = nil;
_arguments = nil;
Expand Down