IOS 中视频和音乐合成
2016-07-15 18:19
726 查看
因为最近在做关于视频相关的一些东西,有一个是给视频添加背景音乐或者配音,自己Google和百度了一些代码,将代码共享出来:
/** 为了方便,我都将选取的视频和音乐文件以及导出的视频将路径设置在桌面上了,资源文件自己设置 **/ NSString *inputFilePath = @"/Users/vs/Desktop/testvideo.mp4"; // 来源路径 NSString *outputFilePath = @"/Users/vs/Desktop/exportMax.mp4"; // 输出路径 NSString *mp3Path = @"/Users/vs/Desktop/月半弯.mp3"; //时间起点 CMTime nextClistartTime = kCMTimeZero; //创建可变的音视频组合 AVMutableComposition * comosition = [AVMutableComposition composition]; //视频采集 AVURLAsset * videoAsset = [[AVURLAsset alloc] initWithURL:[NSURL fileURLWithPath:inputFilePath] options:nil]; //视频时间范围 CMTimeRange videoTimeRange = CMTimeRangeMake(kCMTimeZero, videoAsset.duration); // 视频通道 枚举 kCMPersistentTrackID_Invalid = 0 AVMutableCompositionTrack * videoTrack = [comosition addMutableTrackWithMediaType:AVMediaTypeVideo preferredTrackID:kCMPersistentTrackID_Invalid]; //视频采集通道 AVAssetTrack * videoAssetTrack = [[videoAsset tracksWithMediaType:AVMediaTypeVideo] firstObject]; //把采集轨道数据加入到可变轨道中 [videoTrack insertTimeRange:videoTimeRange ofTrack:videoAssetTrack atTime:nextClistartTime error:nil]; //声音采集 AVURLAsset * audioAsset = [[AVURLAsset alloc] initWithURL:[NSURL fileURLWithPath:mp3Path] options:nil]; //因为视频较短 所以直接用了视频的长度 如果想要自动化需要自己写判断 CMTimeRange audioTimeRange = videoTimeRange; //音频通道 AVMutableCompositionTrack * audioTrack = [comosition addMutableTrackWithMediaType:AVMediaTypeAudio preferredTrackID:kCMPersistentTrackID_Invalid]; //音频采集通道 AVAssetTrack * audioAssetTrack = [[audioAsset tracksWithMediaType:AVMediaTypeAudio] firstObject]; //加入合成轨道中 [audioTrack insertTimeRange:audioTimeRange ofTrack:audioAssetTrack atTime:nextClistartTime error:nil]; #warning test // 3.1 - Create AVMutableVideoCompositionInstruction AVMutableVideoCompositionInstruction *mainInstruction = [AVMutableVideoCompositionInstruction videoCompositionInstruction]; mainInstruction.timeRange = CMTimeRangeMake(kCMTimeZero, videoAsset.duration); // 3.2 - Create an AVMutableVideoCompositionLayerInstruction for the video track and fix the orientation. AVMutableVideoCompositionLayerInstruction *videolayerInstruction = [AVMutableVideoCompositionLayerInstruction videoCompositionLayerInstructionWithAssetTrack:videoTrack]; UIImageOrientation videoAssetOrientation_ = UIImageOrientationUp; BOOL isVideoAssetPortrait_ = NO; CGAffineTransform videoTransform = videoAssetTrack.preferredTransform; if (videoTransform.a == 0 && videoTransform.b == 1.0 && videoTransform.c == -1.0 && videoTransform.d == 0) { videoAssetOrientation_ = UIImageOrientationRight; isVideoAssetPortrait_ = YES; } if (videoTransform.a == 0 && videoTransform.b == -1.0 && videoTransform.c == 1.0 && videoTransform.d == 0) { videoAssetOrientation_ = UIImageOrientationLeft; isVideoAssetPortrait_ = YES; } if (videoTransform.a == 1.0 && videoTransform.b == 0 && videoTransform.c == 0 && videoTransform.d == 1.0) { videoAssetOrientation_ = UIImageOrientationUp; } if (videoTransform.a == -1.0 && videoTransform.b == 0 && videoTransform.c == 0 && videoTransform.d == -1.0) { videoAssetOrientation_ = UIImageOrientationDown; } [videolayerInstruction setTransform:videoAssetTrack.preferredTransform atTime:kCMTimeZero]; [videolayerInstruction setOpacity:0.0 atTime:videoAsset.duration]; // 3.3 - Add instructions mainInstruction.layerInstructions = [NSArray arrayWithObjects:videolayerInstruction,nil]; AVMutableVideoComposition *mainCompositionInst = [AVMutableVideoComposition videoComposition]; CGSize naturalSize; if(isVideoAssetPortrait_){ naturalSize = CGSizeMake(videoAssetTrack.naturalSize.height, videoAssetTrack.naturalSize.width); } else { naturalSize = videoAssetTrack.naturalSize; } float renderWidth, renderHeight; renderWidth = naturalSize.width; renderHeight = naturalSize.height; mainCompositionInst.renderSize = CGSizeMake(renderWidth, renderHeight); mainCompositionInst.instructions = [NSArray arrayWithObject:mainInstruction]; mainCompositionInst.frameDuration = CMTimeMake(1, 30); #warning TODO: test end 如果没有这段代码,合成后的视频会旋转90度 //创建输出 AVAssetExportSession * assetExport = [[AVAssetExportSession alloc] initWithAsset:comosition presetName:AVAssetExportPresetMediumQuality]; assetExport.outputURL = [NSURL fileURLWithPath:outputFilePath];//输出路径 assetExport.outputFileType = AVFileTypeMPEG4;//输出类型 assetExport.shouldOptimizeForNetworkUse = YES; assetExport.videoComposition = mainCompositionInst; [assetExport exportAsynchronouslyWithCompletionHandler:^{ dispatch_async(dispatch_get_main_queue(), ^{ // [self exportDidFinish:assetExport]; switch (assetExport.status) { case AVAssetExportSessionStatusFailed: // 失败 NSLog(@"exportSessionError: %@",assetExport.error.description); break; case AVAssetExportSessionStatusExporting: NSLog(@"AVAssetExportSessionExporting"); break; case AVAssetExportSessionStatusCompleted: // 成功 NSLog(@"exportSessionCompleted"); UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"提示" message:@"保存成功!" delegate:nil cancelButtonTitle:@"OK" otherButtonTitles:nil]; [alert show]; break; } }); }];
相关文章推荐
- 峰回路转,Firefox 浏览器即将重返 iOS 平台
- 峰回路转,Firefox 浏览器即将重返 iOS 平台
- 网易云音乐8亿用户背后的伤疤
- 不可修补的 iOS 漏洞可能导致 iPhone 4s 到 iPhone X 永久越狱
- iOS 12.4 系统遭黑客破解,漏洞危及数百万用户
- 每日安全资讯:NSO,一家专业入侵 iPhone 的神秘公司
- 2 个给使用 Fedora 工作站的音乐爱好者的新应用
- Linux 上最好的五款音乐播放器
- [转][源代码]Comex公布JailbreakMe 3.0源代码
- 买视频送图书-五月活动
- 在 Linux 中使用 SoundConverter 轻松转换音频文件格式
- 5 个很酷的音乐播放器
- DVI 视频接口图文解析
- C#实现语音视频录制-附demo源码
- 编写C++程序使DirectShow进行视频捕捉
- AnyChat的视频会议程序实例详解
- C#调用mmpeg进行各种视频转换的类实例
- C#获取视频某一帧的缩略图的方法
- 基于jQuery的网页影音播放器jPlayer的基本使用教程