2014-11-22 70 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