在Flutter/Firebase中保存缩略图图像沿着视频

7rfyedvj  于 2023-05-18  发布在  Flutter
关注(0)|答案(1)|浏览(233)

我试图从视频中保存缩略图,同时将视频保存到Cloud Firestore,我遇到了麻烦。我可以将视频保存到Storage,并将URL保存到Firerestore数据库中的帖子,但当我试图获取缩略图时,我得到了一个空错误。
我有几个异步函数同时发生,我无法获得需要设置的变量,以便将它们用于另一个函数。
下面是适用的代码:

compressVideo() async {
    // compress video and assign path to mediaInfo
    MediaInfo? mediaInfo = await VideoCompress.compressVideo(
      file!.path,
      quality: VideoQuality.MediumQuality,
      deleteOrigin: false);
    // return the compressed file from the path
    final compressedVideoFile = mediaInfo!.file;
    setState(() {
      compressedFile = compressedVideoFile;
    });
  }

  getThumbnail(String mediaUrl) async {
    File? thumbnailImage = await VideoCompress.getFileThumbnail(mediaUrl);
    return thumbnailImage;
  }

  Future<String> uploadVideo(videoFile) async {
    UploadTask uploadTask = storageRef.child("post_$postId").putFile(videoFile);
    TaskSnapshot taskSnapshot = await uploadTask;
    String downloadUrl = await taskSnapshot.ref.getDownloadURL();
    return downloadUrl;
  }

  Future<String> uploadThumbnail(thumbnail) async {
    UploadTask uploadTask = storageRef.child("post_$postId").putFile(thumbnail);
    TaskSnapshot taskSnapshot = await uploadTask;
    String thumb = await taskSnapshot.ref.getDownloadURL();
    return thumb;
  }

  createPostInFirestore({ String mediaUrl="", String location="", String description="", String thumbnailUrl = "" }) {
    postsRef
      .doc(widget.currentUser!.id)
      .collection("userPosts")
      .doc(postId)
      .set({
        "postId": postId,
        "ownerId": widget.currentUser!.id,
        "username": widget.currentUser!.id,
        "mediaUrl": mediaUrl,
        "thumbnailUrl": thumbnailUrl,
        "description": description,
        "location": location,
        "timestamp": timestamp,
        "likes": {},
      });
  }

  handleSubmit() async {
    setState(() {
      isUploading = true;
    });
    buildLoading(context);
    await compressVideo();
    String mediaUrl = await uploadVideo(compressedFile);
    String thumbfile = await getThumbnail(await uploadVideo(compressedFile));
    String thumbnailUrl = await uploadThumbnail(thumbfile);
    createPostInFirestore(
      mediaUrl: mediaUrl,
      thumbnailUrl: thumbnailUrl,
      location: locationController.text,
      description: captionController.text,
    );
    captionController.clear();
    locationController.clear();
    setState(() {
      file = null;
      compressedFile = null;
      thumb = null;
      isUploading = false;
      postId = const Uuid().v4();
    });
    Navigator.of(context).pop();
  }

当我运行上面的代码时,我得到以下错误_CastError (Null check operator used on a null value),发生在File? thumbnailImage = await VideoCompress.getFileThumbnail(mediaUrl);
如果有人能给我指明正确的方向,我将不胜感激。我试过使用video_thumbnail这样的插件,它会生成一个缩略图来显示在屏幕上,但是当你在一个屏幕上有多个视频并且数据量非常大时,它会很慢。所以我尝试在数据库中存储一个缩略图。

8yoxcaq7

8yoxcaq71#

以下行存在问题:

getThumbnail(String mediaUrl) async {
    File? thumbnailImage = await VideoCompress.getFileThumbnail(mediaUrl);
    return thumbnailImage;
  }

根据getFileThumbnail method,此函数返回File,但您正在获取字符串

String thumbfile = await getThumbnail(await uploadVideo(compressedFile));

以下是更改后的更新代码:

getThumbnail(String videoPath) async {
  final thumbnailPath = await VideoCompress.getFileThumbnail(videoPath);
  return File(thumbnailPath);
}

handleSubmit() async {
  setState(() {
    isUploading = true;
  });
  buildLoading(context);
  await compressVideo();
  String mediaUrl = await uploadVideo(compressedFile);
  File thumbnailFile = await getThumbnail(compressedFile!.path);
  String thumbnailUrl = await uploadThumbnail(thumbnailFile);
  createPostInFirestore(
    mediaUrl: mediaUrl,
    thumbnailUrl: thumbnailUrl,
    location: locationController.text,
    description: captionController.text,
  );
// …
}

你也可以通过在generateThumbnail()方法中声明一个File? thumbnail;状态和update来解决这个问题,这样你就可以直接访问handleSubmit()函数。
参考:video_compress

相关问题