Fixes FileType.audio on iOS by exporting non DRM ipod-library files (#441)
This commit is contained in:
parent
b690afe33e
commit
0fa01bb74a
|
@ -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))
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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: ©Error];
|
||||
|
||||
|
||||
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) {
|
||||
|
|
|
@ -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
|
||||
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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:
|
||||
|
|
Loading…
Reference in New Issue