iOS中实现音视频合并的完整代码

 更新时间:2025年05月19日 10:35:31   作者:90后晨仔  
在 iOS 中,合并音视频通常涉及将多个音频文件、视频文件或音频与视频轨道组合成一个完整的媒体文件,以下是使用 AVFoundation 框架的详细实现方案,涵盖音频合并、视频合并以及音视频合并的完整代码示例,需要的朋友可以参考下

1. 音频合并(多段音频拼接)

将多个音频文件(如 .mp3.m4a)合并为一个音频文件。

代码示例

// 合并音频文件(支持 .mp3/.m4a 等格式)
- (void)mergeAudioFiles:(NSArray<NSURL *> *)audioURLs completion:(void (^)(NSURL *outputURL, NSError *error))completion {
    // 1. 创建 AVMutableComposition 对象
    AVMutableComposition *composition = [AVMutableComposition composition];
    
    // 2. 添加音频轨道
    AVMutableCompositionTrack *audioTrack = [composition addMutableTrackWithMediaType:AVMediaTypeAudio preferredTrackID:kCMPersistentTrackID_Invalid];
    
    // 3. 插入每个音频文件到轨道中
    CMTime currentTime = kCMTimeZero;
    for (NSURL *url in audioURLs) {
        AVURLAsset *asset = [AVURLAsset URLAssetWithURL:url options:nil];
        AVAssetTrack *assetTrack = [[asset tracksWithMediaType:AVMediaTypeAudio] firstObject];
        [audioTrack insertTimeRange:CMTimeRangeMake(kCMTimeZero, asset.duration)
                         ofTrack:assetTrack
                          atTime:currentTime
                           error:nil];
        currentTime = CMTimeAdd(currentTime, asset.duration);
    }
    
    // 4. 导出合并后的音频
    AVAssetExportSession *exportSession = [[AVAssetExportSession alloc] initWithAsset:composition presetName:AVAssetExportPresetAppleM4A];
    NSString *outputPath = [NSTemporaryDirectory() stringByAppendingPathComponent:@"mergedAudio.m4a"];
    exportSession.outputURL = [NSURL fileURLWithPath:outputPath];
    exportSession.outputFileType = AVFileTypeAppleM4A;
    
    [exportSession exportAsynchronouslyWithCompletionHandler:^{
        if (exportSession.status == AVAssetExportSessionStatusCompleted) {
            NSLog(@"音频合并成功: %@", outputPath);
            if (completion) completion([NSURL fileURLWithPath:outputPath], nil);
        } else {
            NSError *error = exportSession.error;
            NSLog(@"音频合并失败: %@", error.localizedDescription);
            if (completion) completion(nil, error);
        }
    }];
}

使用方法

// 示例:合并两个音频文件
NSArray<NSURL *> *audioURLs = @[
    [NSURL fileURLWithPath:[[NSBundle mainBundle] pathForResource:@"audio1" ofType:@"mp3"]],
    [NSURL fileURLWithPath:[[NSBundle mainBundle] pathForResource:@"audio2" ofType:@"mp3"]]
];

[self mergeAudioFiles:audioURLs completion:^(NSURL *outputURL, NSError *error) {
    if (outputURL) {
        NSLog(@"合并后的音频路径: %@", outputURL.path);
    }
}];

2. 视频合并(多段视频拼接)

将多个视频文件(如 .mp4)合并为一个视频文件。

代码示例

// 合并视频文件(支持 .mp4 等格式)
- (void)mergeVideoFiles:(NSArray<NSURL *> *)videoURLs completion:(void (^)(NSURL *outputURL, NSError *error))completion {
    // 1. 创建 AVMutableComposition 对象
    AVMutableComposition *composition = [AVMutableComposition composition];
    
    // 2. 添加视频轨道和音频轨道
    AVMutableCompositionTrack *videoTrack = [composition addMutableTrackWithMediaType:AVMediaTypeVideo preferredTrackID:kCMPersistentTrackID_Invalid];
    AVMutableCompositionTrack *audioTrack = [composition addMutableTrackWithMediaType:AVMediaTypeAudio preferredTrackID:kCMPersistentTrackID_Invalid];
    
    // 3. 插入每个视频文件到轨道中
    CMTime currentTime = kCMTimeZero;
    for (NSURL *url in videoURLs) {
        AVURLAsset *asset = [AVURLAsset URLAssetWithURL:url options:nil];
        AVAssetTrack *videoAssetTrack = [[asset tracksWithMediaType:AVMediaTypeVideo] firstObject];
        AVAssetTrack *audioAssetTrack = [[asset tracksWithMediaType:AVMediaTypeAudio] firstObject];
        
        [videoTrack insertTimeRange:CMTimeRangeMake(kCMTimeZero, asset.duration)
                         ofTrack:videoAssetTrack
                          atTime:currentTime
                           error:nil];
        [audioTrack insertTimeRange:CMTimeRangeMake(kCMTimeZero, asset.duration)
                         ofTrack:audioAssetTrack
                          atTime:currentTime
                           error:nil];
        currentTime = CMTimeAdd(currentTime, asset.duration);
    }
    
    // 4. 导出合并后的视频
    AVAssetExportSession *exportSession = [[AVAssetExportSession alloc] initWithAsset:composition presetName:AVAssetExportPresetHighestQuality];
    NSString *outputPath = [NSTemporaryDirectory() stringByAppendingPathComponent:@"mergedVideo.mp4"];
    exportSession.outputURL = [NSURL fileURLWithPath:outputPath];
    exportSession.outputFileType = AVFileTypeMPEG4;
    
    [exportSession exportAsynchronouslyWithCompletionHandler:^{
        if (exportSession.status == AVAssetExportSessionStatusCompleted) {
            NSLog(@"视频合并成功: %@", outputPath);
            if (completion) completion([NSURL fileURLWithPath:outputPath], nil);
        } else {
            NSError *error = exportSession.error;
            NSLog(@"视频合并失败: %@", error.localizedDescription);
            if (completion) completion(nil, error);
        }
    }];
}

使用方法

// 示例:合并两个视频文件
NSArray<NSURL *> *videoURLs = @[
    [NSURL fileURLWithPath:[[NSBundle mainBundle] pathForResource:@"video1" ofType:@"mp4"]],
    [NSURL fileURLWithPath:[[NSBundle mainBundle] pathForResource:@"video2" ofType:@"mp4"]]
];

[self mergeVideoFiles:videoURLs completion:^(NSURL *outputURL, NSError *error) {
    if (outputURL) {
        NSLog(@"合并后的视频路径: %@", outputURL.path);
    }
}];

3. 音视频合并(将音频与视频组合)

将独立的音频文件和视频文件合并为一个包含音视频的媒体文件。

代码示例

// 合并音频与视频
- (void)mergeAudio:(NSURL *)audioURL withVideo:(NSURL *)videoURL completion:(void (^)(NSURL *outputURL, NSError *error))completion {
    // 1. 创建 AVMutableComposition 对象
    AVMutableComposition *composition = [AVMutableComposition composition];
    
    // 2. 添加视频轨道
    AVMutableCompositionTrack *videoTrack = [composition addMutableTrackWithMediaType:AVMediaTypeVideo preferredTrackID:kCMPersistentTrackID_Invalid];
    AVURLAsset *videoAsset = [AVURLAsset URLAssetWithURL:videoURL options:nil];
    AVAssetTrack *videoAssetTrack = [[videoAsset tracksWithMediaType:AVMediaTypeVideo] firstObject];
    [videoTrack insertTimeRange:CMTimeRangeMake(kCMTimeZero, videoAsset.duration)
                     ofTrack:videoAssetTrack
                      atTime:kCMTimeZero
                       error:nil];
    
    // 3. 添加音频轨道
    AVMutableCompositionTrack *audioTrack = [composition addMutableTrackWithMediaType:AVMediaTypeAudio preferredTrackID:kCMPersistentTrackID_Invalid];
    AVURLAsset *audioAsset = [AVURLAsset URLAssetWithURL:audioURL options:nil];
    AVAssetTrack *audioAssetTrack = [[audioAsset tracksWithMediaType:AVMediaTypeAudio] firstObject];
    [audioTrack insertTimeRange:CMTimeRangeMake(kCMTimeZero, audioAsset.duration)
                     ofTrack:audioAssetTrack
                      atTime:kCMTimeZero
                       error:nil];
    
    // 4. 导出合并后的音视频
    AVAssetExportSession *exportSession = [[AVAssetExportSession alloc] initWithAsset:composition presetName:AVAssetExportPresetHighestQuality];
    NSString *outputPath = [NSTemporaryDirectory() stringByAppendingPathComponent:@"mergedMedia.mp4"];
    exportSession.outputURL = [NSURL fileURLWithPath:outputPath];
    exportSession.outputFileType = AVFileTypeMPEG4;
    
    [exportSession exportAsynchronouslyWithCompletionHandler:^{
        if (exportSession.status == AVAssetExportSessionStatusCompleted) {
            NSLog(@"音视频合并成功: %@", outputPath);
            if (completion) completion([NSURL fileURLWithPath:outputPath], nil);
        } else {
            NSError *error = exportSession.error;
            NSLog(@"音视频合并失败: %@", error.localizedDescription);
            if (completion) completion(nil, error);
        }
    }];
}

使用方法

// 示例:合并一个音频和一个视频文件
NSURL *audioURL = [NSURL fileURLWithPath:[[NSBundle mainBundle] pathForResource:@"backgroundMusic" ofType:@"mp3"]];
NSURL *videoURL = [NSURL fileURLWithPath:[[NSBundle mainBundle] pathForResource:@"video" ofType:@"mp4"]];

[self mergeAudio:audioURL withVideo:videoURL completion:^(NSURL *outputURL, NSError *error) {
    if (outputURL) {
        NSLog(@"合并后的音视频路径: %@", outputURL.path);
    }
}];

4. 注意事项

  • 采样率与编码格式

    • 合并音频时,确保所有音频文件的采样率(如 44.1kHz)一致,否则需要先进行重采样。
    • 合并视频时,确保所有视频的分辨率、帧率一致,否则需调整为统一参数。
  • 性能优化

    • 使用 AVAssetExportSessionAVAssetExportPresetLowQualityAVAssetExportPresetMediumQuality 降低导出质量以加快处理速度。
    • 大文件合并时,建议分段处理或使用后台线程。
  • 错误处理

    • 检查 AVAssetExportSession.statuserror 信息,确保合并过程稳定。
  • 资源释放

    • 合并完成后,删除临时文件以释放存储空间。

5. 第三方工具推荐

如果需要更复杂的音视频处理(如裁剪、滤镜、转码),可以结合以下工具:

  • FFmpeg:通过 FFmpeg-iOS 实现强大的音视频处理功能。
  • GPUImage:用于实时视频滤镜和图像处理。
  • Lame:用于音频编码(如 MP3)。

通过以上方案,你可以高效地实现 iOS 平台上的音视频合并功能,适用于短视频拼接、音乐创作、播客制作等场景。

到此这篇关于iOS中实现音视频合并的完整代码的文章就介绍到这了,更多相关iOS合并音视频内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • 详解iOS学习笔记(十七)——文件操作(NSFileManager)

    详解iOS学习笔记(十七)——文件操作(NSFileManager)

    这篇文章主要介绍了详解iOS学习笔记(十七)——文件操作(NSFileManager),具有一定的参考价值,有需要的可以了解一下。
    2016-12-12
  • iOS实现微信分享多张图片功能

    iOS实现微信分享多张图片功能

    这篇文章主要为大家详细介绍了iOS实现微信分享多张图片功能,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2019-01-01
  • iOS实现去除html标签的方法汇总

    iOS实现去除html标签的方法汇总

    相信大家在做网站的时候,经常会遇到去除html标签的问题,下面这篇文章主要给大家总结介绍了关于iOS如何实现去除html标签的一些方法,文中通过示例代码介绍的非常详细,需要的朋友可以参考借鉴,下面来一起看看吧。
    2017-10-10
  • Flutter之TabBarView组件项目实战示例

    Flutter之TabBarView组件项目实战示例

    这篇文章主要为大家介绍了Flutter之TabBarView组件项目实战示例,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2022-10-10
  • iOS开发中使用CoreLocation框架处理地理编码的方法

    iOS开发中使用CoreLocation框架处理地理编码的方法

    这篇文章主要介绍了iOS开发中使用CoreLocation框架处理地理编码的方法,代码基于传统的Objective-C,需要的朋友可以参考下
    2015-12-12
  • iOS开发之随机生成两圆之间的标准圆

    iOS开发之随机生成两圆之间的标准圆

    这篇文章主要给大家介绍了iOS如何实现在两圆之间随机生成标准圆的方法,实现的效果类似寻找附近人或者附近商家的动态效果,有需要的朋友可以参考借鉴,下面来一起学习学习吧。
    2017-01-01
  • IOS 出现错误reason: image not found的解决方案

    IOS 出现错误reason: image not found的解决方案

    这篇文章主要介绍了IOS 出现错误reason: image not found的解决方案的相关资料,需要的朋友可以参考下
    2017-05-05
  • 详解IOS中GCD的使用

    详解IOS中GCD的使用

    GCD是iOS的一种底层多线程机制,本文给大家详细介绍IOS中GCD的使用,需要的朋友参考下吧
    2016-02-02
  • IOS 关键字const 、static、extern详解

    IOS 关键字const 、static、extern详解

    这篇文章主要介绍了IOS 关键字const 、static、extern详解的相关资料,这里对关键字如何使用,及在IOS开发中的意义做了详解,需要的朋友可以参考下
    2016-11-11
  • iOS实现Pad上菜单弹出界面

    iOS实现Pad上菜单弹出界面

    这篇文章主要为大家详细介绍了iOS实现Pad上菜单弹出界面的相关代码,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2017-06-06

最新评论