I want to export this amazing animation into my video file with AVFoundation.
let animationView = LAAnimationView.animationNamed("hamburger")
let parentLayer: CALayer = CALayer()
let videoLayer: CALayer = CALayer()
videoLayer.frame = CGRect(x: 0, y: 0, width: renderSize.width, height: renderSize.height)
parentLayer.frame = CGRect(x: 0, y: 0, width: renderSize.width, height: renderSize.height)
parentLayer.addSublayer(videoLayer)
parentLayer.addSublayer(animationView.layer)
composition.animationTool = AVVideoCompositionCoreAnimationTool(postProcessingAsVideoLayer: videoLayer, in: parentLayer)
but the animation does not shown in the composed video. I thought the animation begin time is not correct. It should be AVCoreAnimationBeginTimeAtZero
can you add this feature in this amazing animation library ?
Im not sure what it would take to support this but I will add it to our research list!
Is there any progress in this issue? I am also trying to add Lottie animation to video.
Try Lottie 2.0! It now more closely follows CAAnimaiton rules.
I can confirm that it's possible to include Lottie animations when exporting videos with AVFoundation. I'm using version 2.0.5.
Do you have code that enables this?
On Mon, Aug 21, 2017 at 4:38 AM jakob svenningsson notifications@github.com
wrote:
I can confirm that it's possible to include Lottie animations when
exporting videos with AVFoundation. I'm using version 2.0.5.—
You are receiving this because you are subscribed to this thread.
Reply to this email directly, view it on GitHub
https://github.com/airbnb/lottie-ios/issues/30#issuecomment-323721724,
or mute the thread
https://github.com/notifications/unsubscribe-auth/AMwOz-zo6GrgGVxhjvTUMbYQu9syoE1sks5saWw8gaJpZM4L3HTw
.
You just add the layer from the LOTAnimatioView class the same way as if you'd add a normal CALayer to a video using AVFoundation. I can recommend the following tutorial: https://www.raywenderlich.com/30200/avfoundation-tutorial-adding-overlays-and-animations-to-videos. In However there is one difference. I had to call the play method of the LOTAnimationView class before I merged it with the videolayer.
Thanks. Actually it doesn't quite work well.
However the animation is actually not rendered correctly depending on
device etc.
The animation timespace is not linked to the video timespace so you'll
notice that timing is off.
On Mon, Aug 21, 2017 at 1:24 PM Jakob svenningsson notifications@github.com
wrote:
You just add the layer from the LOTAnimatioView class the same way as if
you'd add a normal CALayer to a video using AVFoundation. I can recommend
the following tutorial:
https://www.raywenderlich.com/30200/avfoundation-tutorial-adding-overlays-and-animations-to-videos.
In However there is one difference. I had to call the play method of the
LOTAnimationView class before I merged it with the videolayer.—
You are receiving this because you commented.Reply to this email directly, view it on GitHub
https://github.com/airbnb/lottie-ios/issues/30#issuecomment-323843573,
or mute the thread
https://github.com/notifications/unsubscribe-auth/AMwOzzJ9YnTYINGUyzXjxkzc-THtRrBKks5saeeEgaJpZM4L3HTw
.
You have to change the FPS of the animation to the same FPS as your recording. You also have to set the start frame manually in order to sync the animation with the video.
If you save the process of the animation when you start record, you can set the start of the animation like this:
lottieLayer.animationProgress = animationStart
lottieLayer.loopAnimation = true
lottieLayer.play()
@jakobsvenningsson - I did try your method but it's not working at saving time with avexportsession. I made one method to start animation at static time like below
NSTimeInterval duration = ((_sceneModel.endFrame.floatValue - _sceneModel.startFrame.floatValue) / _sceneModel.framerate.floatValue);
CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath:@"currentFrame"];
animation.speed = 1.0;
animation.fromValue = _sceneModel.startFrame;
animation.toValue = _sceneModel.endFrame;
animation.duration = duration;
animation.fillMode = kCAFillModeBoth;
animation.repeatCount = _loopAnimation ? HUGE_VALF : 1;
animation.autoreverses = _autoReverseAnimation;
animation.delegate = self;
animation.removedOnCompletion = NO;
animation.beginTime = 0.2;
[_compContainer addAnimation:animation forKey:kCompContainerAnimationKey];
// Save video code
[parentLayer addSublayer:overlayLayer];
self.videoComposition.animationTool = [AVVideoCompositionCoreAnimationTool
videoCompositionCoreAnimationToolWithPostProcessingAsVideoLayer:videoLayer
inLayer:parentLayer];
I am adding LOTAnimationView layer in overlay layer. But animation is not working.
Just tried myself with no luck. The animation is not playing at all. I have called play as well as set the frame and the speed. Are there any special requirements of the After Effects file? Is there an option to not remove on completion in after effects?
Animation will not work in AVAssetExport session for new Lottie. Use Lottie 1.0. In new one they shifted all animation logic to frame by frame. And this will cause timing issue and slowness of animation at export. @buba447 - Will you please go back to Lottie 1.0 like animation for future versions? Because even in current version if we will have multiple heavy tasks of ARKIT or COREML then this frame by frame animation causing delays. And everything seems to work in Lottie 1.0. But there are so many limitations in it.
Even in new Lottie animation stops after pushing to new view controller. OR putting app in background.
using Lottie v2.1.4 and the animation (using "LottieLogo2") renders and runs following AVAssetExportSession
but the frame rate is noticeably slower than it is when animating by itself even though I tried to set speed to 1 for both scenarios. I didn't notice a FPS attribute or any way to sync it to what's going on in the video.
will tinker with it as I literally just added it to my app.
@amrittrivedir i use lottie-ios 1.0.4, and i found when export custom layer property animation(LOTStrokeShapeLayer), it will not work, the preview is ok, but the other properties are ok(preview&export).
my app is 猫饼.
Could someone provide working code?
Because after a lot of attempts with different versions of lottie, all that I've achieved is rendering static image in video from animation
@jakobsvenningsson
It's not animating in the exported video. Is there anything wrong about my code below?
NSURL *url = [[NSBundle mainBundle] URLForResource:@"test0" withExtension:@"mov"];
AVAsset *asset = [AVURLAsset assetWithURL:url];
AVAssetTrack *assetTrack = [asset tracksWithMediaType:AVMediaTypeVideo].firstObject;
CGSize naturalSize = assetTrack.naturalSize;
AVMutableComposition *mutableComposition = [AVMutableComposition composition];
AVMutableCompositionTrack *mutableCompositionTrack = [mutableComposition addMutableTrackWithMediaType:AVMediaTypeVideo preferredTrackID:kCMPersistentTrackID_Invalid];
[mutableCompositionTrack insertTimeRange:CMTimeRangeMake(kCMTimeZero, asset.duration) ofTrack:assetTrack atTime:kCMTimeZero error:nil];
AVMutableVideoCompositionInstruction *mainInstruction = [AVMutableVideoCompositionInstruction videoCompositionInstruction];
mainInstruction.timeRange = CMTimeRangeMake(kCMTimeZero, asset.duration);
AVMutableVideoCompositionLayerInstruction *layerInstruction = [AVMutableVideoCompositionLayerInstruction videoCompositionLayerInstructionWithAssetTrack:assetTrack];
[layerInstruction setTransform:CGAffineTransformIdentity atTime:kCMTimeZero];
mainInstruction.layerInstructions = @[layerInstruction];
AVMutableVideoComposition *videoComposition = [AVMutableVideoComposition videoComposition];
videoComposition.instructions = @[mainInstruction];
videoComposition.frameDuration = assetTrack.minFrameDuration;
videoComposition.renderSize = naturalSize;
LOTAnimationView *animationView = [LOTAnimationView animationNamed:@"LottieLogo1" inBundle:[NSBundle mainBundle]];
animationView.frame = CGRectMake(0, 0, 300, 300);
animationView.contentMode = UIViewContentModeScaleAspectFit;
[animationView play];
CALayer *videoLayer = [CALayer layer];
CALayer *parentLayer = [CALayer layer];
parentLayer.frame = CGRectMake(0, 0, naturalSize.width, naturalSize.height);
videoLayer.frame = CGRectMake(0, 0, naturalSize.width, naturalSize.height);
[parentLayer addSublayer:videoLayer];
parentLayer.geometryFlipped = YES;
[parentLayer addSublayer:animationView.layer];
AVVideoCompositionCoreAnimationTool *animationTool = [AVVideoCompositionCoreAnimationTool videoCompositionCoreAnimationToolWithPostProcessingAsVideoLayer:videoLayer inLayer:parentLayer];
videoComposition.animationTool = animationTool;
NSURL *exportURL = [NSURL fileURLWithPath:[[NSTemporaryDirectory() stringByAppendingPathComponent:[NSUUID UUID].UUIDString] stringByAppendingPathExtension:@"mov"]];
NSLog(@"%@", exportURL.path);
AVAssetExportSession *exportSession = [AVAssetExportSession exportSessionWithAsset:asset presetName:AVAssetExportPresetLowQuality];
exportSession.videoComposition = videoComposition;
exportSession.outputURL = exportURL;
exportSession.outputFileType = AVFileTypeQuickTimeMovie;
exportSession.shouldOptimizeForNetworkUse = YES;
NSLog(@"begin");
[exportSession exportAsynchronouslyWithCompletionHandler:^{
switch (exportSession.status) {
case AVAssetExportSessionStatusCompleted:
NSLog(@"completed");
break;
default:
NSLog(@"failed");
}
}];
@hezhk3 I once used animationView like you, add animationView.layer to superLayer, but it didn't now.
I wander is your code can still work properly with the latest version?
@SamChenzx I was using 2.5.0 and there's no update since then.
I gave up exporting video with the layer. I now use snapshots of the view as gif.
I managed to get the animations to play in the rendered video by adding the LOTAnimationView as a subview to self.view _before_ playing them and attaching the layer to the scene. This only worked on the device and not the simulator.
Next I set the framerate of the video using videoComposition.frameDuration = CMTime(value: 1, timescale: framerate) (30 in this case) and then used the framerate of the animations to calculate the new animation speed to match the video framerate. However in the best case scenario (a single animation) the rendered animations play slower than they do regularly and in the worst case the framerates are completely variable, going up and down at seemingly random. For example the more stickers I add the faster they all seem to play on average in the final video.
Basically my final blocker is that the framerates of the animations are variable and tied to something other than the framerate of the video itself, has anyone encountered a solution for this yet?
I successfully exported video
@syyjay Can you please share your solution?
using Lottie v2.1.4 and the animation (using "LottieLogo2") renders and runs following AVAssetExportSession
but the frame rate is noticeably slower than it is when animating by itself even though I tried to set speed to 1 for both scenarios. I didn't notice a FPS attribute or any way to sync it to what's going on in the video.will tinker with it as I literally just added it to my app.
Have you solved the whole problem
@syyjay Can you please share your solution?
CALayer *parentLayer = [CALayer layer];
CALayer *videoLayer = [CALayer layer];
parentLayer.frame = CGRectMake(0, 0, size.width, size.height);
videoLayer.frame = CGRectMake(0, 0, size.width, size.height);
[parentLayer addSublayer:videoLayer];
self.lotView.layer.frame=parentLayer.bounds;
[parentLayer addSublayer:self.lotView.layer];
composition.animationTool = [AVVideoCompositionCoreAnimationTool
videoCompositionCoreAnimationToolWithPostProcessingAsVideoLayer:videoLayer inLayer:parentLayer];
animationStart
animationStart ,How do you compute this value
I managed to get the animations to play in the rendered video by adding the LOTAnimationView as a subview to self.view _before_ playing them and attaching the layer to the scene. This only worked on the device and not the simulator.
Next I set the framerate of the video using
videoComposition.frameDuration = CMTime(value: 1, timescale: framerate)(30 in this case) and then used the framerate of the animations to calculate the new animation speed to match the video framerate. However in the best case scenario (a single animation) the rendered animations play slower than they do regularly and in the worst case the framerates are completely variable, going up and down at seemingly random. For example the more stickers I add the faster they all seem to play on average in the final video.Basically my final blocker is that the framerates of the animations are variable and tied to something other than the framerate of the video itself, has anyone encountered a solution for this yet?
I have the same problem. Have you solved it?
I have a demo about how to render Lottie in video.
LottieInVideo
You can draw the animation image frame by frame to export.
(But it seems that it is way slower than normal export session.)
- (IBAction)onExportBtn:(UIButton *)sender {
NSURL *url = [NSBundle.mainBundle URLForResource:@"test" withExtension:@"mov"];
AVAsset *asset = [AVURLAsset URLAssetWithURL:url options:@{AVURLAssetPreferPreciseDurationAndTimingKey: @(YES)}];
NSTimeInterval duration = CMTimeGetSeconds(asset.duration);
AVAssetExportSession *exportSession = [AVAssetExportSession exportSessionWithAsset:asset presetName:AVAssetExportPresetHighestQuality];
exportSession.outputFileType = AVFileTypeMPEG4;
NSURL *outputURL = [[NSFileManager.defaultManager.temporaryDirectory URLByAppendingPathComponent:@"output"] URLByAppendingPathExtension:@"mp4"];
[NSFileManager.defaultManager removeItemAtURL:outputURL error:nil];
exportSession.outputURL = outputURL;
CIFilter *filter = [CIFilter filterWithName:@"CISourceAtopCompositing"];
[self.animationView stop];
self.animationView.animationProgress = 0;
CGRect bounds = self.animationView.bounds;
__weak typeof(self)weakSelf = self;
exportSession.videoComposition = [AVMutableVideoComposition videoCompositionWithAsset:asset applyingCIFiltersWithHandler:^(AVAsynchronousCIImageFilteringRequest * _Nonnull request) {
__strong typeof(weakSelf)strongSelf = weakSelf;
// Set background image
[filter setValue:request.sourceImage forKey:kCIInputBackgroundImageKey];
// Vary animation progress based on video timing
Float64 seconds = CMTimeGetSeconds(request.compositionTime);
Float64 progress = seconds / duration;
dispatch_sync(dispatch_get_main_queue(), ^{
strongSelf.animationView.animationProgress = progress;
});
// Draw
UIGraphicsBeginImageContextWithOptions(bounds.size, NO, 0);
[strongSelf.animationView drawViewHierarchyInRect:bounds afterScreenUpdates:NO];
UIImage *animationImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
CIImage *inputImage = [CIImage imageWithCGImage:animationImage.CGImage];
// Get output image
[filter setValue:inputImage forKey:kCIInputImageKey];
CIImage *output = filter.outputImage;
// Provide the filter output to the composition
[request finishWithImage:output context:nil];
}];
NSTimer *timer = [NSTimer scheduledTimerWithTimeInterval:0.01 repeats:YES block:^(NSTimer * _Nonnull timer) {
NSLog(@"[progress]: %.3lf", exportSession.progress);
}];
sender.enabled = NO;
[exportSession exportAsynchronouslyWithCompletionHandler:^{
dispatch_async(dispatch_get_main_queue(), ^{
[timer invalidate];
sender.enabled = YES;
[self.animationView play];
switch (exportSession.status) {
case AVAssetExportSessionStatusCompleted:
NSLog(@"[Completed]");
UISaveVideoAtPathToSavedPhotosAlbum(outputURL.path, nil, nil, nil);
break;
default:
NSLog(@"[Failed]: %@", exportSession.error);
break;
}
});
}];
}
Lottie has been completely rewritten in Swift as of 3.0 (https://github.com/airbnb/lottie-ios/pull/777)
I am closing all issues prior to this release to reduce the noise. If you continue to run into this issues or any issue with Lottie 3.0 please open a new ticket
For continued support of Lottie Objective-c please point to this branch: https://github.com/airbnb/lottie-ios/tree/lottie/objectiveC
Lottie 3.0 supports exporting using AVAssetExportSession?
@ben73 could you provide example code, please? :)
Can this issue be reopened? Facing the issue with non-uniform animation speed (which might be the reason as we are kind of recording the lottie-animation by adding in to the view and playing before inserting it into the animationTool flow)
I created demo project with both AVAssetExportSession and AVAssetWritermethods. AVAssetExportSession doesn't work right, AVAssetWriter works great but 3-6 times slower.
@lvpengwei uses AVAssetExportSession with CustomVideoCompositor and CVPixelBuffer magic in LottieInVideo, so it works with almost the same speed as raw AVAssetWriter. It's still cool, but too slow for our app. And deprecated, btw (EAGLContext iOS12+)
We need some AVFoundation + CoreAnimation genius here
I can export video from lottie 3.0+ or 2.5.3; But the animation speed is always wrong in the video. Can someone helps?
@mayqiyue
That's because lottie animation runs in a different time with export session.
You should export lottie animation frame by frame, then add to your video.
You mean through screen recorder? That’s two slow.
hezhk3 notifications@github.com于2019年12月9日 周一20:35写道:
@mayqiyue https://github.com/mayqiyue
That's because lottie animation runs in a different time with export
session.
You should export lottie animation frame by frame, then add to your video.—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
https://github.com/airbnb/lottie-ios/issues/30?email_source=notifications&email_token=ABQZYVYBGUVCLD6L2BSQM6DQXY3RRA5CNFSM4C64OTYKYY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW2ZLOORPWSZGOEGJAPUY#issuecomment-563218387,
or unsubscribe
https://github.com/notifications/unsubscribe-auth/ABQZYV6ZF3FEC6EN7BMMM5LQXY3RRANCNFSM4C64OTYA
.
You mean through screen recorder? That’s two slow. hezhk3 notifications@github.com于2019年12月9日 周一20:35写道:
…
@mayqiyue https://github.com/mayqiyue That's because lottie animation runs in a different time with export session. You should export lottie animation frame by frame, then add to your video. — You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub <#30?email_source=notifications&email_token=ABQZYVYBGUVCLD6L2BSQM6DQXY3RRA5CNFSM4C64OTYKYY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW2ZLOORPWSZGOEGJAPUY#issuecomment-563218387>, or unsubscribe https://github.com/notifications/unsubscribe-auth/ABQZYV6ZF3FEC6EN7BMMM5LQXY3RRANCNFSM4C64OTYA .
Yes, that's the only way currently. @mayqiyue
Or if you are not using any new features, you can try to export with animation tool at Lottie 1.0.4, according to @lvpengwei . LottieInVideo
Ok, thx for your reply
hezhk3 notifications@github.com于2019年12月9日 周一20:58写道:
You mean through screen recorder? That’s two slow. hezhk3
[email protected]于2019年12月9日 周一20:35写道:
… <#m_7553585765126834425_>
@mayqiyue https://github.com/mayqiyue https://github.com/mayqiyue
That's because lottie animation runs in a different time with export
session. You should export lottie animation frame by frame, then add to
your video. — You are receiving this because you were mentioned. Reply to
this email directly, view it on GitHub <#30
https://github.com/airbnb/lottie-ios/issues/30?email_source=notifications&email_token=ABQZYVYBGUVCLD6L2BSQM6DQXY3RRA5CNFSM4C64OTYKYY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW2ZLOORPWSZGOEGJAPUY#issuecomment-563218387>,
or unsubscribe
https://github.com/notifications/unsubscribe-auth/ABQZYV6ZF3FEC6EN7BMMM5LQXY3RRANCNFSM4C64OTYA
.Yes, that's the only way currently. @mayqiyue
https://github.com/mayqiyue
Or if you are not using any new features, you can try to export with
animation tool at Lottie 1.0.4, according to @lvpengwei
https://github.com/lvpengwei . LottieInVideo
https://github.com/lvpengwei/LottieInVideo—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
https://github.com/airbnb/lottie-ios/issues/30?email_source=notifications&email_token=ABQZYVZ4OEFORNC4CVHTJZTQXY6I3A5CNFSM4C64OTYKYY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW2ZLOORPWSZGOEGJCSRQ#issuecomment-563226950,
or unsubscribe
https://github.com/notifications/unsubscribe-auth/ABQZYVYS37CECMYCHOXHL3TQXY6I3ANCNFSM4C64OTYA
.
Most helpful comment
I created demo project with both
AVAssetExportSessionandAVAssetWritermethods. AVAssetExportSession doesn't work right, AVAssetWriter works great but 3-6 times slower.@lvpengwei uses
AVAssetExportSessionwithCustomVideoCompositorandCVPixelBuffermagic in LottieInVideo, so it works with almost the same speed as rawAVAssetWriter. It's still cool, but too slow for our app. And deprecated, btw (EAGLContext iOS12+)We need some AVFoundation + CoreAnimation genius here