【问题标题】:How to cache network videos in flutter application?Flutter应用中如何缓存网络视频?
【发布时间】:2022-01-22 11:54:41
【问题描述】:

我试图了解缓存视频的含义以及它的工作原理。

我遇到的问题是我的颤振 /firebase 应用程序中的高带宽。我每天有 19GB 的流量,有 10-20 个视频,最多有 10 个用户。所以我无法弄清楚问题是什么。因此我联系了 Firebase 支持,他们说

Looking at the graph, the high bandwidth comes from the storage bucket where the videos are stored. Even though it looks like there are few videos, your bandwidth will increase more and more if your application doesn't store the videos in cache.

Try to double check your applications and ensure that these ones download the information only once.

而我就像哈克在追逐什么?怎么做? 这会解决高带宽的问题吗?

这是我的代码的样子

class Videoplayeritem extends StatefulWidget {
  final bool mute;
  final int pickedvideo;

  final int currentPageIndex;
  final bool isPaused;
  final int pageIndex;
  final String videourl;
  final String thumbnailUrl;

  const Videoplayeritem({
    Key key,
    this.videourl,
    this.currentPageIndex,
    this.isPaused,
    this.pageIndex,
    this.thumbnailUrl,
    this.pickedvideo,
    this.mute,
  }) : super(key: key);

  @override
  _VideoplayeritemState createState() => _VideoplayeritemState();
}

class _VideoplayeritemState extends State<Videoplayeritem> {
  VideoPlayerController videoPlayerController;
  bool initialized = false;
  bool stopvideo = false;

  @override
  void initState() {
    super.initState();
    try {
      videoPlayerController = VideoPlayerController.network(
        
        widget.videourl,
        
        videoPlayerOptions: VideoPlayerOptions(mixWithOthers: true),
       
      )..initialize().then((value) {
          if (this.mounted) setState(() {});
          try {
            videoPlayerController?.play();
            videoPlayerController?.setLooping(true);
            if (widget.mute) {
              videoPlayerController?.setVolume(0);
            } else if (!widget.mute) {
              videoPlayerController?.setVolume(1);
            }
          } catch (e) {
            print('error: $e');
          }
        });
    } catch (e) {
      print('error2: $e');
    }

    print('init');
  }

  @override
  void dispose() {
    try {
      if (videoPlayerController.value.isPlaying) {
        videoPlayerController?.pause();
      }

      videoPlayerController?.setVolume(0);
      videoPlayerController?.dispose();
      videoPlayerController = null;
    } catch (e) {
      print('error3: $e');
    }

    print('dispose');
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    if (widget.pageIndex == widget.currentPageIndex &&
            !widget.isPaused &&
            !stopvideo ||
        widget.pageIndex == widget.pickedvideo &&
            widget.currentPageIndex == null &&
            !stopvideo) {
      setState(() {
        videoPlayerController?.play();
      });
    } else {
      setState(() {
        videoPlayerController?.pause();
      });
    }
    if (widget.mute) {
      videoPlayerController?.setVolume(0);
    } else if (!widget.mute) {
      videoPlayerController?.setVolume(1);
    }
    return Container(
      color: Colors.black,
      width: MediaQuery.of(context).size.width,
      height: MediaQuery.of(context).size.height,
      child: Center(
          child: videoPlayerController.value.isInitialized
              ? GestureDetector(
                  onTap: () {
                    if (videoPlayerController.value.isPlaying) {
                      if (this.mounted) {
                        setState(() {
                          stopvideo = true;
                          videoPlayerController?.pause();
                        });
                      }
                    } else {
                      if (this.mounted) {
                        setState(() {
                          stopvideo = false;
                          videoPlayerController?.play();
                          videoPlayerController?.setLooping(true);
                        });
                      }
                    }
                  },
                  child: VisibilityDetector(
                    key: Key("unique keys"),
                    onVisibilityChanged: (VisibilityInfo info) {
                      debugPrint(
                          "${info.visibleFraction} of my widget is visible");
                      if (info.visibleFraction == 0) {
                        print("pause");
                        if (stopvideo == false) {
                          if (this.mounted) {
                            setState(() {
                              stopvideo = true;
                            });
                          }
                        }

                        videoPlayerController?.pause();
                      } else if (widget.pageIndex == widget.currentPageIndex ||
                          widget.pageIndex == widget.pickedvideo &&
                              widget.currentPageIndex == null) {
                        if (this.mounted) {
                          if (stopvideo == true) {
                            setState(() {
                              stopvideo = false;
                            });
                          }
                        }

                        videoPlayerController?.play();
                      } else {}
                    },
                    child: Stack(children: [
                      Center(
                        child: AspectRatio(
                          aspectRatio: videoPlayerController.value.aspectRatio,
                          child: VideoPlayer(videoPlayerController),
                        ),
                      ),
                      PlayPauseOverlay(
                        controller: videoPlayerController,
                        stopvideo: stopvideo,
                      )
                    ]),
                  ))
              : Center(
                  child: Container(
                    width: MediaQuery.of(context).size.width,
                    height: MediaQuery.of(context).size.height,
                    child: CachedNetworkImage(
                      errorWidget: (context, url, error) => Icon(Icons.error),
                      imageUrl: widget.thumbnailUrl,
                      fit: BoxFit.cover,
                    ),
                  ),
                )),
    );
  }
}

我的应用正在 Preloadpageview 中播放视频,这些视频可以像 instagram 中的卷轴一样垂直滚动。视频是从流中加载的。

希望任何人都可以解释 chaching 的确切含义以及它将如何影响我的高带宽。在我的情况下如何使用它?

【问题讨论】:

    标签: firebase flutter firebase-storage video-player


    【解决方案1】:

    我遇到的问题是我的颤振 /firebase 应用程序中的高带宽。我每天有 19GB 的流量,有 10-20 个视频,最多有 10 个用户。

    缓存可以解决此问题的两层:初始视频下载和后续视频重放。

    对于初始视频下载,一种选择是将服务器专用于充当中间缓存。它将下载并与当前videourl 的内容保持同步,然后提供它。然后,videourls 将指向该服务器,以便客户端从中提取视频。
    但这只会解决问题,而且带宽不是免费的。但是您不必托管此缓存服务器,有些公司会收费托管。

    缓存可以帮助后续视频回放的方式是将其保存在视频播放客户端的本地临时存储中,当返回视频时,从本地临时存储中检索并播放它 - 从而避免从服务器询问它再次。

    使用better_player 库可能是一种快速的解决方案。它允许许多配置,包括使用缓存。你可以找到它here

    【讨论】:

      猜你喜欢
      • 2017-09-25
      • 2021-03-28
      • 2012-02-25
      • 2016-08-01
      • 1970-01-01
      • 1970-01-01
      • 2016-05-18
      • 1970-01-01
      • 2011-03-26
      相关资源
      最近更新 更多