2014-11-22 69 views
1

当我运行我的应用程序,然后单击保存按钮来保存混合在一起的两个文件我的应用程序崩溃说无效的文件输出。我不明白为什么这个错误出现,因为两个文件混合是MP3和输出文件是MP3。无效的文件输出AVAssetExport

代码:

@IBAction func mixButton (sender:AnyObject!) { 
     let oldAsset = self.player.currentItem.asset 

     let type = AVMediaTypeAudio 
     let audioFile = NSBundle.mainBundle().URLForResource("file1", withExtension: "mp3") 
     let asset1 = AVURLAsset(URL: audioFile, options: nil) 
     let arr2 = asset1.tracksWithMediaType(type) 
     let track2 = arr2.last as AVAssetTrack 

     let duration : CMTime = track2.timeRange.duration 

     let comp = AVMutableComposition() 
     let comptrack = comp.addMutableTrackWithMediaType(type, 
      preferredTrackID: Int32(kCMPersistentTrackID_Invalid)) 

     comptrack.insertTimeRange(CMTimeRangeMake(CMTimeMakeWithSeconds(0,600), CMTimeMakeWithSeconds(5,600)), ofTrack:track2, atTime:CMTimeMakeWithSeconds(0,600), error:nil) 
     comptrack.insertTimeRange(CMTimeRangeMake(CMTimeSubtract(duration, CMTimeMakeWithSeconds(5,600)), CMTimeMakeWithSeconds(5,600)), ofTrack:track2, atTime:CMTimeMakeWithSeconds(5,600), error:nil) 



     let type3 = AVMediaTypeAudio 
     let s = NSBundle.mainBundle().URLForResource("file2", withExtension:"mp3") 
     let asset = AVURLAsset(URL:s, options:nil) 
     let arr3 = asset.tracksWithMediaType(type3) 
     let track3 = arr3.last as AVAssetTrack 

     let comptrack3 = comp.addMutableTrackWithMediaType(type3, preferredTrackID:Int32(kCMPersistentTrackID_Invalid)) 
     comptrack3.insertTimeRange(CMTimeRangeMake(CMTimeMakeWithSeconds(0,600), CMTimeMakeWithSeconds(10,600)), ofTrack:track3, atTime:CMTimeMakeWithSeconds(0,600), error:nil) 



     let params = AVMutableAudioMixInputParameters(track:comptrack3) 
     params.setVolume(1, atTime:CMTimeMakeWithSeconds(0,600)) 
     params.setVolumeRampFromStartVolume(1, toEndVolume:0, timeRange:CMTimeRangeMake(CMTimeMakeWithSeconds(7,600), CMTimeMakeWithSeconds(3,600))) 
     let mix = AVMutableAudioMix() 
     mix.inputParameters = [params] 

     let item = AVPlayerItem(asset:comp) 
     item.audioMix = mix 
     mixedFile = comp //global variable for mixed file 

}}

@IBAction func saveButton(sender: AnyObject) { 
    let documentsPath = NSSearchPathForDirectoriesInDomains(.DocumentDirectory, .UserDomainMask, true)[0] as String 
    let savedFileTest = documentsPath + "/myfile.mp3" 
    if (NSFileManager.defaultManager().fileExistsAtPath(savedFileTest)) { 
     NSFileManager.defaultManager().removeItemAtPath(savedFileTest, error: nil) 
    } 

    let url = NSURL.fileURLWithPath(savedFileTest) 

    let exporter = AVAssetExportSession(asset: mixedFile, presetName: AVAssetExportPresetHighestQuality) 
    exporter.outputURL = url 
    exporter.outputFileType = AVFileTypeMPEGLayer3 

    exporter.exportAsynchronouslyWithCompletionHandler({ 
     switch exporter.status{ 
     case AVAssetExportSessionStatus.Failed: 
      println("failed \(exporter.error)") 
     case AVAssetExportSessionStatus.Cancelled: 
      println("cancelled \(exporter.error)") 
     default: 
      println("complete") 
     } 

回答

1

输出文件是 MP3。你可以 mp3,但这并不是一个。我不认为苹果框架代码可以将另存为mp3。它可以读取它,但由于各种许可问题,无法编写它。

做它作为一个M4A,像这样(我出演,我从你的原始代码更改的行):

let savedFileTest = documentsPath + "/myfile.m4a" // * 
if (NSFileManager.defaultManager().fileExistsAtPath(savedFileTest)) { 
    NSFileManager.defaultManager().removeItemAtPath(savedFileTest, error: nil) 
} 
let url = NSURL.fileURLWithPath(savedFileTest) 
let exporter = AVAssetExportSession(
    asset: mixedFile, presetName: AVAssetExportPresetAppleM4A) // * 
exporter.outputURL = url 
exporter.outputFileType = AVFileTypeAppleM4A // * 

,那你保存错误的东西(非混合式comp而不是方法混合item)。

+0

谢谢!那么我如何获得混合物品呢? – tryingtolearn 2014-11-23 01:24:35

+0

我已经回答了。看看我说的。看看你自己的代码。 – matt 2014-11-23 01:38:02

+0

但我想获得输出文件在MP3合成器,然后我能做什么? – ABJ 2016-12-10 11:47:07

-2

您可以将其导出到“AVFileTypeQuickTimeMovie”并将其重命名为* .mp3。

初始化导出,在这里您必须将“presentName”参数设置为“AVAssetExportPresetPassthrough”。如果没有,您将无法导出mp3正确。

AVAssetExportSession *export = [[AVAssetExportSession alloc] initWithAsset:sset presetName:AVAssetExportPresetPassthrough]; 

设置输出继电器类型:

exportSession.outputFileType = AVFileTypeQuickTimeMovie; 
exportSession.shouldOptimizeForNetworkUse = true; 

出口,并设置文件扩展名 “MP3”。

+1

我试试这个,我得到AVAssetExportSessionStatusFailed:错误域= AVFoundationErrorDomain代码= -11843“无法写输出文件”UserInfo = {NSLocalizedRecoverySuggestion =更改输出扩展名,然后再试一次,NSLocalizedDescription =无法写输出文件} – fechidal89 2016-07-05 04:47:18