Fixes FileType.audio on iOS by exporting non DRM ipod-library files (#441)

This commit is contained in:
Miguel Ruivo 2020-10-25 18:07:36 +00:00
parent b690afe33e
commit 0fa01bb74a
7 changed files with 94 additions and 11 deletions

View File

@ -1,3 +1,6 @@
## 2.0.11
iOS: Fixes `FileType.audio` exports to support ipod-library content (non DRM protected). From now on, a cached asset (m4a) will be exported from the selected music file in the Music app, so it can later be used. Fixes ([#441](https://github.com/miguelpruivo/flutter_file_picker/issues/441)).
## 2.0.10
Adds missing extension to `name` property of `PlatformFile`. ([#444](https://github.com/miguelpruivo/flutter_file_picker/issues/444))

View File

@ -45,6 +45,7 @@ See the **[File Picker Wiki](https://github.com/miguelpruivo/flutter_file_picker
* [Filters](https://github.com/miguelpruivo/plugins_flutter_file_picker/wiki/API#filters)
* [Parameters](https://github.com/miguelpruivo/flutter_file_picker/wiki/API#parameters)
* [Methods](https://github.com/miguelpruivo/plugins_flutter_file_picker/wiki/API#methods)
4. [FAQ](https://github.com/miguelpruivo/flutter_file_picker/wiki/FAQ)
5. [Troubleshooting](https://github.com/miguelpruivo/flutter_file_picker/wiki/Troubleshooting)
## Usage

View File

@ -9,7 +9,7 @@
#import <PhotosUI/PHPicker.h>
#endif
@interface FilePickerPlugin : NSObject<FlutterPlugin, FlutterStreamHandler, UIDocumentPickerDelegate, UITabBarDelegate, UINavigationControllerDelegate, UIImagePickerControllerDelegate, UIImagePickerControllerDelegate, MPMediaPickerControllerDelegate
@interface FilePickerPlugin : NSObject<FlutterPlugin, FlutterStreamHandler, UIDocumentPickerDelegate, UITabBarDelegate, UINavigationControllerDelegate, UIImagePickerControllerDelegate, MPMediaPickerControllerDelegate
#ifdef PHPicker
, PHPickerViewControllerDelegate
#endif

View File

@ -136,8 +136,8 @@
}
- (void) resolvePickMedia:(MediaType)type withMultiPick:(BOOL)multiPick withCompressionAllowed:(BOOL)allowCompression {
#ifdef PHPicker
#ifdef PHPicker
if (@available(iOS 14, *)) {
PHPickerConfiguration *config = [[PHPickerConfiguration alloc] init];
config.filter = type == IMAGE ? [PHPickerFilter imagesFilter] : type == VIDEO ? [PHPickerFilter videosFilter] : [PHPickerFilter anyFilterMatchingSubfilters:@[[PHPickerFilter videosFilter], [PHPickerFilter imagesFilter]]];
@ -152,7 +152,7 @@
[self.viewController presentViewController:pickerViewController animated:YES completion:nil];
return;
}
#endif
#endif
if(multiPick) {
[self resolveMultiPickFromGallery:type withCompressionAllowed:allowCompression];
@ -401,7 +401,7 @@ didPickDocumentsAtURLs:(NSArray<NSURL *> *)urls{
[NSFileManager.defaultManager copyItemAtURL: url
toURL: cachedUrl
error: &copyError];
if (copyError) {
Log("%@ Error while caching picked file: %@", self, copyError);
return;
@ -424,10 +424,25 @@ didPickDocumentsAtURLs:(NSArray<NSURL *> *)urls{
- (void)mediaPicker: (MPMediaPickerController *)mediaPicker didPickMediaItems:(MPMediaItemCollection *)mediaItemCollection
{
[mediaPicker dismissViewControllerAnimated:YES completion:NULL];
NSMutableArray<NSURL *> * urls = [[NSMutableArray alloc] initWithCapacity:[mediaItemCollection items].count];
int numberOfItems = (int)[mediaItemCollection items].count;
if(numberOfItems == 0) {
return;
}
if(_eventSink != nil) {
_eventSink([NSNumber numberWithBool:YES]);
}
NSMutableArray<NSURL *> * urls = [[NSMutableArray alloc] initWithCapacity:numberOfItems];
for(MPMediaItemCollection * item in [mediaItemCollection items]) {
[urls addObject: [item valueForKey:MPMediaItemPropertyAssetURL]];
NSURL * cachedAsset = [FileUtils exportMusicAsset: [item valueForKey:MPMediaItemPropertyAssetURL] withName: [item valueForKey:MPMediaItemPropertyTitle]];
[urls addObject: cachedAsset];
}
if(_eventSink != nil) {
_eventSink([NSNumber numberWithBool:NO]);
}
if(urls.count == 0) {

View File

@ -24,6 +24,7 @@ typedef NS_ENUM(NSInteger, MediaType) {
+ (NSArray<NSString*>*) resolveType:(NSString*)type withAllowedExtensions:(NSArray<NSString*>*)allowedExtensions;
+ (MediaType) resolveMediaType:(NSString*)type;
+ (NSArray<NSDictionary*>*) resolveFileInfo:(NSArray<NSURL *> *)urls withData:(BOOL)loadData;
+ (NSURL*) exportMusicAsset:(NSString*)url withName: (NSString*)name;
@end

View File

@ -89,12 +89,75 @@
NSDictionary<NSFileAttributeKey, id> * fileAttributes = [[NSFileManager defaultManager] attributesOfItemAtPath:path error:nil];
[files addObject: [[[FileInfo alloc] initWithPath: path
andName: [path lastPathComponent]
andSize: [NSNumber numberWithLongLong: [@(fileAttributes.fileSize) longLongValue] / 1024]
andData: loadData ? [NSData dataWithContentsOfFile:path options: 0 error:nil] : nil] toData]];
andName: [path lastPathComponent]
andSize: [NSNumber numberWithLongLong: [@(fileAttributes.fileSize) longLongValue] / 1024]
andData: loadData ? [NSData dataWithContentsOfFile:path options: 0 error:nil] : nil] toData]];
}
return files;
}
+ (NSURL*) exportMusicAsset:(NSString*) url withName:(NSString *)name {
AVURLAsset *songAsset = [AVURLAsset URLAssetWithURL: (NSURL*)url options:nil];
AVAssetExportSession *exporter = [[AVAssetExportSession alloc] initWithAsset: songAsset
presetName:AVAssetExportPresetAppleM4A];
exporter.outputFileType = @"com.apple.m4a-audio";
NSString* savePath = [NSTemporaryDirectory() stringByAppendingPathComponent:[name stringByAppendingString:@".m4a"]];
NSURL *exportURL = [NSURL fileURLWithPath:savePath];
if ([[NSFileManager defaultManager] fileExistsAtPath:savePath]) {
return exportURL;
}
exporter.outputURL = exportURL;
dispatch_queue_t queue = dispatch_queue_create("exportQueue", 0);
dispatch_async(queue, ^{
dispatch_semaphore_t semaphore = dispatch_semaphore_create(0);
[exporter exportAsynchronouslyWithCompletionHandler:
^{
switch (exporter.status)
{
case AVAssetExportSessionStatusFailed:
{
NSError *exportError = exporter.error;
Log(@"AVAssetExportSessionStatusFailed: %@", exportError);
break;
}
case AVAssetExportSessionStatusCompleted:
{
Log(@"AVAssetExportSessionStatusCompleted");
@autoreleasepool {
dispatch_semaphore_signal(semaphore);
}
break;
}
case AVAssetExportSessionStatusCancelled:
{
Log(@"AVAssetExportSessionStatusCancelled");
@autoreleasepool {
dispatch_semaphore_signal(semaphore);
}
break;
}
default:
{
Log(@"didn't get export status");
break;
}
}
}];
dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);
});
return exportURL;
}
@end

View File

@ -1,7 +1,7 @@
name: file_picker
description: A package that allows you to use a native file explorer to pick single or multiple absolute file paths, with extension filtering support.
homepage: https://github.com/miguelpruivo/plugins_flutter_file_picker
version: 2.0.10
version: 2.0.11
dependencies:
flutter: