Микширование звука в iOS с использованием AVFoundation не работает

Я пытаюсь соединить кучу видео вместе, а затем добавить музыку поверх видео в iOS. Звук добавляется с помощью AVMutableAudioMix. Однако, когда видео, наконец, экспортируется, звуковой микс отсутствует. Вот как выглядит код:

- (void)mergeVideos:(NSArray *)videos{
    AVMutableComposition *mixComposition = [[AVMutableComposition alloc] init];
    AVMutableCompositionTrack *videoTrack = [mixComposition addMutableTrackWithMediaType:AVMediaTypeVideo
                                                                        preferredTrackID:kCMPersistentTrackID_Invalid];
    AVMutableCompositionTrack *audioTrack = [mixComposition addMutableTrackWithMediaType:AVMediaTypeAudio
                                                                        preferredTrackID:kCMPersistentTrackID_Invalid];
    CMTime currentTime = kCMTimeZero;
    for (AVAsset *asset in videos) {
        // 2 - Video track
        [videoTrack insertTimeRange:CMTimeRangeMake(kCMTimeZero, asset.duration)
                            ofTrack:[[asset tracksWithMediaType:AVMediaTypeVideo] objectAtIndex:0] atTime:currentTime error:nil];
        [audioTrack insertTimeRange:CMTimeRangeMake(kCMTimeZero, asset.duration)
                            ofTrack:[[asset tracksWithMediaType:AVMediaTypeAudio] objectAtIndex:0] atTime:currentTime error:nil];
        currentTime = CMTimeAdd(currentTime, asset.duration);
    }
        // 4 - Get path
    NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
    NSString *documentsDirectory = [paths objectAtIndex:0];
    NSString *myPathDocs =  [documentsDirectory stringByAppendingPathComponent:
                             [NSString stringWithFormat:@"mergeVideo-%d.mp4",arc4random() % 1000]];
    NSURL *url = [NSURL fileURLWithPath:myPathDocs]; 
    // 5 - Create exporter
    NSArray *compatiblePresets = [AVAssetExportSession exportPresetsCompatibleWithAsset:mixComposition];
    NSString *quality = AVAssetExportPresetHighestQuality;
    //load the audio
    AVMutableAudioMix *audioMix = nil;
    NSURL *audioURL = [self loadAudioFile];// gives a url for a .caf file from the bundle
    if (audioURL) {
        AVURLAsset *audioAsset = [AVURLAsset assetWithURL:audioURL];
        AVAssetTrack *aTrack =  (AVAssetTrack *)[[audioAsset tracksWithMediaType:AVMediaTypeAudio] firstObject];

        AVMutableAudioMixInputParameters *trackMix =
        [AVMutableAudioMixInputParameters audioMixInputParametersWithTrack:aTrack];

        [trackMix setVolumeRampFromStartVolume:0 toEndVolume:1 timeRange:
         CMTimeRangeMake(CMTimeMakeWithSeconds(0, 1), CMTimeMakeWithSeconds(3, 1))];
        [trackMix setVolume:1.0 atTime:kCMTimeZero];
        AVMutableAudioMix *audioMix = [AVMutableAudioMix audioMix];
        audioMix.inputParameters = [NSArray arrayWithObject:trackMix];
    }

    AVAssetExportSession *exporter = [[AVAssetExportSession alloc] initWithAsset:mixComposition
                                                                      presetName:quality];
    if (audioMix) {
        exporter.audioMix = audioMix;
    }
    exporter.outputURL=url;
    exporter.outputFileType = AVFileTypeMPEG4;
    exporter.shouldOptimizeForNetworkUse = YES;
    [exporter exportAsynchronouslyWithCompletionHandler:^{
        dispatch_async(dispatch_get_main_queue(), ^{
            [self exportDidFinish:exporter];
        });
    }];
}

При выполнении ошибки нет. Просто музыка, содержащаяся в файле .caf, не смешивается с экспортируемым файлом. Есть идеи, что происходит?


person aqs    schedule 07.08.2013    source источник


Ответы (1)


Вы не вставили звук из файла .caf ни в один файл AVMutableCompositionTrack, поэтому аудиомикс, связанный с файлом aTrack, не будет регулировать громкость файла .caf. Если вы хотите, чтобы звук из файла .caf был включен в видео вместе с соответствующим звуковым миксом, создайте еще один AVMutableCompositionTrack для хранения звука из файла .caf:

AVMutableCompositionTrack *audioTrackCAF = [mixComposition addMutableTrackWithMediaType:AVMediaTypeAudio
                                                                    preferredTrackID:kCMPersistentTrackID_Invalid];

(с временными диапазонами, установленными по вашему вкусу):

[audioTrackCAF insertTimeRange:CMTimeRangeMake(kCMTimeZero, audioAsset.duration)
                            ofTrack:aTrack atTime:kCMTimeZero error:nil]

Кроме того, полезно передать NSError * (вместо nil) в insertTimeRange:ofTrack:atTime:error, чтобы убедиться, что у вас есть допустимые диапазоны времени и ваш носитель был вставлен.

person jlw    schedule 10.10.2013