AVMutableComposition - Exporting wrong video transform
Asked Answered
S

1

6

After exporting VideoAsset:

the issues:

  1. Video orientation is not original transform
  2. Exported Video's layer seems to be always landscape.

trying to:

  1. transform video layer orientation - rotate to original orientation
  2. video layer size - make it full screen size (by original orientation)

some notes:

  • videoAsset's CGRect is opposite from beginning.

after export, video transform is wrong after export, video transform is wrong

tried to rotate with no success for full size layer tried to rotate with no success for full size layer

            AVURLAsset*videoAsset = [[AVURLAsset alloc]initWithURL:url options:nil];

            AVMutableComposition* mixComposition = [AVMixerBase compositionVideoTrackAssetUrl:videoAsset];

            AVMutableVideoComposition *videoComposition=[AVMutableVideoComposition videoComposition];
            videoComposition.frameDuration=CMTimeMake(1, 30); //frames per seconds
            videoComposition.renderSize = videoAsset.naturalSize;
            //videoComposition.renderScale = 1.0;

            videoComposition.animationTool = [AVVideoCompositionCoreAnimationTool videoCompositionCoreAnimationToolWithPostProcessingAsVideoLayer:videoLayer inLayer:parentLayer];


  AVMutableCompositionTrack *videoTrack = [[mixComposition tracksWithMediaType:AVMediaTypeVideo] objectAtIndex:0]; //was AVAssetTrack *videoTrack
    AVMutableVideoCompositionLayerInstruction *layerInstruction = [self layerInstructionAfterFixingOrientationForAsset:videoAsset
                                                                                                              forTrack:videoTrack   atTime:videoAsset.duration];



 AVMutableVideoCompositionLayerInstruction *layerInstruction =  [AVMutableVideoCompositionLayerInstruction  videoCompositionLayerInstructionWithAssetTrack:videoTrack];
    [layerInstruction setTransform:videoTrack.preferredTransform atTime:kCMTimeZero];
    [layerInstruction setOpacity:0.0 atTime:videoAsset.duration];




             AVMutableVideoCompositionInstruction *instruction = [AVMutableVideoCompositionInstruction videoCompositionInstruction];
                instruction.timeRange = CMTimeRangeMake(kCMTimeZero, [videoAsset duration]);
                instruction.layerInstructions = [NSArray arrayWithObject:layerInstruction];
                videoComposition.instructions = [NSArray arrayWithObject:instruction];

setting the track

            +(AVMutableComposition *)compositionVideoTrackAssetUrl:(AVURLAsset*)assetUrl{

                AVMutableComposition* mixComposition = [AVMutableComposition composition];
                AVMutableCompositionTrack *compositionVideoTrack = [mixComposition addMutableTrackWithMediaType:AVMediaTypeVideo preferredTrackID:kCMPersistentTrackID_Invalid];
                AVMutableCompositionTrack *compositionAudioTrack = [mixComposition addMutableTrackWithMediaType:AVMediaTypeAudio preferredTrackID:kCMPersistentTrackID_Invalid];


                AVAssetTrack *clipVideoTrack = [[assetUrl tracksWithMediaType:AVMediaTypeVideo] objectAtIndex:0];
                AVAssetTrack *clipAudioTrack = [[assetUrl tracksWithMediaType:AVMediaTypeAudio] objectAtIndex:0];
                [compositionVideoTrack insertTimeRange:CMTimeRangeMake(kCMTimeZero, assetUrl.duration) ofTrack:clipVideoTrack atTime:kCMTimeZero error:nil];
                [compositionAudioTrack insertTimeRange:CMTimeRangeMake(kCMTimeZero, assetUrl.duration) ofTrack:clipAudioTrack atTime:kCMTimeZero error:nil];
                [compositionVideoTrack setPreferredTransform:[[[assetUrl tracksWithMediaType:AVMediaTypeVideo] objectAtIndex:0] preferredTransform]];
                return mixComposition;
            }


so after researching all stack overflow discussions about export rotation,
I'm still having video rotation to size issue...
Subulate answered 16/7, 2017 at 10:19 Comment(5)
Did you solve it?Tanga
It seems that the solution on stackoverflow are outdated.Albuquerque
@RoiMulia, please see my answerSubulate
@HongZhou, please see my answerSubulate
Thanks could u share a bit on your answer?Albuquerque
S
0

OK, my answer code is not organized, but that will do the work:

NOTE: when you using "export Session", set render size as the code below :-

"[AVMixerBase shared].renderSize"

AVURLAsset*videoAsset = [[AVURLAsset alloc]initWithURL:url options:nil];
AVAssetTrack*videoAssetTrack = [[videoAsset tracksWithMediaType:AVMediaTypeVideo] firstObject];
[[AVMixerBase shared]setVideoAsset:videoAsset];

AVMutableComposition *mixComposition = [AVMixerBase compositionVideoTrackAssetUrl:videoAsset]; /* audio + video */
AVMutableCompositionTrack *compositionVideoTrack = [[mixComposition tracksWithMediaType:AVMediaTypeVideo] firstObject];
AVMutableVideoComposition *videoComposition = [AVMutableVideoComposition videoComposition];
AVMutableVideoCompositionLayerInstruction *layerInstruction = [AVMutableVideoCompositionLayerInstruction videoCompositionLayerInstructionWithAssetTrack:compositionVideoTrack];

CALayer *videoLayer = [self videoLayerAssetUrl:videoAsset];
CALayer *parentLayer = [CALayer layer];
CGSize videoSize = [videoAssetTrack naturalSize];
_segments = file.prefferedTranslation.customSegments;
NSLog(@"_segments %@",_segments);


//set render sizes:
//3.0_______COMBINE ALL
UIImageOrientation orientation = [self videoOrientation:videoAsset];
switch (orientation) {
    case UIImageOrientationUp:{ NSLog(@"Up"); //camera - lansdscape right
        [AVMixerBase shared].renderSize = CGSizeMake(videoSize.width, videoSize.height);
        break;
    }
    case UIImageOrientationDown:{ NSLog(@"Down"); //camera = lansdscape left
        [AVMixerBase shared].renderSize = CGSizeMake(videoSize.width, videoSize.height);
        videoLayer.affineTransform = CGAffineTransformMakeRotation(M_PI);
        break;
    }
    case UIImageOrientationLeft:{ NSLog(@"Left");

        break;
    }
    case UIImageOrientationRight:{ NSLog(@"Right");
        //camera = up
        CGAffineTransform t1 = CGAffineTransformMakeTranslation(videoSize.height, 0);
        CGAffineTransform t2 = CGAffineTransformRotate(t1, DEGREES_TO_RADIANS(90.0));
        [layerInstruction setTransform:t2 atTime:kCMTimeZero];
        [AVMixerBase shared].renderSize = CGSizeMake(videoSize.height, videoSize.width);
        break;
    }

    default:
        break;
}


  +(AVMutableComposition *)compositionVideoTrackAssetUrl:(AVURLAsset*)assetUrl{
AVMutableComposition* mixComposition = [AVMutableComposition composition];
mixComposition = [AVMixerBase addVideoTrackAssetUrl:assetUrl mixComposition:mixComposition];
return mixComposition;
}


   +(AVMutableComposition *)addVideoTrackAssetUrl:(AVURLAsset*)assetUrl mixComposition:(AVMutableComposition*)mixComposition{

AVMutableCompositionTrack *compositionVideoTrack = [mixComposition addMutableTrackWithMediaType:AVMediaTypeVideo preferredTrackID:kCMPersistentTrackID_Invalid];
AVMutableCompositionTrack *compositionAudioTrack = [mixComposition addMutableTrackWithMediaType:AVMediaTypeAudio preferredTrackID:kCMPersistentTrackID_Invalid];

AVAssetTrack *clipVideoTrack = [[assetUrl tracksWithMediaType:AVMediaTypeVideo] objectAtIndex:0];
AVAssetTrack *clipAudioTrack = [[assetUrl tracksWithMediaType:AVMediaTypeAudio] objectAtIndex:0];
[compositionVideoTrack insertTimeRange:CMTimeRangeMake(kCMTimeZero, assetUrl.duration) ofTrack:clipVideoTrack atTime:kCMTimeZero error:nil];
[compositionAudioTrack insertTimeRange:CMTimeRangeMake(kCMTimeZero, assetUrl.duration) ofTrack:clipAudioTrack atTime:kCMTimeZero error:nil];
[compositionVideoTrack setPreferredTransform:[[[assetUrl tracksWithMediaType:AVMediaTypeVideo] objectAtIndex:0] preferredTransform]];

return mixComposition;
}


-(CALayer*)videoLayerAssetUrl:(AVURLAsset*)assetUrl{
CGSize sizeOfVideo = [[[assetUrl tracksWithMediaType:AVMediaTypeVideo] objectAtIndex:0] naturalSize];
CALayer *videoLayer = [CALayer layer];
videoLayer.frame = CGRectMake(0, 0, sizeOfVideo.width, sizeOfVideo.height);
//    videoLayer.frame = CGRectMake(0, 0, sizeOfVideo.height, sizeOfVideo.width);
//    [videoLayer setAffineTransform:assetUrl.preferredTransform];


return videoLayer;
}
Subulate answered 17/9, 2017 at 21:34 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.