Я работаю над объединением двух видео и обнаружил странную проблему: когда я пытаюсь объединить портретное видео и альбомное видео, на выходе отображается альбомная версия видео в портретном режиме, чего я не хочу. Я почти уверен, что мне не хватает чего-то фундаментального в управлении ориентацией.
Мой код здесь:
NSMutableArray *videoClipPaths=[[NSMutableArray alloc]init];
[videoClipPaths addObject:[NSURL URLWithString:videoBundleURL1]];
[videoClipPaths addObject:[NSURL URLWithString:videoBundleURL2]];
[videoClipPaths addObject:[NSURL URLWithString:videoBundleURL1]];
float start_time=startSeconds;
float end_time=endSeconds;
AVMutableComposition *mixComposition = [AVMutableComposition composition];
AVMutableCompositionTrack *compositionTrack = [mixComposition addMutableTrackWithMediaType:AVMediaTypeVideo preferredTrackID:kCMPersistentTrackID_Invalid];
AVMutableCompositionTrack *compositionTrack2 = [mixComposition addMutableTrackWithMediaType:AVMediaTypeAudio preferredTrackID:kCMPersistentTrackID_Invalid];
__block CMTime time = kCMTimeZero;
__block CGAffineTransform translate;
__block CGSize size;
for (int i=0; i<[videoClipPaths count]; i++)
{
AVURLAsset *assetClip = [AVURLAsset URLAssetWithURL:[videoClipPaths objectAtIndex:i] options:nil];
AVAssetTrack *clipVideoTrackB = [[assetClip tracksWithMediaType:AVMediaTypeVideo] objectAtIndex:0];
AVAsset *anAsset = [[AVURLAsset alloc] initWithURL:[videoClipPaths objectAtIndex:i] options:nil];
CMTime start;
CMTime duration;
CMTimeRange video_timeRange;
if (i==0){
start = CMTimeMakeWithSeconds(0.0f, anAsset.duration.timescale);
duration = CMTimeMakeWithSeconds(start_time, anAsset.duration.timescale);
video_timeRange = CMTimeRangeMake(kCMTimeZero,duration);
[compositionTrack insertTimeRange:video_timeRange ofTrack:clipVideoTrackB atTime:start error:nil];
size = CGSizeMake(clipVideoTrackB.naturalSize.height, clipVideoTrackB.naturalSize.height);
translate = CGAffineTransformMakeTranslation(-420, 0);
CGAffineTransform newTransform = CGAffineTransformConcat(translate, clipVideoTrackB.preferredTransform);
[compositionTrack setPreferredTransform:newTransform];
time = CMTimeAdd(time, duration);
}else if (i==1){
CMTime duration = anAsset.duration;
float seconds = CMTimeGetSeconds(duration);
start = CMTimeMakeWithSeconds(start_time, anAsset.duration.timescale);
duration = CMTimeMakeWithSeconds(seconds, anAsset.duration.timescale);
video_timeRange = CMTimeRangeMake(kCMTimeZero,duration);
[compositionTrack insertTimeRange:video_timeRange ofTrack:clipVideoTrackB atTime:start error:nil];
translate = CGAffineTransformMakeTranslation(-420, 0);
CGAffineTransform newTransform = CGAffineTransformConcat(translate, clipVideoTrackB.preferredTransform);
[compositionTrack setPreferredTransform:newTransform];
time = CMTimeAdd(time, duration);
}
else if (i==2){
CMTime duration = anAsset.duration;
float seconds = CMTimeGetSeconds(duration);
start = CMTimeMakeWithSeconds(end_time, anAsset.duration.timescale);
duration = CMTimeMakeWithSeconds(seconds-start_time, anAsset.duration.timescale);
// duration = CMTimeMakeWithSeconds(anAsset.duration.timescale, anAsset.duration.timescale);
video_timeRange = CMTimeRangeMake(CMTimeMakeWithSeconds(start_time, anAsset.duration.timescale),duration);
[compositionTrack insertTimeRange:video_timeRange ofTrack:clipVideoTrackB atTime:kCMTimeInvalid error:nil];
translate = CGAffineTransformMakeTranslation(-420, 0);
CGAffineTransform newTransform = CGAffineTransformConcat(translate, clipVideoTrackB.preferredTransform);
[compositionTrack setPreferredTransform:newTransform];
time = CMTimeAdd(time, duration);
}
// video_timeRange = CMTimeRangeMake(start,duration);
//merge audio of video files
AVAssetTrack *clipVideoTrackB1 = [[assetClip tracksWithMediaType:AVMediaTypeAudio] objectAtIndex:0];
/*CMTime start1;
CMTime duration1;
CMTimeRange video_timeRange1;
if (i==0){
start1 = CMTimeMakeWithSeconds(0.0, anAsset.duration.timescale);
duration1 = CMTimeMakeWithSeconds(start_time, anAsset.duration.timescale);
}else if (i==1){
start1 = CMTimeMakeWithSeconds(start_time, anAsset.duration.timescale);
duration1 = CMTimeMakeWithSeconds(end_time-start_time, anAsset.duration.timescale);
}
else if (i==2){
start1 = CMTimeMakeWithSeconds(end_time, anAsset.duration.timescale);
duration1 = CMTimeMakeWithSeconds(anAsset.duration.timescale, anAsset.duration.timescale);
}
video_timeRange1 = CMTimeRangeMake(start,duration);*/
[compositionTrack2 insertTimeRange:video_timeRange ofTrack:clipVideoTrackB1 atTime:start error:nil];
}
Приведенный выше код определяет временной диапазон для 3 видео (на самом деле 2 видео), но мне нужно вставить 2-е видео внутри 1-го видео в заданный интервал времени.
Приведенный ниже код создаст изменяемую композицию всех активов, которые у меня есть:
AVMutableVideoCompositionInstruction *vtemp = [AVMutableVideoCompositionInstruction videoCompositionInstruction];
vtemp.timeRange = CMTimeRangeMake(kCMTimeZero, time);
NSLog(@"\nInstruction vtemp's time range is %f %f", CMTimeGetSeconds( vtemp.timeRange.start),
CMTimeGetSeconds(vtemp.timeRange.duration));
// Also tried videoCompositionLayerInstructionWithAssetTrack:compositionVideoTrack
AVMutableVideoCompositionLayerInstruction *vLayerInstruction = [AVMutableVideoCompositionLayerInstruction
videoCompositionLayerInstructionWithAssetTrack:compositionTrack];
[vLayerInstruction setTransform:compositionTrack.preferredTransform atTime:kCMTimeZero];
vtemp.layerInstructions = @[vLayerInstruction];
AVMutableVideoComposition *videoComposition = [AVMutableVideoComposition videoComposition];
videoComposition.renderSize = size;
videoComposition.frameDuration = CMTimeMake(1,30);
videoComposition.instructions = @[vtemp];
AVAssetExportSession *exporter = [[AVAssetExportSession alloc] initWithAsset:mixComposition presetName:AVAssetExportPresetHighestQuality];
NSParameterAssert(exporter != nil);
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsPath = [paths objectAtIndex:0]; //Get the docs directory
documentsPath=[documentsPath stringByAppendingString:@"/MergeVideos"];
.....остальное сохранение видео в библиотеку Фото
Заранее спасибо !!