Flutter 视频在接下来的 4 个视频中缓存 10 秒

Pra*_*ani 12 caching video-streaming flutter flutter-video-player

有谁知道如何在列表中进行 Flutter 视频缓存 4 到 6 秒?(接下来的 5 个视频)如 Instagram 视频。

有什么办法可以做到吗?

我使用PageView.builder来显示一个完整页面的视频。

我尝试过一个cached_video_player,但它正在加载完整的视频。

这是我所做的。

视频小部件:

typedef OnVideoCompleted = void Function();

class VideoWidget extends StatefulWidget {
  //final bool? play;
  final bool? isDuetVideo;
  final String? url;
  final OnVideoCompleted? onVideoCompleted;
  final HomeWidgetBloc? homeWidgetBloc;

  const VideoWidget(
      {Key? key,
      this.onVideoCompleted,
      required this.url,
      required this.homeWidgetBloc,
      required this.isDuetVideo})
      : super(key: key);

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

class _VideoWidgetState extends State<VideoWidget> {
  late VideoPlayerController videoPlayerController;
  late Future<void> _initializeVideoPlayerFuture;
  final _controllerStateStream = BehaviorSubject<int>.seeded(0);
  VoidCallback? _listener;
  StreamSubscription? _playPauseSubscription;

  @override
  void initState() {
    super.initState();
    videoPlayerController = new VideoPlayerController.network(widget.url!);
    videoPlayerController.initialize().then((_) {
      //       Ensure the first frame is shown after the video is initialized, even before the play button has been pressed.
      _controllerStateStream.add(1);
      _observeForPlayPause();
      _observerForSeekDuration();
      _listener = () {
        final value =
            widget.homeWidgetBloc?.videoEndedStream.valueWrapper?.value;
        print('duration -----value--- ${value}');
        if (videoPlayerController.value.duration.inSeconds > 0 &&
            videoPlayerController.value.position.inMilliseconds ==
                videoPlayerController.value.duration.inMilliseconds &&
            (videoPlayerController.value.position.inMilliseconds ==
                videoPlayerController.value.duration.inMilliseconds)) {
          // FOR AUTO PLAY NEXT VIDEO...
          widget.onVideoCompleted?.call();
          print(
              'duration -----addListener--- ${videoPlayerController.value.duration}');
        }
      };
      videoPlayerController.addListener(_listener!);
    });
  } // This closing tag was missing

  @override
  void dispose() {
    super.dispose();
    _controllerStateStream.close();
    _playPauseSubscription?.cancel();
    try {
      if (_listener != null) {
        videoPlayerController.removeListener(_listener!);
      }
      videoPlayerController.dispose();
    } catch (e) {
      print(e.toString());
    }
  }

  @override
  Widget build(BuildContext context) {
    return StreamBuilder<int>(
      stream: _controllerStateStream,
      builder: (context, snapshot) {
        final isReady = (snapshot.data ?? 0) == 1;

        if (!isReady) {
          return _progressWidget();
        }

        return new Stack(children: <Widget>[
          Container(
            child: Center(
              child: (widget.isDuetVideo! ||
                      videoPlayerController.value.size.width >
                          videoPlayerController.value.size.height)
                  ? AspectRatio(
                      child: VideoPlayer(
                        videoPlayerController,
                      ),
                      aspectRatio: videoPlayerController.value.aspectRatio,
                    )
                  : VideoPlayer(
                      videoPlayerController,
                    ),
              widthFactor: double.maxFinite,
              heightFactor: double.maxFinite,
            ),
          ),
          Visibility(
            visible: !widget.isDuetVideo!,
            child: VideoPlayerCustomControlsWidget(
              controller: videoPlayerController,
            ),
          ),
        ]);
      },
    );
  }

  Center _progressWidget() {
    return Center(
      child: CircularProgressIndicator(
        color: AppStyles.primary500Color,
      ),
    );
  }

  void _observeForPlayPause() {
    _playPauseSubscription =
        widget.homeWidgetBloc?.videoPlayPauseStream.listen((value) {
      if (value == PLAY)
        videoPlayerController.play();
      else
        videoPlayerController.pause();
    });
  }

  void _observerForSeekDuration() {
    _playPauseSubscription =
        widget.homeWidgetBloc?.duetVideoSeekDurationZeroStream.listen((value) {
      if (value == true) videoPlayerController.seekTo(Duration.zero);
      widget.homeWidgetBloc?.duetVideoSeekDurationZeroStream.add(false);
    });
  }
}
Run Code Online (Sandbox Code Playgroud)

更新:

我找到了很多答案(像这样),但所有答案仅用于缓存当前视频,而不是列表中的下一个/上一个视频。我想要它,尤其是清单。

Jim*_*hiu 2

这是我在我的应用程序中使用的preload_page_view,它预加载特定数量的上一页/下一页:

  @override
  Widget build(BuildContext context) {
    return new PreloadPageView.builder(
      itemCount: ...,
      itemBuilder: ...,
      onPageChanged: (int position) {...},
      .....
      preloadPagesCount: 3,
      controller: PreloadPageController(),
    );
  }
Run Code Online (Sandbox Code Playgroud)