Как я могу экспортировать аудиофайл AVPlayer в формате mp3 с помощью AVAssetExportSession?

Теперь я пытаюсь экспортировать mp3-файл, который был воспроизведен с помощью AVPlayer (с использованием URL-адреса), поэтому его не нужно загружать дважды.

Это мой пример кода:

Я пробовал каждый outputFileType...

    self.exporter = [[AVAssetExportSession alloc] initWithAsset:self.asset presetName:AVAssetExportPresetPassthrough];
        }

        NSError *error;

        NSLog(@"export.supportedFileTypes : %@",self.exporter.supportedFileTypes);
       //        "com.apple.quicktime-movie",
//        "com.apple.m4a-audio",
//        "public.mpeg-4",
//        "com.apple.m4v-video",
//        "public.3gpp",
//        "org.3gpp.adaptive-multi-rate-audio",
//        "com.microsoft.waveform-audio",
//        "public.aiff-audio",
//        "public.aifc-audio",
//        "com.apple.coreaudio-format"

        self.exporter.outputFileType = @"public.aiff-audio";
        self.exporter.shouldOptimizeForNetworkUse = YES;

        NSURL *a = [[NSFileManager defaultManager] URLForDirectory:NSDocumentDirectory inDomain:NSUserDomainMask appropriateForURL:nil create:YES error:&error];

        NSURL *url = [a URLByAppendingPathComponent:@"filename.mp3"];

        NSString *filePath = [url absoluteString];

        self.exporter.outputURL = url;

        if (![[NSFileManager defaultManager] fileExistsAtPath:filePath]){
            [self.exporter exportAsynchronouslyWithCompletionHandler:^{

                if (self.exporter.status == AVAssetExportSessionStatusCompleted)
                {

                    if (![[NSFileManager defaultManager] fileExistsAtPath:filePath]){
                        NSLog(@"File doesn't exist at path");
                    }else {
                        NSLog@"File saved!");
}                    
                }
                else if(self.exporter.status == AVAssetExportSessionStatusFailed){
                    NSLog(@"Failed");
                }else if(self.exporter.status == AVAssetExportSessionStatusUnknown){
                    NSLog(@"Unknown");
                }else if(self.exporter.status == AVAssetExportSessionStatusCancelled){
                    NSLog(@"Cancelled");
                }else if(self.exporter.status == AVAssetExportSessionStatusWaiting){
                    NSLog(@"Waiting");
                }else if(self.exporter.status == AVAssetExportSessionStatusExporting){
                    NSLog(@"Exporting");
                }

                NSLog(@"Exporter error! : %@",self.exporter.error);

              }];

        }}else{
            NSLog(@"File already exists at path");
        }

Если это невозможно выполнить, есть ли обходной путь?

Также, как я могу изменить формат аудио файла. Какой идеальный тип для работы с AVAudioPlayer?


person jonypz    schedule 14.06.2016    source источник
comment
Да, даже собственный пример проекта Apple AVFoundationExporter, похоже, не работает с mp3-файлами и пресетом AVAssetExportPresetPassthrough.   -  person Dalmazio    schedule 17.09.2016
comment
см. ответ здесь, может вам помочь: stackoverflow.com/a/47327516/1682312   -  person Usman Nisar    schedule 16.11.2017


Ответы (3)


Похоже, что AVAssetExportSession поддерживает только типы файлов для перекодирования mp3 с помощью com.apple.quicktime-movie (.mov) и com.apple.coreaudio-format (.caf) с использованием AVAssetExportPresetPassthrough предустановлен. Вы также должны обязательно использовать одно из этих расширений файла при записи выходного файла, иначе он не будет сохранен.

Поддерживаемый тип выходного файла и расширения для входного файла mp3 выделены жирным шрифтом (проверено на OS X 10.11.6):

  • com.apple.quicktime-movie (.mov)
  • com.apple.m4a-аудио (.m4a)
  • общедоступный.mpeg-4 (.mp4)
  • com.apple.m4v-видео (.m4v)
  • org.3gpp.adaptive-multi-rate-audio (.amr)
  • com.microsoft.waveform-аудио (.wav)
  • public.aiff-аудио (.aiff)
  • public.aifc-аудио (.aifc)
  • com.apple.coreaudio-format (.caf)

Если вы не возражаете против правильного перекодирования аудиоданных в другой формат, вам не нужно использовать предустановку AVAssetExportPresetPassthrough. Есть также AVAssetExportPresetLowQuality, AVAssetExportPresetMediumQuality и AVAssetExportPresetHighestQuality. В приведенном ниже примере кода выходной URL-адрес имеет расширение .m4a, а полученный результат перекодирования воспроизводится в iTunes и других медиаплеерах:

AVAsset * asset = [AVAsset assetWithURL:inputURL];
AVAssetExportSession * exportSession = [[AVAssetExportSession alloc] initWithAsset:asset presetName:AVAssetExportPresetHighestQuality];
exportSession.outputFileType = AVFileTypeMPEG4;
exportSession.outputURL = outputURL;
exportSession.metadata = asset.metadata;       
[exportSession exportAsynchronouslyWithCompletionHandler:^{

    if (exportSession.status == AVAssetExportSessionStatusCompleted)
    {
            NSLog(@"AV export succeeded.");
    }
    else if (exportSession.status == AVAssetExportSessionStatusCancelled)
    {
        NSLog(@"AV export cancelled.");
    }
    else
    {
        NSLog(@"AV export failed with error: %@ (%ld)", exportSession.error.localizedDescription, (long)exportSession.error.code);
    }
}];
person Dalmazio    schedule 17.09.2016
comment
Попробовал ваш подход. Я получаю mp3-файл, который воспроизводится в QuickTime, но не воспроизводится в iTunes и некоторых других проигрывателях. Вы знаете, как это исправить? - person iOS Dev; 07.10.2016
comment
Похоже, вы не можете сделать это с AVAssetExportPresetPassthrough. Я перекодирую в .m4a, но использую пресет AVAssetExportPresetLowQuality, который на самом деле конвертирует аудиоданные в другой формат, и он работает хорошо. Вы можете попробовать некоторые другие пресеты, включая AVAssetExportPresetMediumQuality и AVAssetExportPresetHighestQuality. Позвольте мне обновить мой ответ с некоторой дополнительной информацией. - person Dalmazio; 08.10.2016
comment
@Dalmazio Как по вашему опыту правильно конвертировать видео в mp3? - person Roi Mulia; 16.07.2017

Я попытался экспортировать аудиофайл в формате mp3 из библиотеки iPod. и это мое решение ниже.

extension DirectoryListViewController: MPMediaPickerControllerDelegate {
public func mediaPicker(_ mediaPicker: MPMediaPickerController, didPickMediaItems mediaItemCollection: MPMediaItemCollection) {
    guard let mediaItem = mediaItemCollection.items.first else { ImportExternalFileService.shared.alertImportError(); return  }
    guard let url = mediaItem.assetURL else { ImportExternalFileService.shared.alertImportError(); return }
    guard let songTitle = mediaItem.title else { ImportExternalFileService.shared.alertImportError(); return }
    guard let exportSession = AVAssetExportSession(asset: AVURLAsset(url: url), presetName: AVAssetExportPresetAppleM4A) else {
        ImportExternalFileService.shared.alertImportError(); return
    }
    exportSession.outputFileType = .m4a
    exportSession.metadata = AVURLAsset(url: url).metadata
    exportSession.shouldOptimizeForNetworkUse = true
    guard let fileExtension = UTTypeCopyPreferredTagWithClass(exportSession.outputFileType!.rawValue as CFString, kUTTagClassFilenameExtension) else {
        ImportExternalFileService.shared.alertImportError(); return
    }
    let documentURL = try! FileManager.default.url(for: .documentDirectory, in: .userDomainMask, appropriateFor: nil, create: true)
    let outputURL = documentURL.appendingPathComponent("\(songTitle).\(fileExtension.takeUnretainedValue())")
    /* Dont't forget to remove the existing url, or exportSession will throw error: can't save file */
    do {
        try FileManager.default.removeItem(at: outputURL)
    } catch let error as NSError {
        print(error.debugDescription)
    }
    exportSession.outputURL = outputURL
    exportSession.exportAsynchronously(completionHandler: {
        if exportSession.status == .completed {
            DispatchQueue.main.async {
                ImportExternalFileService.shared.importRecordFile(url: exportSession.outputURL!)
            }
        } else {
            print("AV export failed with error:- ", exportSession.error!.localizedDescription)
        }
    })
}

public func mediaPickerDidCancel(_ mediaPicker: MPMediaPickerController) {
    dismiss(animated: true, completion: nil)
}

}

person Levine Veblen    schedule 28.03.2019

Нельзя, но можно экспортировать m4a.

AVAssetExportSession *exportSession = [AVAssetExportSession exportSessionWithAsset:audioAsset presetName:AVAssetExportPresetAppleM4A];
exportSession.outputURL = [NSURL fileURLWithPath:exportPath];
exportSession.outputFileType = AVFileTypeAppleM4A;
[exportSession exportAsynchronouslyWithCompletionHandler:^{

}];
person guo.yi    schedule 14.04.2020