dart 如何暂停视频从另一个小部件在Flutter

vfh0ocws  于 2023-09-28  发布在  Flutter
关注(0)|答案(1)|浏览(119)

所以我在这里有一个项目,显示大量的图像和视频,问题是,当用户滚动和视频同时播放时,它真的会破坏整个应用程序的性能,FPS从60下降到30左右。我认为解决这个问题的方法就是在用户滚动的时候暂停视频。我怎么才能让它做到这一点呢?
我使用这个插件的视频:https://pub.dev/packages/video_player
这是父组件,其中包含视频小部件,如您所见,它只是循环遍历数组并显示图片和图像。我想知道的是:如何让视频widget知道用户是否在滚动,视频widget内部有暂停和播放方法,因此根据用户是否在滚动,它将暂停/播放
(FeedVideoItem =视频小部件)
父控件:

@override
  Widget build(BuildContext context) {
    return SafeArea(
      child: SingleChildScrollView(
        child: Column(
          children: <Widget>[
              if (loaded)
            if (_feedDatas.length > 1)
              for (var item in _feedDatas)
                if (item.isImage)
                  FeedImageItem(
                    item: item,
                  )
                else
                // VIDEO WIDGET
                  new FeedVideoItem(videoData: item)
            else
              Center(child: Text('Loading, do hot restart to display')),
          ],
        ),
      ),
    );
  }

视频控件(FeedVideoItem):

class FeedVideoItem extends StatefulWidget {
  final videoData;

  FeedVideoItem({this.videoData}) : super();

  @override
  _FeedVideoItemState createState() => _FeedVideoItemState(videoData);
}

class _FeedVideoItemState extends State<FeedVideoItem> {
  FeedItem item;
  _FeedVideoItemState(this.item);

  VideoPlayerController _controller;
  bool startedPlaying = false;

  Future<void> initialiseVideoPlayerFuture;

  @override
  void initState() {
    _controller = VideoPlayerController.network(item.url);
    initialiseVideoPlayerFuture = _controller.initialize();
    _controller.setLooping(true);
    _controller.setVolume(1.0);
    super.initState();
  }

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

  @override
  Widget build(BuildContext context) {
    return Padding(
      padding: const EdgeInsets.only(bottom: 15.0),
      child: Column(
        children: <Widget>[
          Stack(
            children: <Widget>[
              FutureBuilder(
                future: initialiseVideoPlayerFuture,
                builder: (context, snapshot) {
                  if (snapshot.connectionState == ConnectionState.done) {
                    return InkWell(
                      onTap: () {
                        setState(() {
                          if (_controller.value.isPlaying) {
                            _controller.pause();
                          } else {
                            _controller.play();
                          }
                        });
                      },
                      child: AspectRatio(
                        aspectRatio: _controller.value.aspectRatio,
                        child: VideoPlayer(_controller),
                      ),
                    );
                  } else {
                    //TODO: Add placeholder image
                  }
                },
              ),
              InkWell(
                child: Icon(
                  _controller.value.isPlaying ? Icons.pause : Icons.play_arrow,
                  color: Colors.white,
                ),
              )
            ],
          ),
        ],
      ),
    );
  }
}
e4yzc0pl

e4yzc0pl1#

我使用VisibilityDetector()解决了这个问题,如果视频(Widget)超过60%,我暂停它,否则我播放它。它工作得很好,给予一试。

VisibilityDetector(
                          key: Key(post.id),
                          onVisibilityChanged: (VisibilityInfo info) {
                            var visiblePercentage = info.visibleFraction * 100;
                          
                            
                            if (visiblePercentage < 50.0 &&
                                _controller.value.isInitialized) {
                              if (_controller.value.isInitialized) {
                                try {
                                  _controller.pause();
                                  _controller.setVolume(0.0);
                                } catch (e) {
                                 
                                }
                             
                            } else {
                              if (_controller.value.isInitialized &&
                                  !pausedManually) {
                                try {
                                  _controller.play();
                                  _controller.setVolume(videoControls.volume);
                                } catch (e) {
                                  log('error in video playing and settings volume :: $e');
                                }
                              }
                            }
                          },)

相关问题