在 flutter 中加载与 tiktok 或 Instagram 相同的视频

问题描述 投票:0回答:2

我正在视频滚动应用程序上创建,我有多个视频。所以我遇到的问题是,当我滚动视频时,它需要加载然后播放视频,如果滚动回到同一个视频,那么它会再次加载然后播放。如果我快速滚动,那么视频控制器就会崩溃并且无法正常工作。

我使用页面浏览生成器垂直滚动,但我不知道最好的解决方案是什么。我在 onPageChanged 中写了一些代码 即使这就是为什么我猜它加载很多所以我正在寻找最好的解决方案

这是我的代码

设计形象

onPageChange 事件

  onPageChanged(index) async {
    videoPlayerController!.value.dispose();
    videoPlayerController!.value =
        VideoPlayerController.network(widget.videosList[index]["video_link"]);

    videoPlayerController!.value.setLooping(true);
    videoPlayerController!.value.initialize().then(
      (_) {
        if (isAutoplay.value == true) {
          videoPlayerGetXController.isPlaying.value = true;
          videoPlayerController!.value.play();
          log(videoPlayerController!.value.value.size.toString());
        } else {
          videoPlayerGetXController.isPlaying.value = false;
        }
        videoPlayerGetXController.update();
      },
    );
    PipFlutterPlayerDataSource dataSource = PipFlutterPlayerDataSource(
      PipFlutterPlayerDataSourceType.network,
      widget.videosList[index]["video_link"],
    );
    videoPlayerGetXController.pipFlutterPlayerController.value =
        PipFlutterPlayerController(
      PipFlutterPlayerConfiguration(
        eventListener: (PipFlutterPlayerEvent value) {
          if (PipFlutterPlayerEventType.pipStart ==
              value.pipFlutterPlayerEventType) {
            videoPlayerGetXController.pipFlutterPlayerController.value.play();
          }
          if (PipFlutterPlayerEventType.pipStop ==
              value.pipFlutterPlayerEventType) {
            videoPlayerGetXController.pipFlutterPlayerController.value.pause();
          }
        },
        aspectRatio: 9 / 16,
        fit: BoxFit.contain,
        controlsConfiguration: const PipFlutterPlayerControlsConfiguration(
          enablePlayPause: false,
        ),
        // autoPlay: true,
        deviceOrientationsAfterFullScreen: [DeviceOrientation.portraitUp],
        deviceOrientationsOnFullScreen: [DeviceOrientation.portraitUp],
      ),
    );
    videoPlayerGetXController.pipFlutterPlayerController.value
        .setupDataSource(dataSource);
    videoPlayerGetXController.pipFlutterPlayerController.value
        .setPipFlutterPlayerGlobalKey(
            videoPlayerGetXController.pipFlutterPlayerKey);
    // videoController.pipFlutterPlayerController.value.pause();
    videoPlayerGetXController.update();
  }

页面视图生成器代码

PageView.builder(
                    controller: widget.pageController.value,
                    onPageChanged: (index) async {
                      onPageChanged(index);
                    },
                    scrollDirection: Axis.vertical,
                    itemCount: widget.videosList.length,
                    itemBuilder: (context, i) {
                      pageindex = i;

                      // Future.delayed(const Duration(seconds: 1));
                      return videoPlayerGetXController
                              .pipFlutterPlayerController.value.isFullScreen
                          ? Stack(
                              children: [
                                Container(
                                  height: 1,
                                  width: 1,
                                  color: purpleColor,
                                  child: PipFlutterPlayer(
                                    controller: videoPlayerGetXController
                                        .pipFlutterPlayerController.value,
                                    key: videoPlayerGetXController
                                        .pipFlutterPlayerKey,
                                  ),
                                ),
                                VideoPlayer(videoPlayerController!.value)
                              ],
                            )
                          : InkWell(
                              onTap: () {
                                if (videoPlayerController!
                                    .value.value.isPlaying) {
                                  videoPlayerGetXController.isPlaying.value =
                                      false;
                                  videoPlayerController!.value.pause();
                                } else {
                                  videoPlayerGetXController.isPlaying.value =
                                      true;
                                  videoPlayerController!.value.play();
                                }
                                // videoPlayerGetXController.update();
                              },
                              child: Stack(
                                children: [
                                  Container(
                                    height: MediaQuery.of(context).size.height,
                                    width: MediaQuery.of(context).size.width,
                                    color: primaryBlack,
                                    child: Stack(
                                      alignment: Alignment.center,
                                      children: [
                                        if (videoPlayerController!
                                            .value.value.isInitialized)
                                          SizedBox(
                                            height: 0,
                                            width: 0,
                                            child: PipFlutterPlayer(
                                              controller:
                                                  videoPlayerGetXController
                                                      .pipFlutterPlayerController
                                                      .value,
                                              key: videoPlayerGetXController
                                                  .pipFlutterPlayerKey,
                                            ),
                                          ),
                                        videoPlayerController!
                                                .value.value.isInitialized
                                            ? VideoPlayer(
                                                videoPlayerController!.value)
                                            : Container(),
                                        Positioned(
                                          bottom: widget.fromHomePage == true
                                              ? Get.height * 0.1
                                              : 20,
                                          child: SizedBox(
                                            height: 8,
                                            width: Get.width,
                                            child: VideoProgressIndicator(
                                              videoPlayerController!.value,
                                              allowScrubbing: true,
                                              colors: const VideoProgressColors(
                                                bufferedColor: primaryWhite,
                                                backgroundColor: primaryWhite,
                                                playedColor: purpleColor,
                                              ),
                                            ),
                                          ),
                                        ),
                                        if (widget.fromHomePage != true)
                                          Positioned(
                                            top: 10,
                                            left: 10,
                                            child: GestureDetector(
                                              onTap: () {
                                                Get.back();
                                              },
                                              child: Container(
                                                margin:
                                                    const EdgeInsets.symmetric(
                                                        horizontal: 20,
                                                        vertical: 40),
                                                height: 50,
                                                width: 50,
                                                decoration: BoxDecoration(
                                                  color: whiteColor
                                                      .withOpacity(.2),
                                                  borderRadius:
                                                      BorderRadius.circular(12),
                                                ),
                                                child: const Icon(
                                                  Icons
                                                      .arrow_back_ios_new_outlined,
                                                  size: 16,
                                                  color: primaryWhite,
                                                ),
                                              ),
                                            ),
                                          ),
                                      ],
                                    ),
                                  ),

                                  // if (!videoPlayerGetXController
                                  //     .isPlaying.value)
                                  // const Center(
                                  //   child: Icon(
                                  //     Icons.play_arrow,
                                  //     color: primaryWhite,
                                  //     size: 50,
                                  //   ),
                                  // ),
                                ],
                              ),
                            );
                    },
                  ),
flutter dart video-processing video-player tiktok
2个回答
0
投票

当您不使用应用程序时,TikTok、Instagram 等会在后台加载内容。所以当你打开它时,你总是有一些已经加载的东西,可以立即显示, 访问 https://stackoverflow.com/a/55891860/21947028


0
投票

您可以使用此小部件来播放视频。只需传递视频的 URL 即可正常工作。

在 pubspec 中添加这两个插件

https://pub.dev/packages/chewiehttps://pub.dev/packages/video_player

import 'package:chewie/chewie.dart';
import 'package:flutter/material.dart';
import 'package:video_player/video_player.dart';

class VideoWidget extends StatefulWidget {
  final String url;

  const VideoWidget({required this.url});

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

class _VideoWidgetState extends State<VideoWidget> {
  late VideoPlayerController videoPlayerController;

  late Future<void> _initializeVideoPlayerFuture;

  @override
  void initState() {
    super.initState();
    videoPlayerController =
        new VideoPlayerController.networkUrl(Uri.parse(widget.url));

    _initializeVideoPlayerFuture = videoPlayerController.initialize().then((_) {
      //       Ensure the first frame is shown after the video is initialized, even before the play button has been pressed.
      setState(() {});
    });
  }

  @override
  void dispose() {
    videoPlayerController.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return FutureBuilder(
      future: _initializeVideoPlayerFuture,
      builder: (context, snapshot) {
        return (snapshot.connectionState == ConnectionState.done)
            ? SizedBox(
                height: 200,
                child: Chewie(
                  key: new PageStorageKey(widget.url),
                  controller: ChewieController(
                    videoPlayerController: videoPlayerController,
                    autoInitialize: true,
                    looping: true,
                    showOptions: false,
                    allowFullScreen: false,
                    errorBuilder: (context, errorMessage) {
                      return Center(
                        child: Text(
                          errorMessage,
                          style: TextStyle(color: Colors.white),
                        ),
                      );
                    },
                  ),
                ),
              )
            : SizedBox(
                height: 200,
                child: Center(
                  child: (snapshot.connectionState != ConnectionState.none)
                      ? CircularProgressIndicator()
                      : SizedBox(),
                ),
              );
      },
    );
  }
}
© www.soinside.com 2019 - 2024. All rights reserved.