使用AVMutableComposition将声音与视频合成一个视频
2015-09-02 10:33
375 查看
/** * 合成视频输出到指定路径,注意区分是否3D视频 * * @param audioUrl 音频文件url * @param videoUrl 视频文件url * @param storePath 沙盒目录下的文件夹 * @param storeName 合成的文件名字 * @param tbool 是否3D视频,YES表示是3D视频 * @param successBlock 成功block * @param failureBlcok 失败block */ -(void)mergeAudio:(NSURL*)audioUrl andVideo:(NSURL *)videoUrl toStorePath:(NSString *)storePath WithStoreName:(NSString *)storeName andIf3D:(BOOL)tbool success:(void (^)(void))successBlock failure:(void (^)(void))failureBlcok { AVMutableComposition *mixComposition = [self mergeAudio:audioUrl andVideo:videoUrl]; NSURL *outputFileUrl = [self joinStorePaht:storePath togetherStoreName:storeName]; [self storeAVMutableComposition:mixComposition withStoreUrl:outputFileUrl andVideoUrl:videoUrl WihtName:storeName andIf3D:tbool success:successBlock failure:failureBlcok]; } /** * 音频视频合成得到AVMutableComposition,以较短文件长度作为时间长度 * * @param audioUrl 音频文件 * @param videoUrl 视频文件 * * @return AVMutableComposition */ -(AVMutableComposition *)mergeAudio:(NSURL*)audioUrl andVideo:(NSURL *)videoUrl { AVMutableComposition* mixComposition = [AVMutableComposition composition]; AVURLAsset *audioAsset = [[AVURLAsset alloc]initWithURL:audioUrl options:nil]; AVURLAsset *videoAsset = [[AVURLAsset alloc]initWithURL:videoUrl options:nil]; CMTime ctime; if (CMTimeGetSeconds(audioAsset.duration)>=CMTimeGetSeconds(videoAsset.duration)) { ctime = videoAsset.duration; }else { ctime = audioAsset.duration; } CMTimeRange audio_timeRange = CMTimeRangeMake(kCMTimeZero, ctime); AVMutableCompositionTrack *b_compositionAudioTrack = [mixComposition addMutableTrackWithMediaType:AVMediaTypeAudio preferredTrackID:kCMPersistentTrackID_Invalid]; [b_compositionAudioTrack insertTimeRange:audio_timeRange ofTrack:[[audioAsset tracksWithMediaType:AVMediaTypeAudio] objectAtIndex:0] atTime:kCMTimeZero error:nil]; CMTimeRange video_timeRange = CMTimeRangeMake(kCMTimeZero,ctime); AVMutableCompositionTrack *a_compositionVideoTrack = [mixComposition addMutableTrackWithMediaType:AVMediaTypeVideo preferredTrackID:kCMPersistentTrackID_Invalid]; [a_compositionVideoTrack insertTimeRange:video_timeRange ofTrack:[[videoAsset tracksWithMediaType:AVMediaTypeVideo] objectAtIndex:0] atTime:kCMTimeZero error:nil]; return mixComposition; } /** * 拼接url地址 * * @param sPath 沙盒文件夹名 * @param sName 文件名称 * * @return 返回拼接好的url地址 */ -(NSURL *)joinStorePaht:(NSString *)sPath togetherStoreName:(NSString *)sName { NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES); NSString *documentPath = [paths objectAtIndex:0]; NSFileManager *fileManager = [NSFileManager defaultManager]; NSString *storePath = [documentPath stringByAppendingPathComponent:sPath]; BOOL isExist = [fileManager fileExistsAtPath:storePath]; if(!isExist){ [fileManager createDirectoryAtPath:storePath withIntermediateDirectories:YES attributes:nil error:nil]; } NSString *realName = [NSString stringWithFormat:@"%@.mp4", sName]; storePath = [storePath stringByAppendingPathComponent:realName]; NSURL *outputFileUrl = [NSURL fileURLWithPath:storePath]; return outputFileUrl; } /** * 存储合成的视频 * * @param mixComposition mixComposition参数 * @param storeUrl 存储的路径 * @param successBlock successBlock * @param failureBlcok failureBlcok */ -(void)storeAVMutableComposition:(AVMutableComposition*)mixComposition withStoreUrl:(NSURL *)storeUrl andVideoUrl:(NSURL *)videoUrl WihtName:(NSString *)aName andIf3D:(BOOL)tbool success:(void (^)(void))successBlock failure:(void (^)(void))failureBlcok { __weak typeof(self) welf = self; AVAssetExportSession* _assetExport = [[AVAssetExportSession alloc] initWithAsset:mixComposition presetName:AVAssetExportPresetHighestQuality]; _assetExport.outputFileType = @"com.apple.quicktime-movie"; // _assetExport.outputFileType = @"public.mpeg-4"; _assetExport.outputURL = storeUrl; [_assetExport exportAsynchronouslyWithCompletionHandler:^{ dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ //在系统相册存储一份 UISaveVideoAtPathToSavedPhotosAlbum([storeUrl path], nil, nil, nil); // 在本地沙盒中存储一份,存储成功返回YES,如果不想存到沙盒,直接返回调用<span style="font-family: Arial, Helvetica, sans-serif;">successBlock();</span> // BOOL successful = [welf.photoStore storeVideoImageScale:videoUrl WihtName:aName andIf3D:tbool]; // dispatch_async(dispatch_get_main_queue(), ^{ // if (successful) { // successBlock(); // }else // { // failureBlcok(); // } // }); successBlock(); }); }]; }
相关文章推荐
- iOS开发之音轨合成(音频与音频,音频与视频)
- iOS 如何对音频、视频合成,配音、卡拉OK技术
- iOS 视频的录制、合成以及播放
- android视频的编辑(录制,裁剪,合成)(2)
- iOS多个视频拼接合成为一个视频
- iOS多个视频拼接合成为一个视频
- MongoDB操作类PHP代码
- idea jsp 问题 jsp api冲突
- 苹果开发者账号申请与iTunesconnect中心问题联系电话
- 希尔排序
- C程序编译过程浅析
- Unity屏幕震动实现(通过Camera Viewpoint)
- Intellij IDEA 在电脑蓝屏死机重启后报前言中不允许有内容的BUG解决方法
- 黑马程序员——JDK5.0新特性(泛型)
- 腾讯bugly 的crash 上报和umeng的比较
- 远程执行shell
- 1.9.1 参数化类型
- 关于Appstore提交过程的问题
- Jquery-mobile禁用ajax
- centos中git 创建仓库和本地调试与错误分析