2016-12-02 3 views
3

У меня есть ссылка на MPMediaItem, когда пользователь выбирает звук из библиотеки iPod. Я получаю URL активов этого элемента с помощьюМожно ли сохранить музыку из библиотеки Ipod в мое приложение со скоростью?

let url = item.valueForProperty(MPMediaItemPropertyAssetURL) 

Но это не дает мне точное физическое местоположение файла, вместо этого, он дает мне URL w.r.t библиотеки IPOD.

ipod-library://item/item.mp3?id=1840064795502796074 

Есть ли способ получить физический URL-адрес песни из библиотеки iPod?

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

MPmediaPickerController работает, я выбираю песню и его игра, но я не хочу играть в песню. Я пытался загрузить аудиофайлы на сервер. И у меня есть выбор MPMedia Picker в списке аудио, когда я собираюсь выбрать звук, который я загружу на сервер (HTTP), Как я могу это сделать ??? Как получить доступ к медиа-библиотеке с помощью кода Swift?

ответ

4

Адаптирование ответ Кришны, который использует AVAssetExportSession сохранить MPMediaItem в файл, вы можете сделать что-то вроде следующего в Swift 3:

/// Export MPMediaItem to temporary file. 
/// 
/// - Parameters: 
/// - assetURL: The `assetURL` of the `MPMediaItem`. 
/// - completionHandler: Closure to be called when the export is done. The parameters are a boolean `success`, the `URL` of the temporary file, and an optional `Error` if there was any problem. The parameters of the closure are: 
/// 
/// - fileURL: The `URL` of the temporary file created for the exported results. 
/// - error: The `Error`, if any, of the asynchronous export process. 

func export(_ assetURL: URL, completionHandler: @escaping (_ fileURL: URL?, _ error: Error?) ->()) { 
    let asset = AVURLAsset(url: assetURL) 
    guard let exporter = AVAssetExportSession(asset: asset, presetName: AVAssetExportPresetAppleM4A) else { 
     completionHandler(nil, ExportError.unableToCreateExporter) 
     return 
    } 

    let fileURL = URL(fileURLWithPath: NSTemporaryDirectory()) 
     .appendingPathComponent(NSUUID().uuidString) 
     .appendingPathExtension("m4a") 

    exporter.outputURL = fileURL 
    exporter.outputFileType = "com.apple.m4a-audio" 

    exporter.exportAsynchronously { 
     if exporter.status == .completed { 
      completionHandler(fileURL, nil) 
     } else { 
      completionHandler(nil, exporter.error) 
     } 
    } 
} 

func exampleUsage(with mediaItem: MPMediaItem) { 
    if let assetURL = mediaItem.assetURL { 
     export(assetURL) { fileURL, error in 
      guard let fileURL = fileURL, error == nil else { 
       print("export failed: \(error)") 
       return 
      } 

      // use fileURL of temporary file here 
      print("\(fileURL)") 
     } 
    } 
} 

enum ExportError: Error { 
    case unableToCreateExporter 
} 

Или, in Swift 2:

/// Export MPMediaItem to temporary file. 
/// 
/// - Parameters: 
/// - assetURL: The `assetURL` of the `MPMediaItem`. 
/// - completionHandler: Closure to be called when the export is done. The parameters are a boolean `success`, the `URL` of the temporary file, and an optional `Error` if there was any problem. The parameters of the closure are: 
/// 
/// - fileURL: The `URL` of the temporary file created for the exported results. 
/// - error: The `Error`, if any, of the asynchronous export process. 

func export(assetURL: NSURL, completionHandler: (NSURL?, ErrorType?) ->()) { 
    let asset = AVURLAsset(URL: assetURL) 
    guard let exporter = AVAssetExportSession(asset: asset, presetName: AVAssetExportPresetAppleM4A) else { 
     completionHandler(nil, ExportError.unableToCreateExporter) 
     return 
    } 

    let fileURL = NSURL(fileURLWithPath: NSTemporaryDirectory()) 
     .URLByAppendingPathComponent(NSUUID().UUIDString)! 
     .URLByAppendingPathExtension("m4a") 

    exporter.outputURL = fileURL 
    exporter.outputFileType = "com.apple.m4a-audio" 

    exporter.exportAsynchronouslyWithCompletionHandler { 
     if exporter.status == .Completed { 
      completionHandler(fileURL, nil) 
     } else { 
      completionHandler(nil, exporter.error) 
     } 
    } 
} 

func exampleUsage(with mediaItem: MPMediaItem) { 
    if let assetURL = mediaItem.assetURL { 
     export(assetURL) { fileURL, error in 
      guard let fileURL = fileURL where error == nil else { 
       print("export failed: \(error)") 
       return 
      } 

      // use fileURL of temporary file here 
      print("\(fileURL)") 
     } 
    } 
} 

enum ExportError: ErrorType { 
    case unableToCreateExporter 
} 

Как вы можете видеть, я сказал, что i n временная папка, а не папка «Документы». Кроме того, я использую UUID, а не количество секунд с некоторой ссылочной даты для создания временного файла. Но идея в основном такая же.

+0

Спасибо, очень много. Я искал код за последние 2 недели ... Наконец, я получаю его от вас, и он работает нормально. Большое вам спасибо. У меня есть небольшое сомнение в том, что я exporter.status ==. Завершен и получить данные. Размер данных слишком велик, как я могу уменьшить это без качества песни ... –

+0

Это характер аудиофайлов, которые, как правило, очень большой, если только это не очень короткий клип (несколько секунд).И, как правило, вы не можете резко уменьшить размер, не уменьшая качество и/или уменьшая извлечение 'TimeRange'. Честно говоря, по этой причине вы обычно не храните музыку в объекте 'NSData' /' Data' (потому что они хранятся в памяти одновременно), а мы обычно передаем музыкальные файлы. – Rob

+0

На самом деле, я работаю с приложением для караоке. Поэтому я должен загрузить выбранную песню iTunes на сервер PHP. Если я загружаю низкую память, она работает нормально. Но если я загружу песни iTunes, она не будет загружена. Из-за высокой памяти. решение??? –

2

После выбора песни из библиотеки конвертируйте объект MPMediaItem в NSData и загрузите его на сервер с использованием данных с несколькими формами.

Преобразовать MPMediaItem в NSData

-(void)mediaItemToData : (MPMediaItem *) curItem 
{ 
    NSURL *url = [curItem valueForProperty: MPMediaItemPropertyAssetURL]; 
    AVURLAsset *songAsset = [AVURLAsset URLAssetWithURL: url options:nil]; 

    AVAssetExportSession *exporter = [[AVAssetExportSession alloc] initWithAsset: songAsset 
                     presetName:AVAssetExportPresetAppleM4A]; 

    exporter.outputFileType = @"com.apple.m4a-audio"; 

    NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES); 
    NSString * myDocumentsDirectory = ([paths count] > 0) ? [paths objectAtIndex:0] : nil; 

    [[NSDate date] timeIntervalSince1970]; 
    NSTimeInterval seconds = [[NSDate date] timeIntervalSince1970]; 
    NSString *intervalSeconds = [NSString stringWithFormat:@"%0.0f",seconds]; 

    NSString * fileName = [NSString stringWithFormat:@"%@.m4a",intervalSeconds]; 

    NSString *exportFile = [myDocumentsDirectory stringByAppendingPathComponent:fileName]; 

    NSURL *exportURL = [NSURL fileURLWithPath:exportFile]; 
    exporter.outputURL = exportURL; 

    // do the export 
    // (completion handler block omitted) 
    [exporter exportAsynchronouslyWithCompletionHandler: 
    ^{ 
     int exportStatus = exporter.status; 

     switch (exportStatus) 
     { 
      case AVAssetExportSessionStatusFailed: 
      { 
       NSError *exportError = exporter.error; 
       NSLog (@"AVAssetExportSessionStatusFailed: %@", exportError); 
       break; 
      } 
      case AVAssetExportSessionStatusCompleted: 
      { 
       NSLog (@"AVAssetExportSessionStatusCompleted"); 

       NSData *data = [NSData dataWithContentsOfFile: [myDocumentsDirectory 
                   stringByAppendingPathComponent:fileName]]; 

       [arrayMusic addObject:data]; 
       data = nil; 

       break; 
      } 
      case AVAssetExportSessionStatusUnknown: 
      { 
       NSLog (@"AVAssetExportSessionStatusUnknown"); break; 
      } 
      case AVAssetExportSessionStatusExporting: 
      { 
       NSLog (@"AVAssetExportSessionStatusExporting"); break; 
      } 
      case AVAssetExportSessionStatusCancelled: 
      { 
       NSLog (@"AVAssetExportSessionStatusCancelled"); break; 
      } 
      case AVAssetExportSessionStatusWaiting: 
      { 
       NSLog (@"AVAssetExportSessionStatusWaiting"); break; 
      } 
      default: 
      { 
       NSLog (@"didn't get export status"); break; 
      } 
     } 
    }]; 

} 
+0

У вас есть код для этого? –

+0

Если я выбираю песню, я получаю заголовок и MPMediaItemPropertyAssetURLvalue.If я конвертирую в данные, это nil ... как получить NSData MPMediaItem? –

+0

Проверьте мой отредактированный ответ .... –