问题
I want to merge multiple videos into one.
But i don't know how to do this so please help me for this issue.
Below is my code but its not working for me.
AVMutableComposition* mixComposition = [AVMutableComposition composition];
AVMutableCompositionTrack *compositionCommentaryTrack = [mixComposition addMutableTrackWithMediaType:AVMediaTypeAudio preferredTrackID:kCMPersistentTrackID_Invalid];
[compositionCommentaryTrack insertTimeRange:CMTimeRangeMake(kCMTimeZero, audioAsset.duration)
ofTrack:[[audioAsset tracksWithMediaType:AVMediaTypeAudio] objectAtIndex:0]
atTime:kCMTimeZero error:nil];
AVMutableCompositionTrack *compositionVideoTrack = [mixComposition addMutableTrackWithMediaType:AVMediaTypeVideo preferredTrackID:kCMPersistentTrackID_Invalid];
[compositionVideoTrack insertTimeRange:CMTimeRangeMake(kCMTimeZero, videoAsset.duration)
ofTrack:[[videoAsset tracksWithMediaType:AVMediaTypeVideo] objectAtIndex:0]
atTime:kCMTimeZero error:nil];
AVAssetExportSession* _assetExport = [[AVAssetExportSession alloc] initWithAsset:mixComposition presetName:AVAssetExportPresetHighestQuality];
NSString* videoName = @"export.mov";
NSString *exportPath = [NSTemporaryDirectory() stringByAppendingPathComponent:videoName];
NSURL *exportUrl = [NSURL fileURLWithPath:exportPath];
if ([[NSFileManager defaultManager] fileExistsAtPath:exportPath])
{
[[NSFileManager defaultManager] removeItemAtPath:exportPath error:nil];
}
_assetExport.outputFileType = @"com.apple.quicktime-movie";
_assetExport.outputURL = exportUrl;
_assetExport.shouldOptimizeForNetworkUse = YES;
[_assetExport exportAsynchronouslyWithCompletionHandler:
^(void ) {
// your completion code here
}];
I have searched for this but no answer worked for me.
回答1:
Check my code below this works correct...
-(void)MergeVideo
{
AppDelegate *appdel = (AppDelegate*)[[UIApplication sharedApplication] delegate];
NSLog(@"Array Video Paths :- %@",appdel.arrVideoPath);
CGFloat totalDuration;
totalDuration = 0;
AVMutableComposition *mixComposition = [[AVMutableComposition alloc] init];
AVMutableCompositionTrack *videoTrack = [mixComposition addMutableTrackWithMediaType:AVMediaTypeVideo
preferredTrackID:kCMPersistentTrackID_Invalid];
AVMutableCompositionTrack *audioTrack = [mixComposition addMutableTrackWithMediaType:AVMediaTypeAudio
preferredTrackID:kCMPersistentTrackID_Invalid];
CMTime insertTime = kCMTimeZero;
for (id object in appdel.arrVideoPath)
{
AVAsset *asset = [AVAsset assetWithURL:[NSURL fileURLWithPath:object]];
CMTimeRange timeRange = CMTimeRangeMake(kCMTimeZero, asset.duration);
[videoTrack insertTimeRange:timeRange
ofTrack:[[asset tracksWithMediaType:AVMediaTypeVideo] objectAtIndex:0]
atTime:insertTime
error:nil];
[audioTrack insertTimeRange:timeRange
ofTrack:[[asset tracksWithMediaType:AVMediaTypeAudio] objectAtIndex:0]
atTime:insertTime
error:nil];
insertTime = CMTimeAdd(insertTime,asset.duration);
}
NSString* documentsDirectory= [self applicationDocumentsDirectory];
myDocumentPath= [documentsDirectory stringByAppendingPathComponent:@"merge_video.mp4"];
urlVideoMain = [[NSURL alloc] initFileURLWithPath: myDocumentPath];
if([[NSFileManager defaultManager] fileExistsAtPath:myDocumentPath])
{
[[NSFileManager defaultManager] removeItemAtPath:myDocumentPath error:nil];
}
AVAssetExportSession *exporter = [[AVAssetExportSession alloc] initWithAsset:mixComposition presetName:AVAssetExportPresetHighestQuality];
exporter.outputURL = urlVideoMain;
exporter.outputFileType = @"com.apple.quicktime-movie";
exporter.shouldOptimizeForNetworkUse = YES;
[exporter exportAsynchronouslyWithCompletionHandler:^{
switch ([exporter status])
{
case AVAssetExportSessionStatusFailed:
break;
case AVAssetExportSessionStatusCancelled:
break;
case AVAssetExportSessionStatusCompleted:
break;
default:
break;
}
}];
}
- (NSString*) applicationDocumentsDirectory
{
NSArray* paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString* basePath = ([paths count] > 0) ? [paths objectAtIndex:0] : nil;
return basePath;
}
回答2:
{
AVURLAsset *video01;
AVURLAsset *video02;
CGFloat totalDuration;
totalDuration = 0; //initialization, keep it 0
AVMutableComposition *composition = [AVMutableComposition composition];
AVMutableCompositionTrack *composedTrack = [composition addMutableTrackWithMediaType:AVMediaTypeVideo preferredTrackID:kCMPersistentTrackID_Invalid];
for (int i = 0; i < [arrVideoPath count]; i++) //arrVideoPath contains all video paths
{
if (i == 0)
{
video02 = [[AVURLAsset alloc] initWithURL:[NSURL fileURLWithPath:[arrVideoPath objectAtIndex:i]] options:nil];
[composedTrack insertTimeRange:CMTimeRangeMake(kCMTimeZero, video02.duration) ofTrack:[[video02 tracksWithMediaType:AVMediaTypeVideo] objectAtIndex:0] atTime:kCMTimeZero error:nil];
}
else
{
video01 = [[AVURLAsset alloc] initWithURL:[NSURL fileURLWithPath:[arrVideoPath objectAtIndex:i-1]] options:nil];
video02 = [[AVURLAsset alloc] initWithURL:[NSURL fileURLWithPath:[arrVideoPath objectAtIndex:i]] options:nil];
float duration1 = CMTimeGetSeconds([video01 duration]);
totalDuration = totalDuration + duration1;
CMTime time1 = CMTimeMakeWithSeconds(totalDuration, 1);
[composedTrack insertTimeRange:CMTimeRangeMake(kCMTimeZero, video02.duration) ofTrack:[[video02 tracksWithMediaType:AVMediaTypeVideo] objectAtIndex:0] atTime:time1 error:nil];
}
NSString* documentsDirectory= [self applicationDocumentsDirectory];
myDocumentPath= [documentsDirectory stringByAppendingPathComponent:@"merge_video.mp4"]; //myDocumentPath is NSString that gives path of output video(combined video)
urlVideoMain = [[NSURL alloc] initFileURLWithPath: myDocumentPath]; //urlVideoMain is Url of output video.
if([[NSFileManager defaultManager] fileExistsAtPath:myDocumentPath])
{
[[NSFileManager defaultManager] removeItemAtPath:myDocumentPath error:nil];
} //removes previous video at same path, essential
AVAssetExportSession *exporter = [[AVAssetExportSession alloc] initWithAsset:composition presetName:AVAssetExportPresetHighestQuality];
exporter.outputURL = urlVideoMain;
exporter.outputFileType = @"com.apple.quicktime-movie";
exporter.shouldOptimizeForNetworkUse = YES;
[exporter exportAsynchronouslyWithCompletionHandler:^{
switch ([exporter status]) {
case AVAssetExportSessionStatusFailed:
break;
case AVAssetExportSessionStatusCancelled:
break;
case AVAssetExportSessionStatusCompleted:
break;
default:
break;
}
}];
}
-(NSString*) applicationDocumentsDirectory
{
NSArray* paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString* basePath = ([paths count] > 0) ? [paths objectAtIndex:0] : nil;
return basePath;
}
来源:https://stackoverflow.com/questions/35859872/how-to-merge-multiple-videos-using-avasset-in-ios