airbnb / lottie-ios

An iOS library to natively render After Effects vector animations
http://airbnb.io/lottie/
Apache License 2.0
25.77k stars 3.75k forks source link

add support for video Export usage #30

Closed alexiscn closed 5 years ago

alexiscn commented 7 years ago

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 ?

buba447 commented 7 years ago

Im not sure what it would take to support this but I will add it to our research list!

yasinbor commented 7 years ago

Is there any progress in this issue? I am also trying to add Lottie animation to video.

buba447 commented 7 years ago

Try Lottie 2.0! It now more closely follows CAAnimaiton rules.

jakobsvenningsson commented 7 years ago

I can confirm that it's possible to include Lottie animations when exporting videos with AVFoundation. I'm using version 2.0.5.

jjc235 commented 7 years ago

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 .

jakobsvenningsson commented 7 years ago

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.

jjc235 commented 7 years ago

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 .

jakobsvenningsson commented 7 years ago

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()
amrittrivedir commented 7 years ago

@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.

agibson73 commented 7 years ago

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?

amrittrivedir commented 7 years ago

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.

stanchiang commented 6 years ago

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.

lvpengwei commented 6 years ago

@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 猫饼.

mliapich commented 6 years ago

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

hezhk3 commented 6 years ago

@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");
        }
    }];
SamChenzx commented 6 years ago

@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?

hezhk3 commented 6 years ago

@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.

spykr commented 6 years ago

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?

syyjay commented 5 years ago

I successfully exported video

adobysh commented 5 years ago

@syyjay Can you please share your solution?

syyjay commented 5 years ago

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 commented 5 years ago

@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];
syyjay commented 5 years ago

animationStart

animationStart ,How do you compute this value

smallqiang commented 5 years ago

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?

lvpengwei commented 5 years ago

I have a demo about how to render Lottie in video. LottieInVideo

hezhk3 commented 5 years ago

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;
            }
        });
    }];
}
buba447 commented 5 years ago

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

ben73 commented 5 years ago

Lottie 3.0 supports exporting using AVAssetExportSession?

Andy4202 commented 5 years ago

@ben73 could you provide example code, please? :)

d1xlord commented 5 years ago

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)

damikdk commented 5 years ago

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

mayqiyue commented 4 years ago

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?

hezhk3 commented 4 years ago

@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.

mayqiyue commented 4 years ago

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 .

hezhk3 commented 4 years ago

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

mayqiyue commented 4 years ago

Ok, thx for your reply

hezhk3 notifications@github.com于2019年12月9日 周一20:58写道:

You mean through screen recorder? That’s two slow. hezhk3 notifications@github.com于2019年12月9日 周一20:35写道: … <#m7553585765126834425> @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 .

sagarthecoder commented 3 years ago

How does animationTool work in AVMutableVideoComposition()? Can anyone describe the inner mechanism of animationTool? Is it responsible for slower exporting? I'm using this code ( https://stackoverflow.com/questions/46315867/making-video-from-uiimage-array-with-different-transition-animations/46560615#46560615) for creating animated video. But when use UIBezierPath to animation, then export video is too much slow. Help me to reduce exporting time.

damikdk commented 2 years ago

Is it possible now, with new CoreAnimation engine?

agibson73 commented 2 years ago

Is it possible now, with new CoreAnimation engine?

Sorry what is the new CoreAnimation engine? Or do you mean if this is possible?

damikdk commented 2 years ago

Sorry what is the new CoreAnimation engine? Or do you mean if this is possible?

Lottie 3.4.0 added a new rendering engine powered by Core Animation

the new release says a lot about this new engine. So maybe now we can export lottie animations through AVAssetExportSession? As we tried years ago:

By creating AVMutableVideoComposition and adding AnimationView.layer (CALayer) on it by AVVideoCompositionCoreAnimationTool

I will check later anyway, but maybe it's obvious for maintainers already

calda commented 2 years ago

Just curious, what use case do folks have for exporting a Lottie animation to a video file? It seems technically feasible but I'm not sure exactly why you would want / need to do that.

damikdk commented 2 years ago

@calda Designers create beautiful complex compositions in after effects and export them with bodymovin. We use it in app and allow users to change them in runtime. For example, by inserting your own pictures and videos into them. And after editing, the user can do the export.

You can check templates in applications like Bazaart

calda commented 2 years ago

Oh wow, that's cool! Very nice.

agibson73 commented 2 years ago

https://user-images.githubusercontent.com/8474760/181546499-3fec413d-b7c0-43f8-905d-c46d1315bb5b.mp4

very simplistic example of an export with lottie from iOS. I think the lack of duration and begin time hold Lottie back in terms of export with the apple frameworks. The only way I know to do this is running it inside a custom compositor because you can run it like a clock using frame time. Then the next bottleneck is in the snapshotting technique. I am not really familiar with the inner workings of lottie as its complexity seemed it must be running on a display link or something

calda commented 2 years ago

Yeah, the Main Thread rendering engine basically uses a display link. The new Core Animation engine uses CAAnimations instead so may be easier to work with.

agibson73 commented 2 years ago

Yeah it is possible to export as I did above. I guess the big question to understand how to build this out would be why use the display link if CAAnimations are used? Is it because some of the animations are custom keypaths or are full rerenders used at points in certain animations? I am guessing this is the case as well. If so then exporting running a wall clock type style is the only way.

calda commented 2 years ago

The Main Thread rendering engine uses a display link because it doesn't use CAANimations. The new Core Animation rendering engine uses CAAnimations instead of a display link.

agibson73 commented 2 years ago

So maybe it's as simple as being able to toggle removedOnCompletion = false and change beginTime to AVCoreAnimationBeginTimeAtZero + beginTime...maybe a global isExporting on the AnimationView

lvpengwei commented 2 years ago

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

@damikdk Now, you can try PAG, which is designed for a video editor. and it can run on iOS/Android/Mac/Windows/Linux/Web with the same CPP code.

agibson73 commented 2 years ago

@lvpengwei it seems PAG does everything we are asking in this thread if I am not reading their git page wrong. so maybe this is not needed from Lottie? Are there features missing? The bottleneck you mention above is the snapshoting technique and no matter the context you use it will be slow because of main thread rendering. Actually your use of drawHierarchy is partially GPU bound so you are doing it pretty efficient. To be faster the Lottie view would have to not be updated based on time and the native rending of the animation tool would be faster. There is a way to do what you are doing exponentially faster but it is a private framework. I look in release notes often to see if it has made it public but so far it has not.