zhuanHuanM4a.m 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778
  1. //
  2. // zhuanHuanM4a.m
  3. // suncity-mobile
  4. //
  5. // Created by MacBook Pro on 2020/4/1.
  6. //
  7. #import "zhuanHuanM4a.h"
  8. #import <AVFoundation/AVFoundation.h>
  9. @implementation zhuanHuanM4a
  10. /**
  11. 把.caf转为.m4a格式
  12. @param cafUrlStr .m4a文件路径
  13. @param m4aUrlStr .caf文件路径
  14. @param completed 转化完成的block
  15. */
  16. + (void)convetCafToM4a:(NSString *)cafUrlStr
  17. destUrl:(NSString *)m4aUrlStr
  18. completed:(void (^)(NSError *error)) completed {
  19. AVMutableComposition* mixComposition = [AVMutableComposition composition];
  20. // 音频插入的开始时间
  21. CMTime beginTime = kCMTimeZero;
  22. // 获取音频合并音轨
  23. AVMutableCompositionTrack *compositionAudioTrack = [mixComposition addMutableTrackWithMediaType:AVMediaTypeAudio preferredTrackID:kCMPersistentTrackID_Invalid];
  24. // 用于记录错误的对象
  25. NSError *error = nil;
  26. // 音频原文件资源
  27. AVURLAsset *cafAsset = [[AVURLAsset alloc]initWithURL:[NSURL fileURLWithPath:cafUrlStr] options:nil];
  28. // 原音频需要合并的音频文件的区间
  29. CMTimeRange audio_timeRange = CMTimeRangeMake(kCMTimeZero, cafAsset.duration);
  30. BOOL success = [compositionAudioTrack insertTimeRange:audio_timeRange ofTrack:[[cafAsset tracksWithMediaType:AVMediaTypeAudio] objectAtIndex:0] atTime:beginTime error:&error];
  31. if (!success) {
  32. NSLog(@"插入原音频失败: %@",error);
  33. }else {
  34. NSLog(@"插入原音频成功");
  35. }
  36. // 创建一个导入M4A格式的音频的导出对象
  37. AVAssetExportSession* assetExport = [[AVAssetExportSession alloc] initWithAsset:mixComposition presetName:AVAssetExportPresetAppleM4A];
  38. // 导入音视频的URL
  39. assetExport.outputURL = [NSURL fileURLWithPath:m4aUrlStr];
  40. // 导出音视频的文件格式
  41. assetExport.outputFileType = @"com.apple.m4a-audio";
  42. [assetExport exportAsynchronouslyWithCompletionHandler:^{
  43. // 分发到主线程
  44. dispatch_async(dispatch_get_main_queue(), ^{
  45. int exportStatus = assetExport.status;
  46. if (exportStatus == AVAssetExportSessionStatusCompleted) {
  47. // 合成成功
  48. completed(nil);
  49. NSError *removeError = nil;
  50. if([cafUrlStr hasSuffix:@"caf"]) {
  51. // 删除老录音caf文件
  52. if ([[NSFileManager defaultManager] fileExistsAtPath:cafUrlStr]) {
  53. BOOL success = [[NSFileManager defaultManager] removeItemAtPath:cafUrlStr error:&removeError];
  54. if (!success) {
  55. NSLog(@"删除老录音caf文件失败:%@",removeError);
  56. }else{
  57. NSLog(@"删除老录音caf文件:%@成功",cafUrlStr);
  58. }
  59. }
  60. }
  61. }else {
  62. completed(assetExport.error);
  63. }
  64. }
  65. );
  66. }];
  67. }
  68. @end