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 best solutions below