2012-04-16 7 views
6

Ich versuche, 4 Audiotracks zu einer einzigen Komposition zu kombinieren und diese Komposition dann in eine Datei zu exportieren. Bis jetzt wurde meine Datei erfolgreich erstellt, aber alle Audiospuren werden mit voller Lautstärke abgespielt, anstatt mit den Lautstärkepegeln, die ich einstellen möchte. Hier ist, was ich tue jetzt:Setzen von Track-Levels auf AVMutableComposition

AVMutableComposition *trackComposition = [AVMutableComposition composition]; 

AVAsset *asset1 = ... 
AVAsset *asset2 = ... 
AVAsset *asset3 = ... 
AVAsset *asset4 = ... 

NSMutableArray *inputParams = [NSMutableArray arrayWithCapacity:4]; 

// Add 4 tracks to composition (but only if there are no errors and the track isn't muted 
NSError *err; 
if(asset1 && ![self trackIsMuted:1]){ 
    AVAssetTrack *rawTrack = [[asset1 tracksWithMediaType:AVMediaTypeAudio] objectAtIndex:0]; 
    AVMutableCompositionTrack *compositionAudioTrack = [trackComposition addMutableTrackWithMediaType:AVMediaTypeAudio preferredTrackID:kCMPersistentTrackID_Invalid]; 
    [compositionAudioTrack insertTimeRange:CMTimeRangeMake(kCMTimeZero, [asset1 duration]) ofTrack:rawTrack atTime:kCMTimeZero error:&err]; 
    AVAudioMixInputParameters *audioParams = [self audioParamsForTrack:compositionAudioTrack volume:[self gainForTrack:1]]; 
    [inputParams addObject:audioParams]; 
} 
if(asset2 && !err && ![self trackIsMuted:2]){ 
    AVAssetTrack *rawTrack = [[asset2 tracksWithMediaType:AVMediaTypeAudio] objectAtIndex:0]; 
    AVMutableCompositionTrack *compositionAudioTrack = [trackComposition addMutableTrackWithMediaType:AVMediaTypeAudio preferredTrackID:kCMPersistentTrackID_Invalid]; 
    [compositionAudioTrack insertTimeRange:CMTimeRangeMake(kCMTimeZero, [asset2 duration]) ofTrack:rawTrack atTime:kCMTimeZero error:&err]; 
    AVAudioMixInputParameters *audioParams = [self audioParamsForTrack:compositionAudioTrack volume:[self gainForTrack:2]]; 
    [inputParams addObject:audioParams]; 
} 
if(asset3 && !err && ![self trackIsMuted:3]){ 
    AVAssetTrack *rawTrack = [[asset3 tracksWithMediaType:AVMediaTypeAudio] objectAtIndex:0]; 
    AVMutableCompositionTrack *compositionAudioTrack = [trackComposition addMutableTrackWithMediaType:AVMediaTypeAudio preferredTrackID:kCMPersistentTrackID_Invalid]; 
    [compositionAudioTrack insertTimeRange:CMTimeRangeMake(kCMTimeZero, [asset3 duration]) ofTrack:rawTrack atTime:kCMTimeZero error:&err]; 
    AVAudioMixInputParameters *audioParams = [self audioParamsForTrack:compositionAudioTrack volume:[self gainForTrack:3]]; 
    [inputParams addObject:audioParams]; 
} 
if(asset4 && !err && ![self trackIsMuted:4]){ 
    AVAssetTrack *rawTrack = [[asset4 tracksWithMediaType:AVMediaTypeAudio] objectAtIndex:0]; 
    AVMutableCompositionTrack *compositionAudioTrack = [trackComposition addMutableTrackWithMediaType:AVMediaTypeAudio preferredTrackID:kCMPersistentTrackID_Invalid]; 
    [compositionAudioTrack insertTimeRange:CMTimeRangeMake(kCMTimeZero, [asset4 duration]) ofTrack:rawTrack atTime:kCMTimeZero error:&err]; 
    AVAudioMixInputParameters *audioParams = [self audioParamsForTrack:compositionAudioTrack volume:[self gainForTrack:4]]; 
    [inputParams addObject:audioParams]; 
} 

AVMutableAudioMix *audioMix = [AVMutableAudioMix audioMix]; 
audioMix.inputParameters = inputParams; 

// Export the composition to a file 
AVAssetExportSession *export = [AVAssetExportSession exportSessionWithAsset:trackComposition presetName:AVAssetExportPresetAppleM4A]; 

NSURL *outputURL = [NSURL fileURLWithPath:[[NSTemporaryDirectory() stringByAppendingPathComponent:[NSString guidString]] stringByAppendingPathExtension:@"m4a"]]; 

[export setOutputURL:outputURL]; 
[export setOutputFileType:@"com.apple.m4a-audio"]; 

[export setAudioMix:audioMix]; 

[export exportAsynchronouslyWithCompletionHandler:^{ ... }]; 

Die einzige andere interessante Sache ist die audioParamsForTrack Methode, die hier:

- (AVAudioMixInputParameters *)audioParamsForTrack:(AVAssetTrack *)track volume:(float)vol{ 
    AVMutableAudioMixInputParameters *audioInputParams = [AVMutableAudioMixInputParameters audioMixInputParametersWithTrack:track]; 
    [audioInputParams setVolume:vol atTime:kCMTimeZero]; 

    return [audioInputParams copy]; 
} 

Kann jemand vor Ort, was ich falsch mache? Ich habe versucht, alle möglichen verschiedenen Spuren zu übertragen, um die Audioparameter zu erstellen, aber es scheint keinen Unterschied zu machen. Ich habe etwas über das bevorzugte Volumen einer Spur gesehen - ist das etwas, das mir helfen könnte? Ich bin an dieser Stelle ein bisschen fest, jede Rückmeldung wird geschätzt!

+0

dies auf Ihre Frage nicht unbedingt eine Antwort, aber die damit verbundene, können Sie einstellen, mehr mal auf einem einzelnen AVMutableAudioMixInputParameter-Objekt. Um also eine Rampe auf derselben Spur auf und ab zu setzen, müssen Sie diese Rampen auf dieselbe Parameterinstanz einstellen. Ich habe das zunächst nicht verstanden und dachte, ich müsste ein Parameter-Objekt pro Volumenrampe hinzufügen. – wbarksdale

Antwort

1

Beim Debuggen kann ich das Problem sehen, aber ich bin mir nicht sicher, warum es passiert.

Wenn Sie fügen Sie die params auf das Array, wie folgt aus:

[inputParams addObject:audioParams]; 

Der Track-ID wird auf 0 gesetzt, so dass es fügt nie zu einem Track:

der Konsole:

<AVMutableAudioMixInputParameters: 0x16eab300, track ID = 0, volume mix: volume 0.010 at time 0.000> 

Ich löste dies, indem ich die audioParamsForTrack Methode nicht verwendete, aber die Arbeit gerade vor dem Array tat, so:

NSMutableArray *inputParams = [NSMutableArray arrayWithCapacity:4]; 

      AVMutableAudioMixInputParameters *audioInputParams = [AVMutableAudioMixInputParameters audioMixInputParametersWithTrack:AudioTrack]; 
      [audioInputParams setVolume:.01f atTime:kCMTimeZero]; 

      AVAudioMixInputParameters *audioParams = audioInputParams; 
[inputParams addObject:audioParams]; 

      audioMix.inputParameters = inputParams; 
2

Ich hatte ein ähnliches Problem, aber was für mich gearbeitet wurde die Spur Id ausdrücklich auf den Eingabeparameter einstellen:

[audioInputParams setTrackID:compositionAudioTrack.trackID]; 
+1

Das hat den Trick für mich gemacht. Stellen Sie nur sicher, dass Sie die trackId von der KompositionAudioTrack aus setzen, NICHT das AVAssetTrack-Objekt, falls zutreffend. – manderson