1

There are similar answers to the above question to use preload_page_view package but I am facing issues with it.

I tried two below methods with and without package

with package:

return Scaffold(
      body: PreloadPageView.builder(
        controller: _controller,
        preloadPagesCount: 3,
      scrollDirection: Axis.vertical,
        itemCount: 10,
        itemBuilder: (context, i) {
        return  VideoInit(
          index: i,
           videoUrl: sampleVideo[i],

        );
      }),
    );

without package, I did this trick: by providing viewportFraction

 return Scaffold(
      body: PageView.builder(
        allowImplicitScrolling: true,
        controller: PageController(viewportFraction: 0.999),
        itemCount: 3,
        itemBuilder: (context, i) {
        return  VideoInit(
          index: i,
           videoUrl: sampleVideo[i],

        );
      }),
    );

code for the video player is:

 late VideoPlayerController _controller;
  bool initialized = false;

  initiliazeVideo() {

    _controller = VideoPlayerController.network(
       widget.videoUrl)
      ..initialize().then((_) {
        if (mounted) {
          setState(() {
            _controller.setLooping(true);
            _controller.pause();
            initialized = true;
          });
        }
      });
  }

  @override
  void initState() {
    initiliazeVideo();
    super.initState();
  }

  @override
  void dispose() {
        if (initialized) {
      initialized = false;
      _controller.dispose();
    }
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return  VisibilityDetector(
      onVisibilityChanged: (info) {
        if (info.visibleFraction > 0.5) {
          if (initialized) {
            _controller.play();
          }
        } else if (info.visibleFraction < 0.4) {
          if (initialized) {
            _controller.pause();
            _controller.seekTo(Duration.zero);
          }
        }
      },
      key: UniqueKey(),
      child: initialized
          ? SizedBox.expand(
              child: FittedBox(
                fit:  BoxFit.cover,
                child: SizedBox(
                  width: _controller.value.size.width,
                  height: _controller.value.size.height,
                  child: VideoPlayer(_controller),
                ),
              ),
            )
          : const Center(child: CircularProgressIndicator()),
    );
 

The issue with the above method is when a user tries to use the volume button and swipe the volume indicator to adjust the volume on android, the video starts lagging

https://www.dropbox.com/s/z7t2fvszd8p9f2y/VID_20220115124459.mp4?dl=0


What could be an alternative way to fix this?

Edit/Update
The lag is there if I use a listViewBuilder even. If there's a single video in a page view or list view, there's no such issue. I think this is because of the initialization of multiple video controllers.
Any suggestions for an alternative ways to achieve the required goal?

kanwar manraj
  • 492
  • 8
  • 26
  • Issue may not be related to PageView itself, but VideoPlayer - did you check if it lags without PageView? – mfkw1 Jan 15 '22 at 08:50
  • The lag is there if I use a listViewBuilder. If there's a single video in a page view or list view, there's no such issue. I think this is because of the initialization of multiple video controllers. @mfkw1 – kanwar manraj Jan 15 '22 at 09:25

1 Answers1

0

If you don't want multiple VideoPlayers playing at the same time, more reliable way to synchronize them would be to listen on the PageController.

Pass _controller and index to each page, listen on it and play()/pause() video based on _controller.page == index.

This should have an added bonus of pausing everything during page switching (if you don't want this, you can alter the condition using .floor() or .ceil())

mfkw1
  • 920
  • 6
  • 15
  • Could you please elaborate your code a little bit? In the above code, I am not playing multiple videos at the same time. I am just preloading them and initializing them, so as to reduce the time of initialization, and when that page is visible, I play the video – kanwar manraj Jan 15 '22 at 09:50
  • Yes, but I think the problem is using VisibilityDetector do detect when page is visible. Try to listen to PageController instead, as described in my answer. If you still can't get it right, feel free to comment and I will try to provide you a more detailed code sample. – mfkw1 Jan 15 '22 at 09:55
  • Hi, the issue is not with the VisibilityDetector, As I have even tried using Provider. By creating a ChangeNotifier. and then setting value of currentPageView in onPageChanged function and down the widget tree passing the page index and check if videosProvider.currentVideo == widget.index – kanwar manraj Jan 15 '22 at 10:13
  • And I have tried your method even ``` widget.controller.addListener(() { if (widget.controller.page == widget.index) { _controller.play(); } else { _controller.pause(); } });``` still issue is there – kanwar manraj Jan 15 '22 at 10:18
  • Unfortunately, I can't think of any other solution. You should probably file a bug in `video_player` package. – mfkw1 Jan 15 '22 at 10:33