2014-01-30 5 views
10

Ich versuche, einige Audiodateien mit der gezeigten Technik here zu verketten. Meine Audiodateien sind .m4a und ich kann bestätigen, dass sie in Quicktime gut wiedergegeben werden. Hier ist der Code, den ich verwenden werde versuchen, sie zu verketten:Cocoa: AVAsset geladen von Datei hat 0 Spuren

[currFile.audioContent writeToFile:tempOldFilePath atomically:NO]; 

    AVURLAsset *oldAudioAsset = [AVURLAsset URLAssetWithURL:[NSURL URLWithString:tempOldFilePath] options:nil]; 
    AVURLAsset *newAudioAsset = [AVURLAsset URLAssetWithURL:[NSURL URLWithString:tempInputFilePath] options:nil]; 

    NSLog(@"oldAsset num tracks = %lu",(unsigned long)oldAudioAsset.tracks.count); 
    NSLog(@"newAsset num tracks = %lu",(unsigned long)newAudioAsset.tracks.count); 
    AVAssetTrack *oldTrack = [[oldAudioAsset tracksWithMediaType:AVMediaTypeAudio] objectAtIndex:0]; 
    AVAssetTrack *newTrack = [[newAudioAsset tracksWithMediaType:AVMediaTypeAudio] objectAtIndex:0]; 

    AVMutableComposition *mutableComposition = [AVMutableComposition composition]; 

    AVMutableCompositionTrack *compTrack = [mutableComposition addMutableTrackWithMediaType:AVMediaTypeAudio preferredTrackID:kCMPersistentTrackID_Invalid]; 

    NSError *error=nil; 
    [compTrack insertTimeRange:CMTimeRangeMake(kCMTimeZero, oldTrack.timeRange.duration) ofTrack:oldTrack atTime:kCMTimeZero error:&error]; 
    if (error) { 
     NSLog(@"%@",error.localizedDescription); 
     error=nil; 
    } 
    [compTrack insertTimeRange:CMTimeRangeMake(kCMTimeZero, newTrack.timeRange.duration) ofTrack:newTrack 
         atTime:oldTrack.timeRange.duration error:&error]; 

    if (error) { 
     NSLog(@"%@",error.localizedDescription); 
     error=nil; 
    } 

    exporter = [[AVAssetExportSession alloc] initWithAsset:mutableComposition presetName:AVAssetExportPresetAppleM4A]; 


    exporter.outputURL = [NSURL URLWithString:tempCompFilePath]; 

    exporter.outputFileType = AVFileTypeAppleM4A; 

    [exporter exportAsynchronouslyWithCompletionHandler:^{ 
     NSLog(@"handller"); 
     NSError *error=nil; 
     NSData *newData = [NSData dataWithContentsOfFile:tempCompFilePath options:0 error:&error]; 
     NSLog(@"%lu",(unsigned long)newData.length); 
     if (error) { 
      NSLog(@"%@",error.localizedDescription); 
     } 

     currFile.audioContent = newData; 
     [[AppDelegate sharedDelegate] saveAction:nil]; 

    }]; 

Das erste Problem, das ich bemerkt, ist, dass die Behandlungsmethode des Exporteurs nie aufgerufen. Ich vermute, der Grund dafür ist das andere Problem, das mir aufgefallen ist: Nachdem ich meine AVAssets von URL erstellt habe, zeigen Log-Statements, dass sie 0 Tracks enthalten. Apples Beispiel zeigt nicht genau, wie die AVAssets geladen sind.

Irgendwelche Ratschläge, wie man das funktioniert?

+0

In welcher OS X-Version versuchen Sie dies? –

Antwort

17

Wie Sie bereits festgestellt haben, müssen Sie fileURLWithPath:, nicht URLWithString: verwenden, um Ihre URLs zu erstellen.

URLWithString: erwartet eine Zeichenfolge, die eine URL beschreibt, z. B. @"file:///path/to/file" oder . Wenn Ihre Zeichenfolge nur einen Pfad beschreibt, z. B. @"/path/to/file", müssen Sie fileURLWithPath: verwenden, wodurch die fehlenden Teile korrekt ausgefüllt werden.

Technisch, URLWithString: einen Weg einfach als eine URL interpretiert mit nur einem Pfad aber kein bestimmten Schema, die Sie verwenden in Bezug auf eine Basis-URL in jedem dateiorientierten Schema, wie HTTP gehen könnten (GET /path/to/file). fileURLWithPath: interpretiert einen Pfad als lokalen Dateipfad und gibt eine file: URL entsprechend zurück.

4

Anscheinend habe ich die falsche NSURL-Methode verwendet. Ich änderte es zu diesem:

AVURLAsset *oldAudioAsset = [AVURLAsset URLAssetWithURL:[NSURL fileURLWithPath:tempOldFilePath] options:nil]; 

Jetzt haben meine AVAssets jede 1 Spur in ihnen. Wenn jemand eine gute Erklärung dafür geben kann, warum dies notwendig ist, werde ich diese Antwort akzeptieren.

5

Ich fand den Grund, warum dieser Fehler aufgetreten ist und schließlich lösen.

Ursprünglich hatte ich den Quelldateipfad als ".mp4" festgelegt. Aber die Art der aufgenommenen Videodatei war MOV, also habe ich als " .mov" geändert.

NSString *source_file_path = @"temp_video.mov" 

statt

NSString *source_file_path = @"temp_video.mp4" 

Das Problem wurde behoben und es funktioniert jetzt gut.

Hoffen, für alle hilfreich zu sein.

Verwandte Themen