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. android非法字符的判定、表情符号的判定

    public class EmojiEditText extends EditText {// 输入表情前的光标位置private int cursorPos; // 输入表情前EditText中的文 ...

  2. [Android Pro] 获取手机已经安装的应用 和 获取当前正在运行的所有进程(一个uid对应多个pid)

    1: 获取PackageManager 获取全部静态已安装的应用: PackageManager pm = getPackageManager(); List<PackageInfo> i ...

  3. iOS:第三方框架MJPhotoBrowser图片浏览器的使用

    介绍:MJPhotoBrowser这个第三方库是MJ老师封装的一套用来浏览图片的浏览器,可是是本地图片.网络图片.gif图片等,其也依赖了SDWebImage.SVProgressHUD.YLGIFI ...

  4. LINUX提权后获取敏感信息之方法

    文中的每行为一条命令,文中有的命令可能在你的主机上敲不出来,因为它可能是在其他版本的linux中所使用的命令. 列举关键点 (Linux)的提权是怎么一回事:  收集 – 枚举,枚举和一些更多的枚举. ...

  5. vim配置python开发环境(转)

    安装 因为许多Unix衍生系统已经预装了Vim,我们首先要确认编辑器是否成功安装: vim --version 如果已经安装了,你应该看到类似下面的文字: VIM - Vi IMproved 7.3 ...

  6. Android视图SurfaceView的实现原理分析(示例,出错代码)

    在Android系统中,有一种特殊的视图,称为SurfaceView,它拥有独立的绘图表面,即它不与其宿主窗口共享同一个绘图表面.由于拥有独立的绘图表面,因此SurfaceView的UI就可以在一个独 ...

  7. Hyper-V中的VM如何使用Pass-through Disk

    Configuring Pass-through Disks in Hyper-V http://blogs.technet.com/b/askcore/archive/2008/10/24/conf ...

  8. 30分钟Git命令“从入门到放弃”

    git 现在的火爆程度非同一般,它被广泛地用在大型开源项目中,但是初学者非常容易“从入门到放弃”,各种命令各种参数,天哪,宝宝要吓哭了.实际上新手并不需要了解所有命令的用途,学习是需要一个循序渐进的过 ...

  9. iOS 使用腾讯地图显示用户位置注意事项

    1. 向 target中info 加入  NSLocationWhenInUseUsageDescription,string 类型.值是描写叙述为什么须要用户位置,这句话会出如今 提示用户是否同意a ...

  10. MongoDB的连接字符串

    本文导读:MongoDB数据库与传统的关系型数据库相比,它具有操作简单.完全免费.源码公开等特点,这使MongoDB产品广泛应用于各种大型门户网站和专业网站.由于MongoDB连接并不支持HTTP协议 ...