iOS音频合并

最近遇到一个需求,客户录音试听一下可以,就继续向下录制,当客户录制完成后,需要把前面录制的试听音频和后面的音频进行合并.
最初想到的方法,使用NSData对两个音频文件进行合并,但是合并后,音频文件确实变大了,但是只能播放第一个音频. 这应该怎么办呢?

其实AVFoundation框架提供音视频剪辑,合成等功能. 我在这里仅仅介绍下音频合并,希望能起到抛砖引玉的效果.
这里需要使用到三个核心类
AVMutableComposition: 用于对音视频轨道的添加和删除
AVMutableCompositionTrack: 代表着一个音频/视频 的轨道,可以添加音频/视频资源
AVAssetExportSession:用于导出处理后的音视频文件.

步骤

  1. 创建AVMutableComposition
  2. AVMutableComposition 添加一个新音频的轨道,并返回音频轨道
  3. 循环添加需要的音频资源
  4. 导出合并的音频文件
代码
//
// HMAudioComposition.m
// HMAVAudoTools
//
// Created by 传智.小飞燕 on 16/7/25.
// Copyright © 2016年 itheima. All rights reserved. #import "HMAudioComposition.h"
#import <AVFoundation/AVFoundation.h> @implementation HMAudioComposition /// 合并音频文件
/// @param sourceURLs 需要合并的多个音频文件
/// @param toURL 合并后音频文件的存放地址
/// 注意:导出的文件是:m4a格式的.
+ (void) sourceURLs:(NSArray *) sourceURLs composeToURL:(NSURL *) toURL completed:(void (^)(NSError *error)) completed{ NSAssert(sourceURLs.count > 1,@"源文件不足两个无需合并"); // 1. 创建`AVMutableComposition `,用于合并所有的音视频文件
AVMutableComposition* mixComposition = [AVMutableComposition composition]; // 2. 给`AVMutableComposition` 添加一个新音频的轨道,并返回音频轨道
AVMutableCompositionTrack *compositionAudioTrack = [mixComposition addMutableTrackWithMediaType:AVMediaTypeAudio preferredTrackID:kCMPersistentTrackID_Invalid];
// 3. 循环添加需要的音频资源 // 3.1 音频插入的开始时间,用于记录每次添加音频文件的开始时间
CMTime beginTime = kCMTimeZero;
// 3.2 用于记录错误的对象
NSError *error = nil;
// 3.3 循环添加音频资源
for (NSURL *sourceURL in sourceURLs) {
// 3.3.1 音频文件资源
AVURLAsset *audioAsset = [[AVURLAsset alloc]initWithURL:sourceURL options:nil];
// 3.3.2 需要合并的音频文件的播放的时间区间
CMTimeRange audio_timeRange = CMTimeRangeMake(kCMTimeZero, audioAsset.duration);
// 3.3.3 添加音频文件
// 参数说明:
// insertTimeRange:源录音文件的的区间
// ofTrack:插入音频的内容
// atTime:源音频插入到目标文件开始时间
// error: 插入失败记录错误
// 返回:YES表示插入成功,`NO`表示插入失败
BOOL success = [compositionAudioTrack insertTimeRange:audio_timeRange ofTrack:[[audioAsset tracksWithMediaType:AVMediaTypeAudio] objectAtIndex:0] atTime:beginTime error:&error];
// 3.3.4 如果插入失败,打印插入失败信息
if (!success) {
NSLog(@"插入音频失败: %@",error);
completed(error);
return;
}
// 3.3.5 记录下次音频文件插入的开始时间
beginTime = CMTimeAdd(beginTime, audioAsset.duration);
} // 4. 导出合并的音频文件
// 4.0 创建一个导入M4A格式的音频的导出对象
AVAssetExportSession* assetExport = [[AVAssetExportSession alloc] initWithAsset:mixComposition presetName:AVAssetExportPresetAppleM4A];
// 4.2 设置导入音视频的URL
assetExport.outputURL = toURL;
// 导出音视频的文件格式
assetExport.outputFileType = @"com.apple.m4a-audio";
// 4.3 导入出
[assetExport exportAsynchronouslyWithCompletionHandler:^{
// 4.5 分发到主线程
dispatch_async(dispatch_get_main_queue(), ^{
completed(assetExport.error);
});
}];
}
@end

完整Demo下载地址

iOS音频合并的更多相关文章

  1. iOS 音频视频图像合成那点事

    代码地址如下:http://www.demodashi.com/demo/13420.html 人而无信不知其可 前言 很久很久没有写点什么了,只因为最近事情太多了,这几天终于闲下来了,趁此机会,记录 ...

  2. 一篇对iOS音频比较完善的文章

    转自:http://www.cnblogs.com/iOS-mt/p/4268532.html 感谢作者:梦想通 前言 从事音乐相关的app开发也已经有一段时日了,在这过程中app的播放器几经修改我也 ...

  3. iOS音频AAC视频H264编码 推流最佳方案

    iOS音频AAC视频H264编码 推流最佳方案 项目都是个人的调研与实验,可能很多不好或者不对的地方请多包涵. 1    功能概况 *  实现音视频的数据的采集 *  实现音视频数据的编码,视频编码成 ...

  4. IOS 音频开发文件大小计算

    音频基础知识 音频文件计算大小 音频转码 标签(空格分隔): 调查 IOS音频 https://developer.apple.com/library/ios/documentation/MusicA ...

  5. iOS 音频拼接

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

  6. iOS音频处理

    ios音频处理 1. iOS底层音频处理技术(带源代码) http://www.cocoachina.com/ios/20111122/3563.html 2.ios 音频入门 http://blog ...

  7. IOS 音频播放

    iOS音频播放 (一):概述 前言 从事音乐相关的app开发也已经有一段时日了,在这过程中app的播放器几经修改我也因此对于iOS下的音频播放实现有了一定的研究.写这个系列的博客目的一方面希望能够抛砖 ...

  8. iOS音频播放(一):概述

    (本文转自码农人生) 前言 从事音乐相关的app开发也已经有一段时日了,在这过程中app的播放器几经修改,我也因此对于iOS下的音频播放实现有了一定的研究.写这个 系列的博客目的一方面希望能够抛砖引玉 ...

  9. IOS音频1:之采用四种方式播放音频文件(一)AudioToolbox AVFoundation OpenAL AUDIO QUEUE

    本文转载至 http://blog.csdn.net/u014011807/article/details/40187737 在本卷你可以学到什么? 采用四种方法设计应用于各种场合的音频播放器: 基于 ...

随机推荐

  1. !!! # @ --- ODATA 云驱动 --- 数据库发布 RESTFUL API

    Cloud Drivers   ODATA 云驱动   http://www.cdata.com/cloud/ Makes on-premise & cloud data sources ea ...

  2. InternalError: (pymysql.err.InternalError) (1205, u'Lock wait timeout exceeded; try restarting transaction')

    在mysql innodb中使用事务,如果插入或者更新出错,一定要主动显式地执行rollback,否则可能产生不必要的锁而锁住其他的操作 我们在使用数据库的时候,可以使用contextlib,这样异常 ...

  3. 二十四种设计模式:建造者模式(Builder Pattern)

    建造者模式(Builder Pattern) 介绍将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示. 示例用同样的构建过程创建Sql和Xml的Insert()方法和Get()方 ...

  4. C++迭代器之'反向迭代器'

    反向迭代器(Reverse Iterator)是普通迭代器的适配器,通过重新定义自增和自减操作,以达到按反序遍历元素的目的.如果在标准算法库中用反向迭代器来代替普通的迭代器,那么运行结果与正常情况下相 ...

  5. [转载]Delphi事件的广播

    https://blog.csdn.net/dropme/article/details/975736 明天就是五一节了,辛苦了好几个月,借此机会应该尽情放松一番.可是想到Blog好久没有写文章,似乎 ...

  6. delphi Align属性

    ---------------------------------------------- -

  7. 利用Nodejs & Cheerio & Request抓取Lofter美女图片

    还是参考了这篇文章: http://cnodejs.org/topic/54bdaac4514ea9146862abee 另外有上面文章 nodejs抓取网易公开课的一些经验. 代码如下,注意其中用到 ...

  8. Vue脚手架(vue-cli)搭建和目录结构详解

    一.环境搭建 1.安装node.npm.webpack,不多说 2.安装vue-cli脚手架构建工具,打开命令行工具输入:npm install vue-cli -g,安装完成之后输入 vue -V( ...

  9. IP地址转换、主机大小端、htonl、ntohl实现

    copy   #include <IOSTREAM> //#include <WINSOCK.H> using std; typedef  uint16; unsigned   ...

  10. js正则表达式之中文验证(转)

    原文地址:http://houfeng0923.iteye.com/blog/1035321 今天做表单提交的输入框条件验证,验证是否包含中文:网上搜了一圈基于js正则表达式的验证基本不好用,而且大多 ...