zoukankan      html  css  js  c++  java
  • iOS音频合并

    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下载地址

  • 相关阅读:
    Dot Net WinForm 控件开发 (七) 为属性提下拉式属性编辑器
    WinForm 程序的界面多语言切换
    c#遍历HashTable
    Dot Net WinForm 控件开发 (三) 自定义类型的属性需要自定义类型转换器
    Dot Net WinForm 控件开发 (六) 为属性提供弹出式编辑对话框
    Dot Net WinForm 控件开发 (一) 写一个最简单的控件
    Dot Net WinForm 控件开发 (四) 设置属性的默认值
    Dot Net WinForm 控件开发 (二) 给控件来点描述信息
    Dot Net WinForm 控件开发 (八) 调试控件的设计时行为
    Dot Net WinForm 控件开发 (五) 复杂属性的子属性
  • 原文地址:https://www.cnblogs.com/LiLihongqiang/p/6704726.html
Copyright © 2011-2022 走看看