具有不同音量的Avfoundation混合音频不起作用

问题描述 投票:3回答:1

我想通过AVAssetExportSession将视频(mp4文件)和音频(mp3文件)合并为不同的卷。例如,视频中的音频音量可能为1,而其他音频的音量可能为0.5作为背景音乐。然而,似乎[AVMutableAudioMixInputParameters setVolume][AVMutableAudioMixInputParameters setVolumeRampFromStartVolume]不起作用。输出文件中的音乐音量似乎没有降低。

代码如下所示

AVMutableComposition *mixComposition = [[AVMutableComposition alloc] init];
// add a video track
AVMutableCompositionTrack *videoTrack = [mixComposition addMutableTrackWithMediaType:AVMediaTypeVideo preferredTrackID:kCMPersistentTrackID_Invalid];
[videoTrack insertTimeRange:CMTimeRangeMake(kCMTimeZero,videoAsset.duration) ofTrack:[[videoAsset tracksWithMediaType:AVMediaTypeVideo] objectAtIndex:0] atTime:kCMTimeZero error:nil];

AVMutableAudioMix *audioMix = [AVMutableAudioMix audioMix];
NSMutableArray *audioMixParams = [[NSMutableArray alloc]init];

NSError *error;

if (musicPath && mVolume > 0) {
    // add a music track
    AVMutableCompositionTrack *audioTrack = [mixComposition addMutableTrackWithMediaType:AVMediaTypeAudio preferredTrackID:kCMPersistentTrackID_Invalid];

    AVURLAsset *musicAsset = [AVURLAsset URLAssetWithURL:[NSURL fileURLWithPath:musicPath] options:nil];
    if ([[musicAsset tracksWithMediaType:AVMediaTypeAudio] count] <= 0) {
        [self.logger error:@"music file error : ", musicPath];
        handler(NO);
        return;
    }
    AVAssetTrack *musicAudioTrack = [[musicAsset tracksWithMediaType:AVMediaTypeAudio] objectAtIndex:0];
    AVMutableAudioMixInputParameters *musicParam = [AVMutableAudioMixInputParameters audioMixInputParameters];
    musicParam.trackID = musicAudioTrack.trackID;
    [self.logger debug:@"merge video and music : set music source volume -> %f", mVolume];
    // set music's volume
    [musicParam setVolumeRampFromStartVolume:mVolume toEndVolume:mVolume timeRange:CMTimeRangeMake(kCMTimeZero, videoAsset.duration)];
    // add param to mix
    [audioMixParams addObject:musicParam];

    [audioTrack insertTimeRange:CMTimeRangeMake(kCMTimeZero, videoAsset.duration) ofTrack:musicAudioTrack atTime:kCMTimeZero error:&error];
    if (error) {
        [self.logger error:@"Error when insert audio track of music file : %@", error.description];
    }
}

if ([[videoAsset tracksWithMediaType:AVMediaTypeAudio] count] && vVolume > 0) {
    // add video sound track
    AVMutableCompositionTrack *videoAudioTrack = [mixComposition addMutableTrackWithMediaType:AVMediaTypeAudio preferredTrackID:kCMPersistentTrackID_Invalid];
    AVAssetTrack * sourceAudioTrack = [[videoAsset tracksWithMediaType:AVMediaTypeAudio] objectAtIndex:0];
    AVMutableAudioMixInputParameters *videoParam = [AVMutableAudioMixInputParameters audioMixInputParameters];
    videoParam.trackID = sourceAudioTrack.trackID;
    [self.logger debug:@"merge video and music : set video source volume -> %f", vVolume];
    // set video's audio volume
    [videoParam setVolumeRampFromStartVolume:vVolume toEndVolume:vVolume timeRange:CMTimeRangeMake(kCMTimeZero, videoAsset.duration)];
    // add param to mix
    [audioMixParams addObject:videoParam];

    [videoAudioTrack insertTimeRange:CMTimeRangeMake(kCMTimeZero, videoAsset.duration) ofTrack:sourceAudioTrack atTime:kCMTimeZero error:&error];
    if (error) {
        [self.logger error:@"Error when insert audio track of video file : %@", error.description];
    }
}

// merge
audioMix.inputParameters = [NSArray arrayWithArray:audioMixParams];

AVAssetExportSession *exporter = [[AVAssetExportSession alloc] initWithAsset:mixComposition presetName:AVAssetExportPresetHighestQuality];
exporter.outputURL= [NSURL fileURLWithPath:outputPath];
exporter.outputFileType = AVFileTypeMPEG4;
exporter.shouldOptimizeForNetworkUse = YES;
exporter.audioMix = audioMix;
exporter.timeRange = CMTimeRangeMake(kCMTimeZero, videoAsset.duration);
[exporter exportAsynchronouslyWithCompletionHandler:^{
}];

有人可以帮忙吗?谢谢

ios avfoundation avassetexportsession
1个回答
0
投票

我找到了解决方案。 AudioMixInputParameters必须获取CompositionTrack的轨道ID,而不是AVAssetTrack的轨道ID

© www.soinside.com 2019 - 2024. All rights reserved.