React Native生成视频缩略图的URL

10

我有一些视频,希望在用户点击完整视频之前以缩略图的形式呈现。这些视频不是本地的,我只有URL。是否有RN组件可以实现这一点? RN Image组件无法将视频URL作为源。


1
你解决了这个问题吗?我想不出如何获取实际的视频文件。 - Keng
我还没有遇到任何事情,@Keng。 - omriki
10个回答

6
可以使用Expo视频缩略图库,就像这个例子一样。
import React from 'react';
import { StyleSheet, Button, View, Image, Text } from 'react-native';
import * as VideoThumbnails from 'expo-video-thumbnails';

export default class App extends React.Component {
  state = {
    image: null,
  };

  generateThumbnail = async () => {
    try {
      const { uri } = await VideoThumbnails.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 (
      <View style={styles.container}>
        <Button onPress={this.generateThumbnail} title="Generate thumbnail" />
        {image && <Image source={{ uri: image }} style={{ width: 200, height: 200 }} />}
        <Text>{image}</Text>
      </View>
    );
  }
}

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

-更新-

另一种方法是使用视频库而不播放视频和控制器。

例如:

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}
/>

在这个例子中,它将展示视频但不播放,基本上会给你缩略图。
注:如果您在同一视图中有多个视频超过10个,则不建议使用。

另一种方法是,加载视频播放器但不播放它,这样它将显示视频缩略图而不播放视频。我编辑了答案,请看一下。 - Balalen
2
前几天我忘了在这里回复。实际上,expo-video-thumbnails也适用于本地视频文件。我在本地有一些编码问题,所以它没有工作。但是当我交叉检查时,它运行良好。感谢@Balalen的回复。 - Manju JK
1
我在IOS上遇到错误 [错误:无法写入文件。] - Bhadresh
@Bhadresh 你使用的是哪个解决方案?是 Expo 还是 Video? - Balalen
@Balalen,请看我在这里的问题 https://stackoverflow.com/questions/69525358/error-cant-write-to-file-error-in-react-native-expo-video-thumbnails-ios - Bhadresh
显示剩余2条评论

5
不可能。视频缩略图无法从视频URL自动生成。它应该与视频一起在后端数据库中创建和存储,当RN应用程序接收到视频URL时,还应该接收到缩略图URL。然后,您可以使用和组件在缩略图上添加按压行为。
但是,如果您只使用Youtube视频,则react-native-thumbnail-video可能是解决问题的快速方法。

4

很遗憾,目前没有react-native组件/api可以实现这一功能。但是,您可以利用本地操作系统api(在iOS上使用AVAssetImageGenerator,在Android上使用MediaMetadataRetriever)在您的react-native应用程序中从视频url生成缩略图。

对于快速解决方案,您可以使用react-native-create-thumbnail。它是上述系统api的封装,并支持远程和本地视频。


2
现在可以使用expo-video-thumbnails轻松实现这一点。
安装方法:
expo install expo-video-thumbnails

范例代码:

import React, { useState } from 'react';
import { StyleSheet, Button, View, Image, Text } from 'react-native';
import * as VideoThumbnails from 'expo-video-thumbnails';

export default function App() {
  const [image, setImage] = useState(null);

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

  return (
    <View style={styles.container}>
      <Button onPress={generateThumbnail} title="Generate thumbnail" />
      {image && <Image source={{ uri: image }} style={styles.image} />}
      <Text>{image}</Text>
    </View>
  );
}

Source: https://docs.expo.dev/versions/latest/sdk/video-thumbnails/#videothumbnailsoptions


1

1
您可以按照以下步骤完成此操作:
步骤1:使用以下命令在当前项目上安装“ react-native-link-preview”软件包:

"react-native-link-preview"

yarn add react-native-link-preview

第二步:这是获取链接详细信息的代码,例如链接标题、链接缩略图等。
LinkPreview.getPreview('https://www.youtube.com/watch?v=MejbOFk7H6c')
        .then(data => console.debug(data));

完整代码:

import React, { Component } from 'react';
import { Text, View, FlatList, Image } from 'react-native';
import LinkPreview from '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/'
    }
];

export default class App extends Component {
    constructor(props) {
        super(props);
        this.state = {
            linkData: []
        };
    }

    async componentDidMount() {
        let _tempLinkData = [];
        for (let link of links) {
            await LinkPreview.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 (
            <View style={{ marginTop: 35 }}>
                <FlatList
                    contentContainerStyle={{ paddingHorizontal: 20}}
                    data={this.state.linkData}
                    renderItem={({ item }) => (
                        <View style={{ flex: 1, flexDirection: "row", padding: 5 }}>
                            <Image
                                style={{ width: 50, height: 50 }}
                                source={{ uri: item.thumbnail }}
                            />
                            <View style={{ marginLeft: 10, }}>
                                <Text style={{ fontSize: 16, lineHeight: 20, }}>{item.title}</Text>
                                <View style={{ flex: 1, flexDirection: "row", justifyContent: "space-between", }}>
                                    <Text style={{ fontSize: 16, lineHeight: 20, color: "#a1a1a1" }}>{item.link}</Text>
                                </View>
                            </View>
                        </View>
                    )}

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

        );
    }
}

0

我正在使用react-native-ffmpeg导出缩略图:

ffmpeg -i input.flv -ss 00:00:14.435 -frames:v 1 out.png

请查看此链接


0

仅适用于Android:

事实证明你可以只使用<Image /><FastImage />并传递视频源,只是不能选择用于缩略图的特定时间/帧。实际上要少麻烦得多。

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

使用Expo的VideoThumbnail包真是一场噩梦,每次调用generateThumbnail()时总是崩溃...


0

可以使用以下代码

<ImageBackground>
       <View style={{alignItems:'center',marginTop:'50%'}}>
                 <Icon name='caret-forward-circle-outline' size={50} color={'#000'}/>
       </View>
</ImageBackground>

-注意 我认为它在IOS上不起作用,但在安卓上是可能的。


<Icon>:从 'react-native-vector-icons/Ionicons' 中导入 Icon。 - Mayur Solanki
3
你的答案可以通过添加更多支持性信息来改进。请[编辑]以添加更多细节,例如引用或文献资料,以便他人能够确认你的答案是正确的。你可以在帮助中心找到有关如何撰写良好答案的更多信息。 - Community

0
你还可以使用"react-native-compressor"包从视频URL中获取缩略图
从包中导入函数:
import {createVideoThumbnail} from 'react-native-compressor'

创建缩略图并将其设置为常量。
const thumbnail = await createVideoThumbnail(videoFileUrl);

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接