Skip to content Skip to sidebar Skip to footer

React Native Generate Thumbnail For Video Url

I have videos that I'd like to present as thumbnails before a user clicks on them for the full video. They are not local, I only have the url. Is there a RN component to do this? T

Solution 1:

Not possible. Video thumbnail cannot be auto-generated from video URL. It should be created and stored along with the video in backend database and when RN app receives video URL, it should receive thumbnail URL too. Then you can use Image and TouchableOpacity components to add pressing behavior on the thumbnail.

However, if you use Youtube videos only, then react-native-thumbnail-video might be a quick solution to your problem.

Solution 2:

Unfortunately there is no react-native component/api that does this. However, you can leverage native OS apis (AVAssetImageGenerator on ios and MediaMetadataRetriever on android) to generate thumbnails from video url in your react-native app.

For a quick solution, you can use react-native-create-thumbnail. It's a wrapper around the above mentioned system apis and supports both remote and local videos.

Solution 3:

It's possible using Expo Video Thumbnail library

just like this example

importReactfrom'react';
import { StyleSheet, Button, View, Image, Text } from'react-native';
import * asVideoThumbnailsfrom'expo-video-thumbnails';

exportdefaultclassAppextendsReact.Component {
  state = {
    image: null,
  };

  generateThumbnail = async () => {
    try {
      const { uri } = awaitVideoThumbnails.getThumbnailAsync(
        'http://d23dyxeqlo5psv.cloudfront.net/big_buck_bunny.mp4',
        {
          time: 15000,
        }
      );
      this.setState({ image: uri });
    } catch (e) {
      console.warn(e);
    }
  };

  render() {
    const { image } = this.state;
    return (
      <Viewstyle={styles.container}><ButtononPress={this.generateThumbnail}title="Generate thumbnail" />
        {image && <Imagesource={{uri:image }} style={{width:200, height:200 }} />}
        <Text>{image}</Text></View>
    );
  }
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    justifyContent: 'center',
    alignItems: 'center',
    backgroundColor: '#F5FCFF',
  },
});

-UPDATE-

another way to do this is using video library without playing the video and the controllers

example:

npm install --save react-native-video



import Video from 'react-native-video';

// Within your render function, assuming you have a file called// "background.mp4" in your project. You can include multiple videos// on a single screen if you like.

<Video source={{uri: "background"}}   // Can be a URL or a local file.
       paused={true}
controls={false}
/>

in this example, it will display the video without playing it, so basically will give you the thumbnail.

P.S: Not recommended if you have multiple videos in the same view more than 10.

Solution 4:

You can do this with the following steps:

Step 1: Install the "react-native-link-preview" package on current project using this command:

yarn add react-native-link-preview

Step 2: This is the code where you can get link details: like link title, link thumbnail images, etc.

LinkPreview.getPreview('https://www.youtube.com/watch?v=MejbOFk7H6c')
        .then(data =>console.debug(data));

Full Code:

importReact, { Component } from'react';
import { Text, View, FlatList, Image } from'react-native';
importLinkPreviewfrom'react-native-link-preview';

let links = [
    {
        link: 'https://aws.amazon.com/'
    },
    {
        link: 'https://firebase.google.com/'
    },
    {
        link: 'https://www.youtube.com/watch?v=Kmiw4FYTg2U'
    },
    {
        link: 'https://en.wikipedia.org/wiki/React_Native'
    },
    {
        link:'https://stackoverflow.com/'
    }
];

exportdefaultclassAppextendsComponent {
    constructor(props) {
        super(props);
        this.state = {
            linkData: []
        };
    }

    asynccomponentDidMount() {
        let _tempLinkData = [];
        for (let link of links) {
            awaitLinkPreview.getPreview(link.link)
                .then(data => {
                    console.debug("Data : ", data);
                    let _newLinkDetails = {
                        link: link.link,
                        title: data.title,
                        thumbnail: data.images[0]
                    };
                    _tempLinkData.push(_newLinkDetails);
                });

        }
        this.setState({ linkData: _tempLinkData });
    }

    render() {
        return (
            <Viewstyle={{marginTop:35 }}><FlatListcontentContainerStyle={{paddingHorizontal:20}}
                    data={this.state.linkData}renderItem={({item }) => (
                        <Viewstyle={{flex:1, flexDirection: "row", padding:5 }}><Imagestyle={{width:50, height:50 }}
                                source={{uri:item.thumbnail }}
                            /><Viewstyle={{marginLeft:10, }}><Textstyle={{fontSize:16, lineHeight:20, }}>{item.title}</Text><Viewstyle={{flex:1, flexDirection: "row", justifyContent: "space-between", }}><Textstyle={{fontSize:16, lineHeight:20, color: "#a1a1a1" }}>{item.link}</Text></View></View></View>
                    )}

                    keyExtractor={(item, index) => String(index)}
                />
            </View>

        );
    }
}

Solution 5:

For Android only:

Turns out you can just use <Image /> or <FastImage /> and pass the video source, you just can't choose the specific time/frame to use for the thumbnail. Way less hassle tbh.

Source: https://github.com/react-native-camera/react-native-camera/issues/700

Using Expo's VideoThumbnail package was a nightmare, and always ended up crashing the app when trying to call generateThumbnail() on null...

Post a Comment for "React Native Generate Thumbnail For Video Url"