本圖片轉(zhuǎn)視頻加入了圖片縮放和轉(zhuǎn)場效果恩袱,通過向一個本地的黑色背景視頻black.mp4加入圖片的縮放和轉(zhuǎn)場動畫來實現(xiàn)
- (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;
//通過本地視頻地址創(chuàng)建視頻源
? ? 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];
//創(chuàng)建一個存放圖片圖層的數(shù)組
? ? 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"];
? ? ? ? }];
//創(chuàng)建視頻圖層并添加生成的圖片動畫
? ? ? ? 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];
//導(dǎo)出視頻
? ? 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);
? ? ? ? ? ? }
? ? ? ? }
? ? }];
}