开发者

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

开发者 https://www.devze.com 2025-05-20 10:17 出处:网络 作者: 90后晨仔
目录1. 音频合并(多段音频拼接)代码示例使用方法2. 视频合并(多段视频拼接)代码示例使用方法3. 音视频合并(将音频与视频组合)代码示例使用方法4. 注意事项5. 第三方工具推荐1. 音频合并(多段音频拼接)
目录
  • 1. 音频合并(多段音频拼接)
    • 代码示例
    • 使用方法
  • 2. 视频合并(多段视频拼接)
    • 代码示例
    • 使用方法
  • 3. 音视频合并(将音频与视频组合)
    • 代码示例
    • 使用方法
  • 4. 注意事项
    • 5. 第三方工具推荐

      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] initWithAphpsset: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 = exportSessvztNXion.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 avztNXddMutableTrackWithMediaType: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 *outputphpPath = [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);
              }
          }];
      }
      

      使用方法

      //php 示例:合并一个音频和一个视频文件
      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合并音视频内容请搜索编程客栈(www.devze.com)以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程客栈(www.devze.com)!

      0

      精彩评论

      暂无评论...
      验证码 换一张
      取 消

      关注公众号