在 Flutter 中移动到新屏幕之前下载并缓存多个视频

Downloading and Caching multiple videos before moving to a new screen in Flutter

我有一个 flutter 应用程序的要求,可以按顺序播放多个视频。基本上,播放一个视频,当我点击一个按钮时,应该播放下一个视频等等。

视频很短(1-3 秒),而且非常小。它们存储在 Firebase 存储中。

问题是播放视频不能有任何延迟。所以我正在寻找一种在导航到包含视频的屏幕之前下载和缓存多个视频的方法。

我试过像这样使用 flutter 缓存管理器:

 Future<List<File>> fetchFile(urls) async {

  urls.forEach((url) async {
     var file = await DefaultCacheManager().getSingleFile(url);
     videos.add(file);
   });
   return videos;
} 

在这里,我尝试从 url 列表中获取所有视频,然后我使用 Future 构建器并导航到包含视频列表的下一页。

  Navigator.of(context).push(MaterialPageRoute(builder: (context) => LessonScreen(videos)));

但我在使用这种方法时遇到了很多问题,例如视频无法按顺序播放,或者根本无法加载,甚至导致应用程序崩溃。

有谁知道如何使用 flutter 缓存管理器或任何其他方法实现此目的?

提前感谢您的帮助!

Dart 中的 forEach 是异步的,因此您无法预测迭代的执行顺序,尤其是当块内有异步例程时。如果您需要保证内部异步调用的顺序,请使用常规的 for 循环。

for(int i=0;i<urls.length;i++) {
      var file = await DefaultCacheManager().getSingleFile(urls[i]);
      videos.add(file);
    });

这将保证 videos[] 与 urls[] 的顺序相同,并且 videos[] 在返回之前用 File 对象填充。

对于拥有包含视频网址的对象的任何人的另一个选择,只需使用地图并引用 ID 以确保它是正确的视频:

    Map<String, File> id_with_video_map = Map();
    List<ObjectWithFile> list = await _fireStoreUtils.getObjectsThatHaveVideoFileUrls();

list.forEach((element) async {
          File file = await DefaultCacheManager().getSingleFile(element.video);
          id_with_video_map[element.id] = file; //add the video and associate it with an id
        });

在您的小部件堆栈中,根据文件是否准备好检查并显示每个:

       id_with_video_map[snapshot.data.id] != null ?
       VideoPlayerThatUsesFiles(id_with_video_map[snapshot.data.id]!) //True, let's pass the video file with it instead of url

                            :

       VideoPlayerThatUsesURLInstead(snapshot.data.url) //false, let's default to the regular video url