Marco
Marco

Reputation: 1077

iOS - change volume for each AVAssetTrack

I have some audio files that I need to insert in an AVMutableComposition. Each audio have a different volume. To accomplish that I created an AVMutableTrackComposition and an AVAssetTrack for each audio file. So I change the volume for every track using an instance of AVMutableAudioMix.

let composition = AVMutableComposition()
var trackMixArray = NSMutableArray()

for audio in layer{
   let trackAudio:AVMutableCompositionTrack = composition.addMutableTrackWithMediaType(AVMediaTypeAudio, preferredTrackID: CMPersistentTrackID())

   let file = project.stringByAppendingPathComponent(audio.name)
   let soundAsset = AVURLAsset(URL: NSURL(fileURLWithPath: file), options: option as [NSObject : AnyObject])
   let sounds = soundAsset.tracksWithMediaType(AVMediaTypeAudio)
   var sound:AVAssetTrack = sounds[0] as! AVAssetTrack
   let duration:CMTime = sound.timeRange.duration

   let audioTimeRange:CMTimeRange = CMTimeRangeFromTimeToTime(kCMTimeZero, duration)
   let start:CMTime = CMTimeMakeWithSeconds(audio.start.toDouble()!, 600)
   let stop:CMTime = CMTimeMakeWithSeconds(audio.stop.toDouble()!, 600)

   let trackMix = AVMutableAudioMixInputParameters(track: trackAudio)
   trackMix.setVolume(audio.volume, atTime: kCMTimeZero)
   trackMixArray.addObject(trackMix)

   trackAudio.insertTimeRange(audioTimeRange, ofTrack: sound, atTime: start, error: nil)
 }

let audioMix = AVMutableAudioMix()
audioMix.inputParameters = trackMixArray as [AnyObject]

Using a single AVMutableCompositionTrack with more AVAssetTrack associated to it doesn't allow me to change the volume for each track.

 let trackMix = AVMutableAudioMixInputParameters(track: sound)
 trackMix.setVolume(audio.volume, atTime: kCMTimeZero)
 trackMixArray.addObject(trackMix)

It's possible to change the volume directly from the AVAssetTrack?

Upvotes: 4

Views: 3276

Answers (1)

DimaC
DimaC

Reputation: 436

    AVMutableComposition *collageComposition = [[AVMutableComposition alloc]init];
        ...
        Some Magic
        ...
    NSArray *tracksToDuck = [collageComposition tracksWithMediaType:AVMediaTypeAudio];
            audioMix = [AVMutableAudioMix audioMix];
            NSMutableArray *trackMixArray = [NSMutableArray array];
            for (int i = 0; i < [tracksToDuck count]; i++) {
                AVMutableAudioMixInputParameters *trackMix = [AVMutableAudioMixInputParameters audioMixInputParametersWithTrack:[tracksToDuck objectAtIndex:i]];
                        [trackMix setVolume:volume atTime:kCMTimeZero];
                [trackMixArray addObject:trackMix];
            }
            audioMix.inputParameters = trackMixArray;

    ... 
    AVAssetExportSession Magic
    ...
    generalExporter = [[AVAssetExportSession alloc] initWith...
    generalExporter.audioMix = audioMix;

This should help you to change volume in each track, just change it to swift.

EDIT: each AVMutableCompositionTrack have segments, each segment have startTime and duration, you can use AVMutableAudioMixInputParameters to change volume for each CMTimeRange

 - (void)setVolumeRampFromStartVolume:(float)startVolume
                         toEndVolume:(float)endVolume
                           timeRange:(CMTimeRange)timeRange

Upvotes: 1

Related Questions