//抽取原視頻的音頻與需要的音樂混合
-(void)addmusic:(id)sender
{
[MBProgressHUDshowHUDAddedTo:self.viewanimated:YES];
AVMutableComposition*composition?=[AVMutableCompositioncomposition];
audioMixParams?=[[NSMutableArrayalloc]initWithObjects:nil];
//錄制的視頻
NSURL*video_inputFileUrl?=[NSURLfileURLWithPath:self.videoPath];
AVURLAsset*songAsset?=[AVURLAssetURLAssetWithURL:video_inputFileUrloptions:nil];
CMTime?startTime?=CMTimeMakeWithSeconds(0,songAsset.duration.timescale);
CMTime?trackDuration?=songAsset.duration;
//獲取視頻中的音頻素材
[selfsetUpAndAddAudioAtPath:video_inputFileUrltoComposition:compositionstart:startTimedura:trackDurationoffset:CMTimeMake(14*44100,44100)];
//本地要插入的音樂
NSString*bundleDirectory?=[[NSBundlemainBundle]bundlePath];
NSString*path?=?[bundleDirectorystringByAppendingPathComponent:@"30secs.mp3"];
NSURL*assetURL2=[NSURLfileURLWithPath:path];
//獲取設置完的本地音樂素材
[selfsetUpAndAddAudioAtPath:assetURL2toComposition:compositionstart:startTimedura:trackDurationoffset:CMTimeMake(0,44100)];
//創(chuàng)建一個可變的音頻混合
AVMutableAudioMix*audioMix?=[AVMutableAudioMixaudioMix];
audioMix.inputParameters=[NSArrayarrayWithArray:audioMixParams];//從數(shù)組里取出處理后的音頻軌道參數(shù)
//創(chuàng)建一個輸出
AVAssetExportSession*exporter?=[[AVAssetExportSessionalloc]
initWithAsset:composition
presetName:AVAssetExportPresetAppleM4A];
exporter.audioMix=?audioMix;
exporter.outputFileType=@"com.apple.m4a-audio";
NSString*?fileName?=[NSStringstringWithFormat:@"%@.mov",@"overMix"];
//輸出路徑
NSString*exportFile?=[NSStringstringWithFormat:@"%@/%@",[selfgetLibarayPath],fileName];
if([[NSFileManagerdefaultManager]fileExistsAtPath:exportFile])?{
[[NSFileManagerdefaultManager]removeItemAtPath:exportFileerror:nil];
}
NSLog(@"是否在主線程1%d",[NSThreadisMainThread]);
NSLog(@"輸出路徑===%@",exportFile);
NSURL*exportURL?=[NSURLfileURLWithPath:exportFile];
exporter.outputURL=?exportURL;
self.mixURL=exportURL;
[exporterexportAsynchronouslyWithCompletionHandler:^{
intexportStatus?=(int)exporter.status;
switch(exportStatus){
caseAVAssetExportSessionStatusFailed:{
NSError*exportError?=exporter.error;
NSLog(@"錯誤,信息:?%@",?exportError);
[MBProgressHUDhideHUDForView:self.viewanimated:YES];
break;
}
caseAVAssetExportSessionStatusCompleted:{
NSLog(@"是否在主線程2%d",[NSThreadisMainThread]);
NSLog(@"成功");
//最終混合
[selftheVideoWithMixMusic];
break;
}
}
}];
}
//最終音頻和視頻混合
-(void)theVideoWithMixMusic
{
NSError*error?=nil;
NSFileManager*fileMgr?=[NSFileManagerdefaultManager];
NSString*documentsDirectory?=[NSHomeDirectory()
stringByAppendingPathComponent:@"Documents"];
NSString*videoOutputPath?=[documentsDirectorystringByAppendingPathComponent:@"test_output.mp4"];
if([fileMgrremoveItemAtPath:videoOutputPatherror:&error]!=YES)?{
NSLog(@"無法刪除文件,錯誤信息:%@",[errorlocalizedDescription]);
}
//聲音來源路徑(最終混合的音頻)
NSURL???*audio_inputFileUrl?=self.mixURL;
//視頻來源路徑
NSURL???*video_inputFileUrl?=?[NSURLfileURLWithPath:self.videoPath];
//最終合成輸出路徑
NSString*outputFilePath?=[documentsDirectorystringByAppendingPathComponent:@"final_video.mp4"];
NSURL???*outputFileUrl?=?[NSURLfileURLWithPath:outputFilePath];
if([[NSFileManagerdefaultManager]fileExistsAtPath:outputFilePath])
[[NSFileManagerdefaultManager]removeItemAtPath:outputFilePatherror:nil];
CMTime?nextClipStartTime?=kCMTimeZero;
//創(chuàng)建可變的音頻視頻組合
AVMutableComposition*?mixComposition?=[AVMutableCompositioncomposition];
//視頻采集
AVURLAsset*?videoAsset?=[[AVURLAssetalloc]initWithURL:video_inputFileUrloptions:nil];
CMTimeRange?video_timeRange?=CMTimeRangeMake(kCMTimeZero,videoAsset.duration);
AVMutableCompositionTrack*a_compositionVideoTrack?=?[mixCompositionaddMutableTrackWithMediaType:AVMediaTypeVideopreferredTrackID:kCMPersistentTrackID_Invalid];
[a_compositionVideoTrackinsertTimeRange:video_timeRangeofTrack:[[videoAssettracksWithMediaType:AVMediaTypeVideo]objectAtIndex:0]atTime:nextClipStartTimeerror:nil];
//聲音采集
AVURLAsset*?audioAsset?=[[AVURLAssetalloc]initWithURL:audio_inputFileUrloptions:nil];
CMTimeRange?audio_timeRange?=CMTimeRangeMake(kCMTimeZero,videoAsset.duration);//聲音長度截取范圍==視頻長度
AVMutableCompositionTrack*b_compositionAudioTrack?=?[mixCompositionaddMutableTrackWithMediaType:AVMediaTypeAudiopreferredTrackID:kCMPersistentTrackID_Invalid];
[b_compositionAudioTrackinsertTimeRange:audio_timeRangeofTrack:[[audioAssettracksWithMediaType:AVMediaTypeAudio]objectAtIndex:0]atTime:nextClipStartTimeerror:nil];
//創(chuàng)建一個輸出
AVAssetExportSession*?_assetExport?=[[AVAssetExportSessionalloc]initWithAsset:mixCompositionpresetName:AVAssetExportPresetMediumQuality];
_assetExport.outputFileType=AVFileTypeQuickTimeMovie;
_assetExport.outputURL=outputFileUrl;
_assetExport.shouldOptimizeForNetworkUse=YES;
self.theEndVideoURL=outputFileUrl;
[_assetExportexportAsynchronouslyWithCompletionHandler:
^(void)?{
[MBProgressHUDhideHUDForView:self.viewanimated:YES];
//播放
NSURL*url?=?[NSURLfileURLWithPath:outputFilePath];
MPMoviePlayerViewController*theMovie?=[[MPMoviePlayerViewControlleralloc]initWithContentURL:url];
[selfpresentMoviePlayerViewControllerAnimated:theMovie];
theMovie.moviePlayer.movieSourceType=MPMovieSourceTypeFile;
[theMovie.moviePlayerplay];
}
];
NSLog(@"完成!輸出路徑==%@",outputFilePath);
}
//通過文件路徑建立和添加音頻素材
-?(void)setUpAndAddAudioAtPath:(NSURL*)assetURLtoComposition:(AVMutableComposition*)compositionstart:(CMTime)startdura:(CMTime)duraoffset:(CMTime)offset{
AVURLAsset*songAsset?=[AVURLAssetURLAssetWithURL:assetURLoptions:nil];
AVMutableCompositionTrack*track?=[compositionaddMutableTrackWithMediaType:AVMediaTypeAudiopreferredTrackID:kCMPersistentTrackID_Invalid];
AVAssetTrack*sourceAudioTrack?=[[songAssettracksWithMediaType:AVMediaTypeAudio]objectAtIndex:0];
NSError*error?=nil;
BOOLok?=NO;
CMTime?startTime?=?start;
CMTime?trackDuration?=?dura;
CMTimeRange?tRange?=CMTimeRangeMake(startTime,trackDuration);
//設置音量
//AVMutableAudioMixInputParameters(輸入?yún)?shù)可變的音頻混合)
//audioMixInputParametersWithTrack(音頻混音輸入?yún)?shù)與軌道)
AVMutableAudioMixInputParameters*trackMix?=[AVMutableAudioMixInputParametersaudioMixInputParametersWithTrack:track];
[trackMixsetVolume:0.8fatTime:startTime];
//素材加入數(shù)組
[audioMixParamsaddObject:trackMix];
//Insert?audio?into?track??//offsetCMTimeMake(0,?44100)
ok?=?[trackinsertTimeRange:tRangeofTrack:sourceAudioTrackatTime:kCMTimeInvaliderror:&error];
}
#pragma?mark?-?保存路徑
-(NSString*)getLibarayPath
{
NSFileManager*fileManager?=[NSFileManagerdefaultManager];
NSArray*?paths?=NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,NSUserDomainMask,YES);
NSString*?path?=?[pathsobjectAtIndex:0];
NSString*movDirectory?=?[pathstringByAppendingPathComponent:@"tmpMovMix"];
[fileManagercreateDirectoryAtPath:movDirectorywithIntermediateDirectories:YESattributes:nilerror:nil];
returnmovDirectory;
}