Ios AVMutableComposition中的视频方向已更改

Ios AVMutableComposition中的视频方向已更改,ios,objective-c,avfoundation,avmutablecomposition,Ios,Objective C,Avfoundation,Avmutablecomposition,我用avmutablecomposition合并了四个肖像视频。但最终的视频方向改为横向。视频的尺寸是720x1280 我多次检查以解决该问题,但我的解决方案不起作用 这是我的密码: AVMutableComposition *composition = [AVMutableComposition composition]; AVMutableCompositionTrack *compositionVideoTrack = [composition addMutableTrac

我用avmutablecomposition合并了四个肖像视频。但最终的视频方向改为横向。视频的尺寸是720x1280

我多次检查以解决该问题,但我的解决方案不起作用

这是我的密码:

    AVMutableComposition *composition = [AVMutableComposition composition];
    AVMutableCompositionTrack *compositionVideoTrack = [composition addMutableTrackWithMediaType:AVMediaTypeVideo preferredTrackID:kCMPersistentTrackID_Invalid];
    AVMutableCompositionTrack *compositionAudioTrack = [composition addMutableTrackWithMediaType:AVMediaTypeAudio preferredTrackID:kCMPersistentTrackID_Invalid];
    AVMutableVideoComposition *videoComposition = [AVMutableVideoComposition videoComposition];
    videoComposition.frameDuration = CMTimeMake(1,30);
    videoComposition.renderScale = 1.0;

AVMutableVideoCompositionInstruction *instruction = [AVMutableVideoCompositionInstruction videoCompositionInstruction];

AVMutableVideoCompositionLayerInstruction *layerInstruction = [AVMutableVideoCompositionLayerInstruction videoCompositionLayerInstructionWithAssetTrack:compositionVideoTrack];



NSLog(@"%@",videoPathArray);

// Get only paths the user selected
NSMutableArray *array = [NSMutableArray array];
for(NSString* string in videoPathArray){
    if(![string isEqualToString:@""]){
        [array addObject:string];
    }
}

videoPathArray = array;
float time = 0;
CMTime startTime = kCMTimeZero;

for (int i = 0; i<videoPathArray.count; i++) {

    AVURLAsset *sourceAsset = [AVURLAsset URLAssetWithURL:[NSURL fileURLWithPath:[videoPathArray objectAtIndex:i]] options:[NSDictionary dictionaryWithObject:[NSNumber numberWithBool:YES] forKey:AVURLAssetPreferPreciseDurationAndTimingKey]];

    NSError *error = nil;

    if ([[sourceAsset tracksWithMediaType:AVMediaTypeVideo] count] != 0){

    BOOL ok = NO;
    AVAssetTrack *sourceVideoTrack = [[sourceAsset tracksWithMediaType:AVMediaTypeVideo] objectAtIndex:0];
    AVAssetTrack *sourceAudioTrack = [[sourceAsset tracksWithMediaType:AVMediaTypeAudio] objectAtIndex:0];

    CGSize temp = CGSizeApplyAffineTransform(sourceVideoTrack.naturalSize, sourceVideoTrack.preferredTransform);
    CGSize size = CGSizeMake(fabsf(temp.width), fabsf(temp.height));
    CGAffineTransform transform = sourceVideoTrack.preferredTransform;

    videoComposition.renderSize = sourceVideoTrack.naturalSize;
    if (size.width > size.height) {

        [layerInstruction setTransform:transform atTime:CMTimeMakeWithSeconds(time, 30)];
    } else {

        float s = size.width/size.height;

        CGAffineTransform newOne = CGAffineTransformConcat(transform, CGAffineTransformMakeScale(s,s));

        float x = (size.height - size.width*s)/2;

        CGAffineTransform newer = CGAffineTransformConcat(newOne, CGAffineTransformMakeTranslation(x, 0));

        [layerInstruction setTransform:newer atTime:CMTimeMakeWithSeconds(time, 30)];

    }

    if(i == 0 )
    {
        [compositionVideoTrack setPreferredTransform:sourceVideoTrack.preferredTransform];
    }

    ok = [compositionVideoTrack insertTimeRange:CMTimeRangeMake(kCMTimeZero, [sourceAsset duration]) ofTrack:sourceVideoTrack atTime:startTime error:&error];


    ok = [compositionAudioTrack insertTimeRange:CMTimeRangeMake(kCMTimeZero, [sourceAsset duration]) ofTrack:sourceAudioTrack atTime:startTime error:nil];

    if (!ok) {
        {
            [radialView4 setHidden:YES];
            NSLog(@"Export failed: %@", [[self.exportSession error] localizedDescription]);
            UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Error" message:@"Something Went Wrong :("  delegate:nil cancelButtonTitle:@"Ok" otherButtonTitles: nil, nil];
            [alert show];
            [radialView4 setHidden:YES];
            break;
        }

    }

    NSLog(@"\n source asset duration is %f \n source vid track timerange is %f %f \n composition duration is %f \n composition vid track time range is %f %f",CMTimeGetSeconds([sourceAsset duration]), CMTimeGetSeconds(sourceVideoTrack.timeRange.start),CMTimeGetSeconds(sourceVideoTrack.timeRange.duration),CMTimeGetSeconds([composition duration]), CMTimeGetSeconds(compositionVideoTrack.timeRange.start),CMTimeGetSeconds(compositionVideoTrack.timeRange.duration));

    startTime = CMTimeAdd(startTime, [sourceAsset duration]);
    }
}

instruction.layerInstructions = [NSArray arrayWithObject:layerInstruction];
instruction.timeRange = compositionVideoTrack.timeRange;

videoComposition.instructions = [NSArray arrayWithObject:instruction];

NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *myPathDocs =  [documentsDirectory stringByAppendingPathComponent:
                         [NSString stringWithFormat:@"RampMergedVideo.mov"]];
unlink([myPathDocs UTF8String]);
NSURL *url = [NSURL fileURLWithPath:myPathDocs];

AVAssetExportSession *exporter = [[AVAssetExportSession alloc] initWithAsset:composition
                                                                  presetName:AVAssetExportPreset1280x720];
exporter.outputURL=url;
exporter.outputFileType = AVFileTypeQuickTimeMovie;
exporter.shouldOptimizeForNetworkUse = YES;
[exporter exportAsynchronouslyWithCompletionHandler:^{
    dispatch_async(dispatch_get_main_queue(), ^{

        switch ([exporter status]) {
            case AVAssetExportSessionStatusFailed:
                NSLog(@"Export failed: %@", [exporter error]);
                break;
            case AVAssetExportSessionStatusCancelled:
                NSLog(@"Export canceled");
                break;
            case AVAssetExportSessionStatusCompleted:{

                break;
            }
            default:
                break;
        }
        if (exporter.status != AVAssetExportSessionStatusCompleted){
            NSLog(@"Retry export");

        }

    });
}];
AVMutableComposition*composition=[AVMutableComposition];
AVMutableCompositionTrack*compositionVideoTrack=[composition addMutableTrackWithMediaType:AVMediaTypeVideo preferredTrackID:kCMPersistentTrackID_无效];
AVMutableCompositionTrack*compositionAudioTrack=[CompositionAddMutableTrackWithMediaType:AVMediaTypeAudio preferredTrackID:kCMPersistentTrackID_无效];
AVMutableVideoComposition*videoComposition=[AVMutableVideoComposition];
videoComposition.frameDuration=CMTimeMake(1,30);
videoComposition.renderScale=1.0;
AVMutableVideoCompositionInstruction*指令=[AVMutableVideoCompositionInstruction videoCompositionInstruction];
AvmutableVideoCompositionLayerStruction*LayerStruction=[AvmutableVideoCompositionLayerStruction VideoCompositionLayerStructionWithAssetTrack:compositionVideoTrack];
NSLog(@“%@”,视频路径阵列);
//仅获取用户选择的路径
NSMutableArray*数组=[NSMutableArray];
for(视频路径阵列中的NSString*字符串){
如果(![string IsequalString:@”“){
[数组addObject:string];
}
}
videoPathArray=阵列;
浮动时间=0;
CMTime startTime=KCMTIME0;
用于(int i=0;i size.height){
[层结构设置转换:转换时间:CMTimeMakeWithSeconds(时间,30)];
}否则{
浮动s=尺寸.宽度/尺寸.高度;
CGAffineTransform newOne=CGAffineTransformConcat(变换,CGAffineTransformMakeScale(s,s));
浮动x=(size.height-size.width*s)/2;
CGAffineTransform newer=CGAffineTransformConcat(newOne,CGAffineTransformMakeTransform makeTranslation(x,0));
[layerInstruction setTransform:LayerAttime:CMTimeMakeWithSeconds(时间,30)];
}
如果(i==0)
{
[compositionVideoTrack setPreferredTransform:sourceVideoTrack.preferredTransform];
}
ok=[compositionVideoTrack insertTimeRange:CMTimeRangeMake(kCMTimeZero,[sourceAsset duration])of Track:sourceVideoTrack时间:起始时间错误:&error];
ok=[compositionAudioTrack insertTimeRange:CMTimeRangeMake(kCMTimeZero,[sourceAsset duration])of Track:sourceAudioTrack时间:startTime错误:nil];
如果(!ok){
{
[radialView4设置隐藏:是];
NSLog(@“导出失败:%@,[[self.exportSession error]localizedDescription]);
UIAlertView*alert=[[UIAlertView alloc]initWithTitle:@“错误”消息:@“出现问题:”(“委托:nil CancelButtontile:@“确定”其他Buttontiles:nil,nil];
[警报显示];
[radialView4设置隐藏:是];
打破
}
}
NSLog(@“\n源资产持续时间为%f\n源视频曲目时间范围为%f%f\n合成持续时间为%f\n合成视频曲目时间范围为%f%f”、CMTimeGetSeconds([sourceAsset duration])、CMTimeGetSeconds(sourceVideoTrack.timerange.start)、CMTimeGetSeconds(sourceVideoTrack.timerange.duration)、CMTimeGetSeconds([composition duration]),CMTimeGetSeconds(compositionVideoTrack.timeRange.start),CMTimeGetSeconds(compositionVideoTrack.timeRange.duration));
startTime=CMTimeAdd(startTime,[sourceAsset duration]);
}
}
instruction.layerInstructions=[NSArray arrayWithObject:layerInstruction];
instruction.timeRange=compositionVideoTrack.timeRange;
videoComposition.instructions=[NSArray arrayWithObject:instruction];
NSArray*Path=NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,NSUserDomainMask,是);
NSString*documentsDirectory=[paths objectAtIndex:0];
NSString*myPathDocs=[DocumentsDirectoryStringByAppendingPathComponent:
[NSString stringWithFormat:@“RampMergedVideo.mov”];
取消链接([myPathDocs UTF8String]);
NSURL*url=[NSURL fileURLWithPath:myPathDocs];
AVAssetExportSession*导出器=[[AVAssetExportSession alloc]initWithAsset:composition
预设名称:AVAssetExportPreset1280x720];
exporter.outputURL=url;
exporter.outputFileType=AVFileTypeQuickTimeMovie;
exporter.shouldOptimizationForNetworkUse=是;
[exporter exportAsynchronouslyWithCompletionHandler:^{
dispatch\u async(dispatch\u get\u main\u queue()^{
开关([导出器状态]){
案例AvassetExportSessionStatus失败:
NSLog(@“导出失败:%@,[导出程序错误]);
打破
案例AvassetExportSessionStatus取消:
NSLog(“导出已取消”);
打破
案例AvassetExportSessionStatus已完成:{
打破
}
违约:
打破
}
if(exporter.status!=AVAssetExportSessionStatusCompleted){
NSLog(@“重试导出”);
}
});
}];
视频路径阵列:( “/var/mobile/Containers/Data/Application/0C143367-043C-410F-B5D0-50D7DB097CBE/Documents/trimmedFirst.mov”, “/var/mobile/Containers/Data/Application/0C143367-043C-410F-B5D0-50D7DB097CBE/Documents/trimFilterApplied.mov”, “/var/mobile/Containers/Data/Application/0C143367-043C-410F-B5D0-50D7DB097CBE/Documents/trimmedSecond.mov”, “/var/mobile/Containers/Data/Application/0C143367-043C-410F-B5D0-50D7DB097CBE/Documents/ramp_logo_trait.mov” )

有人能就我的问题提出建议吗