繁体   English   中英

如何使用 AVAssetExportSession 导出 AVPlayer 音频 mp3 文件?

[英]How can I export a AVPlayer audio mp3 file using AVAssetExportSession?

我现在正在尝试导出使用 AVPlayer(使用 url)播放的 mp3 文件,因此不必下载两次。

这是我的示例代码:

我已经尝试了每个 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 的理想类型是什么?

看起来AVAssetExportSession只支持使用AVAssetExportPresetPassthrough预设的com.apple.quicktime-movie (.mov) 和com.apple.coreaudio-format (.caf) 的 mp3 转码文件类型。 在编写输出文件时,您还必须确保使用这些文件扩展名之一,否则将无法保存。

mp3 输入文件支持的输出文件类型和扩展名以粗体显示(在 OS X 10.11.6 上测试):

  • com.apple.quicktime-电影 (.mov)
  • com.apple.m4a-音频 (.m4a)
  • public.mpeg-4 (.mp4)
  • com.apple.m4v-视频 (.m4v)
  • org.3gpp.adaptive-multi-rate-audio (.amr)
  • com.microsoft.waveform-audio (.wav)
  • public.aiff-audio (.aiff)
  • public.aifc-音频 (.aifc)
  • com.apple.coreaudio 格式 (.caf)

如果您不介意将音频数据正确转码为另一种格式,那么您不必使用AVAssetExportPresetPassthrough预设。 还有AVAssetExportPresetLowQualityAVAssetExportPresetMediumQualityAVAssetExportPresetHighestQuality 在下面的示例代码中,输出 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);
    }
}];

我试图从 ipod 库中导出 mp3 格式的音频文件。 这是我下面的解决方案。

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)
}

}

你不能,但你可以导出 m4a。

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

}];

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM