不同音量的 Avfoundation 混合音频不起作用
Avfoundation mix audios with different volumes doesn't not work
我想通过 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:^{
}];
有人能帮忙吗?谢谢
我找到了解决办法。 AudioMixInputParameters 必须采用 CompositionTrack 的轨道 ID,而不是 AVAssetTrack
我想通过 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:^{
}];
有人能帮忙吗?谢谢
我找到了解决办法。 AudioMixInputParameters 必须采用 CompositionTrack 的轨道 ID,而不是 AVAssetTrack