【发布时间】:2015-11-19 14:03:59
【问题描述】:
问题:
我在获取使用 AVFoundation 创建的视频以在 VideoLayer 中显示时遇到问题,CALayer,尺寸正确。
示例:
这是视频的外观(在应用中显示给用户)
但是,导出后的视频如下:
详情
如您所见,它是一个方形视频,背景为绿色,视频适合指定帧。但是,生成的视频不适合用于包含它的CALayer(请参阅视频应拉伸到的黑色空间?)。
有时视频确实填充了图层,但被拉伸超出了边界(宽度过大或高度过大),并且通常无法保持视频的自然宽高比。
代码
CGRect displayedFrame = [self adjustedVideoBoundsFromVideo:gifVideo];//the cropped frame
CGRect renderFrame = [self renderSizeForGifVideo:gifVideo]; //the full rendersize
AVAsset * originalAsset = self.videoAsset;
AVAssetTrack * videoTrack = [[originalAsset tracksWithMediaType:AVMediaTypeVideo] objectAtIndex:0];
AVMutableComposition * mainComposition = [AVMutableComposition composition];
AVMutableCompositionTrack * compositionTrack = [mainComposition addMutableTrackWithMediaType:AVMediaTypeVideo preferredTrackID:kCMPersistentTrackID_Invalid];
[compositionTrack insertTimeRange:CMTimeRangeMake(kCMTimeZero, originalAsset.duration) ofTrack:videoTrack atTime:kCMTimeZero error:nil];
CALayer * parentLayer = [CALayer layer];
CALayer * backgroundLayer = [CALayer layer];
CALayer * videoLayer = [CALayer layer];
parentLayer.frame = renderFrame;
backgroundLayer.frame = parentLayer.bounds;
backgroundLayer.backgroundColor = self.backgroundColor.CGColor;
videoLayer.frame = displayedFrame;
[parentLayer addSublayer:backgroundLayer];
[parentLayer addSublayer:videoLayer];
AVMutableVideoComposition * videoComposition = [AVMutableVideoComposition videoComposition];
videoComposition.frameDuration = CMTimeMake(1, 30);
videoComposition.renderSize = CGSizeMake(renderFrame.size.width, renderFrame.size.height);
videoComposition.animationTool = [AVVideoCompositionCoreAnimationTool
videoCompositionCoreAnimationToolWithPostProcessingAsVideoLayer:videoLayer inLayer:parentLayer];
AVMutableVideoCompositionInstruction * instruction = [AVMutableVideoCompositionInstruction videoCompositionInstruction];
instruction.timeRange = CMTimeRangeMake(kCMTimeZero, mainComposition.duration);
AVMutableVideoCompositionLayerInstruction * layerInstruction = [AVMutableVideoCompositionLayerInstruction
videoCompositionLayerInstructionWithAssetTrack:videoTrack];
instruction.layerInstructions = @[layerInstruction];
videoComposition.instructions = @[instruction];
NSString* videoName = @"myNewGifVideo.mp4";
NSString *exportPath = [NSTemporaryDirectory() stringByAppendingPathComponent:videoName];
NSURL *exportUrl = [NSURL fileURLWithPath:exportPath];
if ([[NSFileManager defaultManager] fileExistsAtPath:exportPath])
{
[[NSFileManager defaultManager] removeItemAtPath:exportPath error:nil];
}
AVAssetExportSession * exporter = [[AVAssetExportSession alloc] initWithAsset:mainComposition presetName:AVAssetExportPresetHighestQuality];
exporter.videoComposition = videoComposition;
exporter.outputFileType = AVFileTypeMPEG4;
exporter.outputURL = exportUrl;
[exporter exportAsynchronouslyWithCompletionHandler:^
{
dispatch_async(dispatch_get_main_queue(), ^{
self.finalVideo = exportUrl;
[self.delegate shareManager:self didCreateVideo:self.finalVideo];
if (completionBlock){
completionBlock();
}
});
}];
我的尝试:
我尝试调整videoLayer 的frame、bounds 和contentGravity,但没有任何用处。
我尝试在AVMutableVideoCompositionLayerInstruction 中添加transform 以将视频缩放到displayRect 的大小(可以选择许多不同的视频,它们的宽度和高度是可变的。每个视频在结果视频,没有一个是正确的)转换有时会得到一个正确的维度(通常是宽度),但会弄乱另一个维度。如果我以稍微不同的方式裁剪/缩放视频,它永远不会始终正确地获得一个维度。
我尝试更改 videoComposition 的 renderSize 但这会破坏方形裁剪。
我似乎无法正确理解。如何让视频用displayedFrame 帧完美填充videoLayer(最后注意:视频的naturalSize 与displayedFrame 不同,这就是我尝试对其进行转换的原因)?
【问题讨论】:
标签: ios objective-c core-animation avfoundation calayer