简体   繁体   English

是否可以使用 AVAssetWriter 完全裁剪视频?

[英]Is it possible fully crop a video with AVAssetWriter?

I am using AVAssetWriter to create a video file, I want to crop it and came upon the keys for AVVideoCleanApertureKey .我正在使用 AVAssetWriter 创建一个视频文件,我想裁剪它并找到AVVideoCleanApertureKey的键。 This lets me set a viewport for the video, which looks like it is cropping the video.这让我可以为视频设置一个视口,看起来像是在裁剪视频。 But in reality it doesn't, the full frame is still present in the video file, and wether the "crop" is used seems to be up to the view player.但实际上并非如此,视频文件中仍然存在全帧,是否使用“裁剪”似乎取决于视图播放器。

So, is there a way to make discard the "outside" data around the viewport with AVAssetWriter?那么,有没有办法用 AVAssetWriter 丢弃视口周围的“外部”数据? Or do I need to change my approach completely.还是我需要完全改变我的方法。

These images show the same video file, but only QuickTime cares about the viewport.这些图像显示相同的视频文件,但只有 QuickTime 关心视口。

在此处输入图像描述

I believe the direct answer to the question is NO.我相信这个问题的直接答案是否定的。 So in the end I switched over to AVMutableVideoComposition and AVAssetExportSession as other answers around the web suggested.所以最后我切换到AVMutableVideoCompositionAVAssetExportSession作为 web 建议的其他答案。

    AVAsset *video = [AVAsset assetWithURL:outputURL];
    AVAssetTrack *assetVideoTrack = [[video tracksWithMediaType:AVMediaTypeVideo] lastObject];
    AVMutableVideoCompositionLayerInstruction *layerInstruction = [AVMutableVideoCompositionLayerInstruction videoCompositionLayerInstructionWithAssetTrack:assetVideoTrack];
    CGAffineTransform transform = CGAffineTransformMakeTranslation(-self.rect.origin.x, -self.rect.origin.y);
    [layerInstruction setTransform:transform atTime:kCMTimeZero];
    AVMutableVideoCompositionInstruction *instruction = [AVMutableVideoCompositionInstruction videoCompositionInstruction];
    instruction.layerInstructions = @[layerInstruction];
    instruction.timeRange = assetVideoTrack.timeRange;
    AVMutableVideoComposition *videoComposition = [AVMutableVideoComposition videoComposition];
    
    // https://stackoverflow.com/questions/22883525/avassetexportsession-giving-me-a-green-border-on-right-and-bottom-of-output-vide
    videoComposition.renderSize = CGSizeMake(floor(self.rect.size.width / 16) * 16, 
                                             floor(self.rect.size.height / 16) * 16);
    videoComposition.renderScale = 1.0;
    
    videoComposition.frameDuration = CMTimeMake(1, 30);
    videoComposition.instructions = @[instruction];
    AVAssetExportSession *exportSession = [AVAssetExportSession exportSessionWithAsset:video presetName:AVAssetExportPreset1280x720];
    exportSession.shouldOptimizeForNetworkUse = NO;
    exportSession.outputFileType = AVFileTypeMPEG4;
    exportSession.videoComposition = videoComposition;
    exportSession.outputURL = outputURL2;

    [exportSession exportAsynchronouslyWithCompletionHandler:^{ 
        NSLog(@"done processing video!");
    }];

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM