Search code examples
iosavfoundationavvideocomposition

Flip video horizontally on x- axis in objective c


I have two play two videos simultaneously on a view .Both videos would be same.

Now, my concern is the video on right is actually to be flipped horizontally along x-axis and then saved in photo library.I have tried googling a lot and found that CGAFFineRotateTransform can help but I am not able to use that in my code.Kindly help me to flip the video on right horizontally while keeping the scale and move same.

Any help or guidance in this direction would be appreciable .Thanks in advance!

Check the difference between video on left and right,video on left is complete but video on right is showing half video only


Solution

  • To just flip (mirror) the video horizontally, use a negative x-value for scaling:

    CGAffineTransform scale = CGAffineTransformMakeScale( -1.0, 1.0);
    

    Edit: Regarding your more general question on how to position tracks: For each video track involved:

    • build a bounding rect based on the original size of the track - this is the source rect
    • ask yourself where the track should end up, in terms of origin and size in the resulting video - this gives you the destination rect

    You can then derive the corresponding affine transform with a function like:

    CGAffineTransform NHB_CGAffineTransformMakeRectToRect( CGRect srcRect, CGRect dstRect)
    {
        CGAffineTransform t = CGAffineTransformIdentity;
        t = CGAffineTransformTranslate( t, dstRect.origin.x - fmin( 0., dstRect.size.width), dstRect.origin.y - fmin( 0., dstRect.size.height));
        t = CGAffineTransformScale( t, dstRect.size.width / srcRect.size.width, dstRect.size.height / srcRect.size.height);
        return t;
    }
    

    To mirror, provide a negative size for the corresponding axis (the - fmin(,) part compensates the offset).

    Given a video track and assuming, for example, the track should go mirrored to the right half of a 640x480 video, you can get the corresponding transform with:

    CGSize srcSize = videoTrack.naturalSize;
    CGRect srcRect = CGRectMake( 0, 0, srcSize.width, srcSize.height);
    CGRect dstRect = CGRectMake( 320, 0, -320, 480);
    CGAffineTransform t = NHB_CGAffineTransformMakeRectToRect(srcRect, dstRect);
    

    Of course this may stretch the video track; to keep the aspect ratio, you'll have to take the source size into account when calculating the destination rect.

    Some remarks:

    • note that in NHB_CGAffineTransformMakeRectToRect I deliberately chose to start with the identity matrix, and then add the required transforms one by one. This way much more complex transforms can be build, including rotation. As I said, try to get a grasp on affine transforms, they're really powerful
    • AVAssetTracks naturalSize sometimes returns confusing results for some videos with complex SAR/PAR definitions. To make this bullet proof, you'll have to derive the size from the dimensions in the corresponding format descriptions, but that's a whole new topic...