2

我正在尝试将一堆视频拼接在一起,然后在 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不会混合到导出的文件中。知道发生了什么吗?

4

1 回答 1

3

您尚未将 .caf 文件中的音频插入到 anyAVMutableCompositionTrack中,因此与之关联的音频混合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 *(而不是nilinsertTimeRange:ofTrack:atTime:error有助于确保您有有效的时间范围并插入了您的媒体。

于 2013-10-10T14:02:14.707 回答