工作中或许会遇到这样的需求,将两段不同的音频合成一个音频(暂且称之为音频拼接),实现起来相对来说不是很难,再介绍如何拼接之前,先了解下AVFoundation下的几个基本知识点。

基本知识

AVAsset

正如官网文档所说——”AVAsset is an abstract class to represent timed audiovisual media such as videos and sounds. Each asset contains a collection of tracks that are intended to be presented or processed together, each of a uniform media type, including but not limited to audio, video, text, closed captions, and subtitles”.大致意思就是说AVAsset是AVFoundation中的一个抽象类,用来代表多媒体资源,比如,音频,视频等。

AVURLAsset

AVURLAsset是AVAsset的子类,是一个具体类,用URL来进行初始化。

AVMutableComposition

AVMutableComposition结合了媒体数据,可以看成是track(音频轨道)的集合,用来合成音视频。

AVMutableCompositionTrack

AVMutableCompositionTrack用来表示一个track,包含了媒体类型、音轨标识符等信息,可以插入、删除、缩放track片段。

AVAssetTrack

AVAssetTrack表示素材轨道。

AVAssetExportSession

AVAssetExportSession用来对一个AVAsset源对象进行转码,并导出为事先设置好的格式。

音频拼接

介绍完基本知识,接下来就介绍下如何实现音频拼接。
1、首先,获取本地的两个音频素材(一首五环之歌和iPhone的默认通知提示音):

    NSString *auidoPath1 = [[NSBundle mainBundle] pathForResource:@"三全音" ofType:@"mp3"];    NSString *audioPath2 = [[NSBundle mainBundle] pathForResource:@"五环之歌" ofType:@"mp3"];    AVURLAsset *audioAsset1 = [AVURLAsset assetWithURL:[NSURL fileURLWithPath:auidoPath1]];    AVURLAsset *audioAsset2 = [AVURLAsset assetWithURL:[NSURL fileURLWithPath:audioPath2]];

2、接下来就是创建两个音频轨道,并获取工程中两个音频素材的轨道:

    AVMutableComposition *composition = [AVMutableComposition composition];    // 音频轨道
    AVMutableCompositionTrack *audioTrack1 = [composition addMutableTrackWithMediaType:AVMediaTypeAudio preferredTrackID:0];    AVMutableCompositionTrack *audioTrack2 = [composition addMutableTrackWithMediaType:AVMediaTypeAudio preferredTrackID:0];    // 音频素材轨道
    AVAssetTrack *audioAssetTrack1 = [[audioAsset1 tracksWithMediaType:AVMediaTypeAudio] firstObject];    AVAssetTrack *audioAssetTrack2 = [[audioAsset2 tracksWithMediaType:AVMediaTypeAudio] firstObject];

3、将两段音频插入音轨文件进行合并:

    // 音频合并 - 插入音轨文件
    [audioTrack1 insertTimeRange:CMTimeRangeMake(kCMTimeZero, audioAsset1.duration) ofTrack:audioAssetTrack1 atTime:kCMTimeZero error:nil];
    [audioTrack2 insertTimeRange:CMTimeRangeMake(kCMTimeZero, audioAsset2.duration) ofTrack:audioAssetTrack2 atTime:kCMTimeZero error:nil];

4、最后就是用AVAssetExportSession导出合并后音频文件:

    // 合并后的文件导出 - 音频文件目前只找到合成m4a类型的
    AVAssetExportSession *session = [[AVAssetExportSession alloc] initWithAsset:composition presetName:AVAssetExportPresetAppleM4A];    NSString *outPutFilePath = [[self.filePath stringByDeletingLastPathComponent] stringByAppendingPathComponent:@"xindong.m4a"];
    session.outputURL = [NSURL fileURLWithPath:outPutFilePath];
    session.outputFileType = AVFileTypeAppleM4A;
    [session exportAsynchronouslyWithCompletionHandler:^{        NSLog(@"合并完成----%@", outPutFilePath);
        _player = [[AVAudioPlayer alloc] initWithContentsOfURL:[NSURL fileURLWithPath:outPutFilePath] error:nil];
        [_player play];
    }];

对于音频文件的合成导出类型,目前只找到支持.m4a格式的(不知道是否支持其他类型)。对于导出文件所支持的类型可以通过[session supportedFileTypes]进行查看。demo链接…