本图片转视频加入了图片缩放和转场效果,通过向一个本地的黑色背景视频black.mp4加入图片的缩放和转场动画来实现
- (void)videoAnimation:(NSArray *)imgArr (void(^)(NSURL*))success{
//每张图片显示的时间
NSInteger picTime = 3;
//获取背景视频地址
NSString *videoPath = [[NSBundle mainBundle] pathForResource:@"black" ofType:@"mp4"];
NSString *cachePath = [NSTemporaryDirectory() stringByAppendingPathComponent:@"imagesComposition.mp4"];
if ([[NSFileManager defaultManager] fileExistsAtPath:cachePath])
{
[[NSFileManager defaultManager] removeItemAtPath:cachePath error:nil];
}
NSURL *exportUrl = [NSURLfileURLWithPath:cachePath];
//视频时长
NSInteger tempDuration =self.imgArr.count*picTime+0.1*self.imgArr.count;
NSInteger duration = tempDuration >180.0?180.0:tempDuration;
//通过本地视频地址创建视频源
AVURLAsset*videoAsset = [AVURLAsset assetWithURL:[NSURL fileURLWithPath:videoPath]];
AVMutableComposition *mutableComposition = [AVMutableComposition composition];
//获取视频轨道
AVMutableCompositionTrack *videoCompositionTrack = [mutableComposition addMutableTrackWithMediaType:AVMediaTypeVideo preferredTrackID:kCMPersistentTrackID_Invalid];
AVAssetTrack *videoAssetTrack = [videoAsset tracksWithMediaType:AVMediaTypeVideo].firstObject;
CMTimeValue value = videoAsset.duration.timescale* duration;
CMTime endTime =CMTimeMake(value, videoAsset.duration.timescale);
CMTimeRange timeR = CMTimeRangeMake(kCMTimeZero, endTime);
[videoCompositionTrack insertTimeRange:timeR ofTrack:videoAssetTrack atTime:kCMTimeZero error:nil];
//获取视频轨道上的素材添加到最终合成的视频轨道中
AVMutableVideoCompositionInstruction *videoCompostionInstruction = [AVMutableVideoCompositionInstruction videoCompositionInstruction];
videoCompostionInstruction.timeRange= timeR;
AVMutableVideoCompositionLayerInstruction *videoLayerInstruction = [AVMutableVideoCompositionLayerInstruction videoCompositionLayerInstructionWithAssetTrack:videoCompositionTrack];
[videoLayerInstruction setTransform:videoAssetTrack.preferredTransform atTime:kCMTimeZero];
[videoLayerInstruction setOpacity:0 atTime:endTime];
videoCompostionInstruction.layerInstructions=@[videoLayerInstruction];
AVMutableVideoComposition *mutableVideoComposition = [AVMutableVideoComposition videoComposition];
mutableVideoComposition.renderSize=CGSizeMake(720,1280);
mutableVideoComposition.frameDuration=CMTimeMake(1,25);
mutableVideoComposition.instructions=@[videoCompostionInstruction];
//创建一个存放图片图层的数组
CALayer*bgLayer = [[CALayer alloc]init];
bgLayer.frame=CGRectMake(0,0,720,1280);
bgLayer.position=CGPointMake(360,640);
NSMutableArray *imageLayers = [NSMutableArray array];
for(UIImage*img in self.imgArr) {
CALayer*imageL = [[CALayer alloc]init];
imageL.contents= (__bridgeid)img.CGImage;
imageL.bounds=CGRectMake(0,0,720,1280);
imageL.contentsGravity = kCAGravityResizeAspect;
imageL.backgroundColor = [UIColor blackColor].CGColor;
imageL.anchorPoint=CGPointMake(0,0);
[bgLayer addSublayer:imageL];
[imageLayers addObject:imageL];
}
//图片图层添加动画效果
[imageLayers enumerateObjectsUsingBlock:^(id _Nonnullobj,NSUIntegeridx,BOOL*_Nonnullstop) {
CABasicAnimation*animation1 = [CABasicAnimation animationWithKeyPath:@"transform.scale"];
animation1.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];
animation1.removedOnCompletion=false;
animation1.beginTime=1.1+picTime* idx;
animation1.fromValue= [NSNumber numberWithFloat:1.0];
animation1.toValue= [NSNumber numberWithFloat:1.1];
animation1.duration=2;
animation1.fillMode=kCAFillModeBoth;
[(CALayer*)obj addAnimation:animation1 forKey:@"transform.scale"];
CABasicAnimation*animation2 = [CABasicAnimation animationWithKeyPath:@"position"];
animation2.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];
animation2.removedOnCompletion=false;
animation2.beginTime=0.1+picTime* idx;
animation2.fromValue= [NSValue valueWithCGPoint:CGPointMake(720* idx,0)];
animation2.toValue= [NSValue valueWithCGPoint:CGPointMake(0,0)];
animation2.duration=1;
animation2.fillMode=kCAFillModeBoth;
[(CALayer*)obj addAnimation:animation2forKey:@"position"];
}];
//创建视频图层并添加生成的图片动画
CALayer*parentLayer = [[CALayer alloc]init];
CALayer*videoLayer = [[CALayer alloc]init];
parentLayer.frame=CGRectMake(0,0,720,1280);
videoLayer.frame=CGRectMake(0,0,720,1280);
[parentLayer addSublayer:videoLayer];
[parentLayer addSublayer:bgLayer];
parentLayer.geometryFlipped=YES;
//视频图层加入最终合成的视频轨道中
mutableVideoComposition.animationTool = [AVVideoCompositionCoreAnimationTool videoCompositionCoreAnimationToolWithPostProcessingAsVideoLayer:videoLayer inLayer:parentLayer];
//导出视频
AVAssetExportSession *assetExport = [AVAssetExportSession exportSessionWithAsset:mutableComposition presetName:AVAssetExportPresetHighestQuality];
assetExport.outputFileType = AVFileTypeMPEG4;
assetExport.outputURL= exportUrl;
assetExport.shouldOptimizeForNetworkUse = YES;
assetExport.videoComposition= mutableVideoComposition;
[assetExport exportAsynchronouslyWithCompletionHandler:^{
if (assetExport.status == AVAssetExportSessionStatusCompleted) {
if(success) {
success(exportUrl);
}
}
}];
}
网友评论