Load video same as tiktok or Instagram in flutter using Video Player and PageView Builder also How to handle the video controller for each video

98 views Asked by At

Using the GetX state management, develope a social media app like TikTok, where user can watch videos. When scroll vertically, video get changed. So I have implement the same functionality in my code. I have used VideoPlayer(video_player) package.From the api it fetch multiple videos. In my code, I have initialized all the video controller from the list, and play the video. But I want that, when the app is started, initialized 0 index video and play it from the list, at that time 1 index video was initialized. When the user change to the next video (0 index -> 1 index) then 1 index video was started playing, 0 index video was paused and 2 index video is get initialized. Again the video change to next video, then 2 index video was started playing, 1 index video was stopped & 0 index video get disposed also 3 index video was initialized. Logic was implemented for forward scrolling. When the user reverse scrolling, logic was viceversa. Basically i need the preloading videos.

Here the above screenshot,i attach the logic of the preloading videos.

Here is my code :

class HomeScreenNew extends StatefulWidget {
  const HomeScreenNew({super.key});

  @override
  State<HomeScreenNew> createState() => _HomeScreenNewState();
}

class _HomeScreenNewState extends State<HomeScreenNew> {
  late PageController pageController;
  late ScrollController scrollController;
  final List<VideoPlayerController> controllers = [];
  final List<ValueNotifier<double>> _progressIndicators = [];
  final VideoControllerX controllerX = Get.put(VideoControllerX());

  @override
  void initState() {
    super.initState();
    pageController = PageController(initialPage: 0);
    scrollController = ScrollController();
    controllerX.fetchHomeVideos().then((_) {
      for (var video in controllerX.videoList) {
        VideoPlayerController controller =
            VideoPlayerController.networkUrl(Uri.parse(video.videoUrl))
              ..initialize().then((value) {
                setState(() {});
              });
        controllers.add(controller);
        _progressIndicators.add(ValueNotifier<double>(0.0));
        controller.addListener(() {
          _updateProgress(controller);
        });
      }
      // Initialize and play the first video
      _playCurrentVideo(0);
      //----- Add a listener to detect when the page scrolling state changes
      pageController.addListener(() {
        if (pageController.page != null &&
            pageController.page!.round() == pageController.page) {
          // Page has settled, play the current video and pause the others
          _playCurrentVideo(pageController.page!.toInt());
        }
      });
    });
  }

  @override
  void dispose() {
    for (var controller in controllers) {
      controller.removeListener(() {});
      controller.dispose();
    }
    for (var progressIndicator in _progressIndicators) {
      progressIndicator.dispose();
    }
    pageController.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: PageView.builder(
        controller: pageController,
        itemCount: controllers.length,
        scrollDirection: Axis.vertical,
        pageSnapping: true,
        onPageChanged: (value) {
          _playCurrentVideo(value);
        },
        itemBuilder: (context, index) {
          final newController = controllers[index];
          newController
            ..play()
            ..setLooping(true);
          return newController.value.isInitialized
              ? Stack(
                  fit: StackFit.expand,
                  children: [
                    //-------------Main Video Screen--------
                    AspectRatio(
                      aspectRatio: newController.value.aspectRatio,
                      child: VideoPlayer(newController),
                    ),

                    //--------Video Progress Bar-------
                    Positioned(
                        bottom: 0.0,
                        left: 0.0,
                        right: 0.0,
                        child: ValueListenableBuilder(
                          valueListenable: _progressIndicators[index],
                          builder: (context, value, child) {
                            return LinearProgressIndicator(
                              value: value,
                              backgroundColor: Colors.white,
                              valueColor:
                                  const AlwaysStoppedAnimation(Colors.red),
                            );
                          },
                        ))
                  ],
                )
              : Container(
                  color: Colors.black,
                  child: const Center(
                    child: CircularProgressIndicator(),
                  ),
                );
        },
      ),
    );
  }

  //-----Play the current video and pause the others-----
  void _playCurrentVideo(int index) {
    for (var i = 0; i < controllers.length; i++) {
      if (i == index) {
        controllers[i].play();
      } else {
        controllers[i].pause();
        controllers[i].seekTo(const Duration(milliseconds: 0));
      }
    }
  }

  //---------Update Progress----------

  void _updateProgress(VideoPlayerController controller) {
    int controllerIndex = controllers.indexOf(controller);
    if (controllerIndex == -1) {
      return;
    }
    final progress = controller.value.position.inMilliseconds /
        controller.value.duration.inMilliseconds;
    _progressIndicators[controllerIndex].value = progress;
  }
}

I want to display the videos, like tiktok reels or instagram reels, where video fetch seamless without any load. I am trying to manage the videocontroller initialize and dispose index wise which i have mention above. But in my code, all videocontroller was initialized at a time .So I think it might get load in the app. Anyone have any solution that, how to handle preloading videos like controller the video controller in flutter app like Tiktok & Instagram reels.

0

There are 0 answers