Search code examples
reactjsreact-nativeanimationvideolottie

How can I export an animation in react native to an mp4


The issue I am facing is that I want to interact(animated) with 2 images and some text objects... I want to fade the images from one to the other and I also want to animate text at the same time. I can do this in the DOM but I can't find ANYWHERE how to export this collection of animations to a video format and save it to the user's device.

I would love to integrate Lottie since it is so robust, but there is no way to export anything to video. All I've found is screen recorders but what if a notification pops up, it'll ruin the experience. Also, framerate is an issue with the screen recording.

I know you can do this on a server or with native ios functions, but it'd like to do this strictly with react native. But I'm open to hearing other suggestions I may have not thought of.


Solution

  • Looks like this package can handle the animation to mp4 conversion: https://www.remotion.dev/ An example on how to animate two DOM elements and export them as an MP4 video:

    import React from 'react';
    import { StyleSheet, View, Text } from 'react-native';
    import { useVideoConfig, Sequence, useAnimatedStyle, Easing } from 'remotion';
    
    function MyComponent() {
      const { width, height, fps } = useVideoConfig();
    
      // Define the animated styles for the two elements
      const animatedStyle1 = useAnimatedStyle(() => {
        return {
          transform: [{ translateY: height / 2 }],
          opacity: 0,
          easing: Easing.easeInOut,
          durationInFrames: fps * 2,
        };
      }, []);
    
      const animatedStyle2 = useAnimatedStyle(() => {
        return {
          transform: [{ translateY: -height / 2 }],
          opacity: 1,
          easing: Easing.easeInOut,
          durationInFrames: fps * 2,
          delayInFrames: fps,
        };
      }, []);
    
      return (
        <View style={styles.container}>
          <Sequence from={0} durationInFrames={fps * 4}>
            <Text style={[styles.text, animatedStyle1]}>Hello</Text>
            <Text style={[styles.text, animatedStyle2]}>World</Text>
          </Sequence>
        </View>
      );
    }
    
    export default function App() {
      const { width, height, fps } = useVideoConfig();
    
      return (
        <View style={{ flex: 1 }}>
          <MyComponent />
        </View>
      );
    }
    
    const styles = StyleSheet.create({
      container: {
        flex: 1,
        justifyContent: 'center',
        alignItems: 'center',
      },
      text: {
        fontSize: 48,
        fontWeight: 'bold',
        color: '#fff',
      },
    });
    

    In this example, we define a MyComponent function that uses the useAnimatedStyle hook from Remotion to define the animated styles for two Text components. We then use the Sequence component to specify the animation sequence for the two elements.

    Export MyComponent as the default export of our module, and import it into the App component. Finally, we use the useVideoConfig hook to get the video configuration (width, height, and FPS) and wrap MyComponent in a View component.

    To export the animation as an MP4 video, we can run the following command from the terminal in the root directory of our project:

    remotion render src/index.js my-video.mp4
    

    This will generate a video file called my-video.mp4 in the root directory of our project, based on the animation defined in MyComponent.