iOS音频合并
iOS音频合并
最近遇到一个需求,客户录音试听一下可以,就继续向下录制,当客户录制完成后,需要把前面录制的试听音频和后面的音频进行合并.
最初想到的方法,使用NSData对两个音频文件进行合并,但是合并后,音频文件确实变大了,但是只能播放第一个音频. 这应该怎么办呢?
其实AVFoundation框架提供音视频剪辑,合成等功能. 我在这里仅仅介绍下音频合并,希望能起到抛砖引玉的效果.
这里需要使用到三个核心类AVMutableComposition: 用于对音视频轨道的添加和删除AVMutableCompositionTrack: 代表着一个音频/视频 的轨道,可以添加音频/视频资源AVAssetExportSession:用于导出处理后的音视频文件.
步骤
- 创建
AVMutableComposition- 给
AVMutableComposition添加一个新音频的轨道,并返回音频轨道- 循环添加需要的音频资源
- 导出合并的音频文件
代码
//
// 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音频合并的更多相关文章
- iOS 音频视频图像合成那点事
代码地址如下:http://www.demodashi.com/demo/13420.html 人而无信不知其可 前言 很久很久没有写点什么了,只因为最近事情太多了,这几天终于闲下来了,趁此机会,记录 ...
- 一篇对iOS音频比较完善的文章
转自:http://www.cnblogs.com/iOS-mt/p/4268532.html 感谢作者:梦想通 前言 从事音乐相关的app开发也已经有一段时日了,在这过程中app的播放器几经修改我也 ...
- iOS音频AAC视频H264编码 推流最佳方案
iOS音频AAC视频H264编码 推流最佳方案 项目都是个人的调研与实验,可能很多不好或者不对的地方请多包涵. 1 功能概况 * 实现音视频的数据的采集 * 实现音视频数据的编码,视频编码成 ...
- IOS 音频开发文件大小计算
音频基础知识 音频文件计算大小 音频转码 标签(空格分隔): 调查 IOS音频 https://developer.apple.com/library/ios/documentation/MusicA ...
- iOS 音频拼接
工作中或许会遇到这样的需求,将两段不同的音频合成一个音频(暂且称之为音频拼接),实现起来相对来说不是很难,再介绍如何拼接之前,先了解下AVFoundation下的几个基本知识点. 基本知识 AVAss ...
- iOS音频处理
ios音频处理 1. iOS底层音频处理技术(带源代码) http://www.cocoachina.com/ios/20111122/3563.html 2.ios 音频入门 http://blog ...
- IOS 音频播放
iOS音频播放 (一):概述 前言 从事音乐相关的app开发也已经有一段时日了,在这过程中app的播放器几经修改我也因此对于iOS下的音频播放实现有了一定的研究.写这个系列的博客目的一方面希望能够抛砖 ...
- iOS音频播放(一):概述
(本文转自码农人生) 前言 从事音乐相关的app开发也已经有一段时日了,在这过程中app的播放器几经修改,我也因此对于iOS下的音频播放实现有了一定的研究.写这个 系列的博客目的一方面希望能够抛砖引玉 ...
- IOS音频1:之采用四种方式播放音频文件(一)AudioToolbox AVFoundation OpenAL AUDIO QUEUE
本文转载至 http://blog.csdn.net/u014011807/article/details/40187737 在本卷你可以学到什么? 采用四种方法设计应用于各种场合的音频播放器: 基于 ...
随机推荐
- 游戏用户接口设计的一些小原则(摘自 game coding complete)
1.没有坏之前不要修理 2.简单的操作却有非常复杂的结果时,要小心设计. 3.记得给玩家反馈. 4.玩家不知道该功能,可能就根本不会用这个功能. 5.观察并持续改进.(给不熟悉该设计的人玩,站在他们后 ...
- Kali 2.0安装与使用指南
阅读目录 (1)如果坚持用系统自带浏览器,其汉化方法: (2)如果有强迫症删了系统自带浏览器,然后重新安装了一个新的火狐可能遇到的问题: (3)如果你有火狐账号,你登陆了发现书签和插件没有同步? (4 ...
- (C语言版)链表(四)——实现双向循环链表创建、插入、删除、释放内存等简单操作
双向循环链表是基于双向链表的基础上实现的,和双向链表的操作差不多,唯一的区别就是它是个循环的链表,通过每个节点的两个指针把它们扣在一起组成一个环状.所以呢,每个节点都有前驱节点和后继节点(包括头节点和 ...
- centos7 yum安装redis(转)
正如我们所知的那样,Redis是一个开源的.基于BSD许可证的,基于内存的.键值存储NoSQL数据库.Redis经常被视为一个数据结构服务器,因为Redis支持字符串strings.哈希hashes. ...
- eclipse package explorer视图中怎么让default package不显示?
如下图所示:
- 批处理命令中set定义的两种变量介绍 计算机基础知识
摘自: http://www.amhl.net/wenzhang/DianNaoChangShi/20101201/127422.html 所谓的自定义变量,就是由我们来给它赋予值的变量. ①赋值变量 ...
- [Python爬虫] 之十五:Selenium +phantomjs根据微信公众号抓取微信文章
借助搜索微信搜索引擎进行抓取 抓取过程 1.首先在搜狗的微信搜索页面测试一下,这样能够让我们的思路更加清晰 在搜索引擎上使用微信公众号英文名进行“搜公众号”操作(因为公众号英文名是公众号唯一的,而中文 ...
- 我的自动化测试历程(Selenium+TestNG+Java+ReportNG+Jenkins)
原地址:http://blog.csdn.net/shilinjie_8952/article/details/53380373?locationNum=11&fps=1 测试环境:Java+ ...
- MyEclipse 集成 Gradle开发环境
一.上Grandle官网下载Gradle,地址:http://www.gradle.org/downloads 如果只是运行只下载gradle-2.6-bin.zip 就可以了,如果为了扩展开发的话就 ...
- Java中equals()、equalsIgnoreCase()和==的区别
用久了C#,在Java中,判断一个字符串还是习惯性的用了==,但是总是不能按照正确的判断分支运行,后来才想起来Java中是有equals的,然后就有引出了equalsIgnoreCase. 这三种 ...