AVPlayer plays video composition result incorrectly

前端 未结 1 1703
旧时难觅i
旧时难觅i 2020-12-17 03:42

I need a simple thing: play a video while rotating and applying CIFilter on it.

First, I create the player item:

AVPlay         


        
相关标签:
1条回答
  • 2020-12-17 04:08

    UPDATE: There comes out to be an easier way to "change" the AVPlayerItem video dimensions during playback - set the renderSize property of video composition (can be done using AVMutableVideoComposition class).

    MY OLD ANSWER BELOW:


    After a lot of debugging I understood the problem and found a solution. My initial guess that AVPlayer still considers the video being of the original size was correct. In the image below it is explained what was happening:

    As for the solution, I couldn't find a way to change the video size inside AVAsset or AVPlayerItem. So I just manipulated the video to fit the size and scale that AVPlayer was expecting, and then when playing in a player with correct aspect ratio and flag to scale and fill the player area - everything looks good. Here is the graphical explanation:

    And here goes the additional code that needs to be inserted in the applyingCIFiltersWithHandler block mentioned in the question:

    ... after Step 3 in the question codes above
    
    // make the frame the same aspect ratio as the original input frame
    // by adding empty spaces at the top and the bottom of the extent rectangle
    CGFloat newHeight = originalExtent.size.height * originalExtent.size.height / extent.size.height;
    CGFloat inset = (extent.size.height - newHeight) / 2;
    extent = CGRectInset(extent, 0, inset);
    sourceImage = [sourceImage imageByCroppingToRect:extent];
    
    // scale down to the original frame size
    CGFloat scale = originalExtent.size.height / newHeight;
    CGAffineTransform scaleTransform = CGAffineTransformMakeScale(scale, scale);
    [transformFilter setValue:sourceImage forKey: kCIInputImageKey];
    [transformFilter setValue: [NSValue valueWithCGAffineTransform: scaleTransform] forKey: kCIInputTransformKey];
    sourceImage = transformFilter.outputImage;
    
    // translate the frame to make it's origin start at (0, 0)
    CGAffineTransform translation = CGAffineTransformMakeTranslation(0, -inset * scale);
    [transformFilter setValue:sourceImage forKey: kCIInputImageKey];
    [transformFilter setValue: [NSValue valueWithCGAffineTransform: translation] forKey: kCIInputTransformKey];
    sourceImage = transformFilter.outputImage;
    
    0 讨论(0)
提交回复
热议问题