美文网首页iOS开发攻城狮的集散地iOS程序猿
iOS 多条音频拼接为一条音频进行播放

iOS 多条音频拼接为一条音频进行播放

作者: freesan44 | 来源:发表于2021-11-12 07:28 被阅读0次

    场景

    把多条mp3音频合并为一条保存并进行播放

    解决方案

    1. 首先把全部音频路径生成为一个数组:
    NSMutableArray * fileUrlArr = @[].mutableCopy;
        [mp3NameArr enumerateObjectsUsingBlock:^(id  _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
            NSString *mp3Name = [NSString stringWithFormat:@"%@",obj];
        
            // mp3路径
            NSString *audioFileURL = [[NSBundle mainBundle] pathForResource:mp3Name ofType:@"mp3"];
            [fileUrlArr addObject:audioFileURL];
        }];
    
    1. 通过以下方法合并音频,保存在一个随机文件中,因为文件如果已存在或者文件目录写入失败,会出现【AVAssetExportSessionStatusFailed】错误码
    ///合并音频
    - (void) mergeAVAssetWithSourceURLs:(NSArray *)sourceURLsArr completed:(void (^)(NSString * outputFileUrlStr)) completed{
        //创建音频轨道,并获取多个音频素材的轨道
        AVMutableComposition *composition = [AVMutableComposition composition];
        //音频插入的开始时间,用于记录每次添加音频文件的开始时间
        __block CMTime beginTime = kCMTimeZero;
        [sourceURLsArr enumerateObjectsUsingBlock:^(id  _Nonnull audioFileURL, NSUInteger idx, BOOL * _Nonnull stop) {
            //获取音频素材
            AVURLAsset *audioAsset1 = [AVURLAsset assetWithURL:[NSURL fileURLWithPath:audioFileURL]];
            //音频轨道
            AVMutableCompositionTrack *audioTrack1 = [composition addMutableTrackWithMediaType:AVMediaTypeAudio preferredTrackID:0];
            //获取音频素材轨道
            AVAssetTrack *audioAssetTrack1 = [[audioAsset1 tracksWithMediaType:AVMediaTypeAudio] firstObject];
            //音频合并- 插入音轨文件
            [audioTrack1 insertTimeRange:CMTimeRangeMake(kCMTimeZero, audioAsset1.duration) ofTrack:audioAssetTrack1 atTime:beginTime error:nil];
            // 记录尾部时间
            beginTime = CMTimeAdd(beginTime, audioAsset1.duration);
        }];
        //导出合并后的音频文件
        //音频文件目前只找到支持m4a 类型的
        AVAssetExportSession *session = [[AVAssetExportSession alloc]initWithAsset:composition presetName:AVAssetExportPresetAppleM4A];
        NSDateFormatter *formater = [[NSDateFormatter alloc] init];
        [formater setDateFormat:@"yyyy-MM-dd-HH:mm:ss-SSS"];
        NSString * timeFromDateStr = [formater stringFromDate:[NSDate date]];
        NSString *outPutFilePath = [NSHomeDirectory() stringByAppendingFormat:@"/tmp/sound-%@.mp4", timeFromDateStr];
        
        
        // 音频文件输出
        session.outputURL = [NSURL fileURLWithPath:outPutFilePath];
        session.outputFileType = AVFileTypeAppleM4A; //与上述的`present`相对应
        session.shouldOptimizeForNetworkUse = YES;   //优化网络
        [session exportAsynchronouslyWithCompletionHandler:^{
            if (session.status == AVAssetExportSessionStatusCompleted) {
                NSLog(@"合并成功----%@", outPutFilePath);
                if (completed) {
                    completed(outPutFilePath);
                }
            } else {
                // 其他情况, 具体请看这里`AVAssetExportSessionStatus`.
                NSLog(@"合并失败----%ld", (long)session.status);
                if (completed) {
                    completed(nil);
                }
            }
        }];
    }
    
    1. 输出合并音频
    // 合并音频文件生成新的音频
        [self mergeAVAssetWithSourceURLs:musicArr completed:^(NSString *outputFileUrlStr) {
            if (!outputFileUrlStr) {
                NSLog(@"声音生成失败!");
                return;
            }
                self.audioPlayer = [[AVAudioPlayer alloc] initWithContentsOfURL:[NSURL fileURLWithPath:outputFileUrlStr] error:nil];
                [self.audioPlayer play];
        }];
    

    参考:
    https://www.cxyzjd.com/article/ismilesky/52780349
    https://www.jianshu.com/p/3e357e3129b8
    http://www.cocoachina.com/articles/17624

    相关文章

      网友评论

        本文标题:iOS 多条音频拼接为一条音频进行播放

        本文链接:https://www.haomeiwen.com/subject/lddgzltx.html