Reputation: 4604
I have 2 WAV files (mono) I would like to merge.
I want to merge them into a stereo WAV file where the first file will use the left channel while the second file will use the right channel (if possible, I would also like to control the volume and lower the second file a bit).
I've tried to use AVAssetReaderAudioMixOutput, but got the following error:
[AVAssetReaderAudioMixOutput initWithAudioTracks:audioSettings:] tracks must all be part of the same AVAsset
I'm not sure how to merge 2 different files.
AVAssetReaderOutput* reader=[AVAssetReaderAudioMixOutput assetReaderAudioMixOutputWithAudioTracks:[NSArray arrayWithObjects:
[[AVURLAsset URLAssetWithURL:[NSURL fileURLWithPath:[documentDirectory stringByAppendingPathComponent:@"left.wav"]] options:nil].tracks lastObject],
[[AVURLAsset URLAssetWithURL:[NSURL fileURLWithPath:[documentDirectory stringByAppendingPathComponent:@"right.wav"]] options:nil].tracks lastObject],
nil] audioSettings:nil];
Upvotes: 2
Views: 548
Reputation: 373
Use AVMutableComposition
, which is a subclass of AVAsset
.
Example:
AVURLAsset *asset1 = [AVURLAsset assetWithURL:audioURL1];
AVURLAsset *asset2 = [AVURLAsset assetWithURL:audioURL2];
AVMutableComposition *composition = [AVMutableComposition composition];
AVMutableCompositionTrack *compositionTrack1 =
[composition addMutableTrackWithMediaType:AVMediaTypeAudio preferredTrackID:kCMPersistentTrackID_Invalid];
AVMutableCompositionTrack *compositionTrack2 =
[composition addMutableTrackWithMediaType:AVMediaTypeAudio preferredTrackID:kCMPersistentTrackID_Invalid];
NSArray<AVAssetTrack *> *assetTracks1 = [asset1 tracksWithMediaType:AVMediaTypeAudio];
NSArray<AVAssetTrack *> *assetTracks2 = [asset2 tracksWithMediaType:AVMediaTypeAudio];
AVAssetTrack *assetTrack1 = [assetTracks1 firstObject];
AVAssetTrack *assetTrack2 = [assetTracks2 firstObject];
[compositionTrack1 insertTimeRange:CMTimeRangeMake(kCMTimeZero, asset1.duration)
ofTrack:assetTrack1
atTime:kCMTimeZero
error:error];
[compositionTrack2 insertTimeRange:CMTimeRangeMake(kCMTimeZero, asset2.duration)
ofTrack:assetTrack2
atTime:kCMTimeZero
error:error];
// Now `compositionTrack1` and `compositionTrack2` are from the same `AVAsset`.
AVAssetReaderAudioMixOutput *mixOutput = [AVAssetReaderAudioMixOutput
assetReaderAudioMixOutputWithAudioTracks:@[ compositionTrack1, compositionTrack2 ]
audioSettings:processingSettings];
Upvotes: 0