从页面导航到另一个页面时如何暂停颤动视频(video_player插件)

时间:2019-02-14 14:13:44

标签: android ios dart flutter

我正在使用flutter video_player(https://pub.dartlang.org/packages/video_player)插件播放视频。但是,当我从一个页面导航到另一个页面时,视频仍在播放。从任何其他应用程序播放音乐时,我遇到同样的问题(例如:在播放颤动视频时播放通知中的音乐)。我该如何暂停?

4 个答案:

答案 0 :(得分:0)

您有-VideoPlayerController _controller;

导航到其他屏幕之前-

 _controller.pause();  // add this
Navigator.push(
      context, MaterialPageRoute(builder: (BuildContext context) => NextPage()));

OR

如果它是有状态的小部件,则可以覆盖-dispose()方法。

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

答案 1 :(得分:0)

或者您可以ng-cloak使用视频播放器小部件的override方法:

dispose

您可以通过重塑您的应用以使视频播放器小部件成为导航树中的最后一个方法来使此方法起作用,因此,每当您向后导航时,它都会自动暂停,播放器小部件会遇到很多问题。我用我刚才提到的方法设法解决了这个特殊问题

答案 2 :(得分:0)

编辑: 第二个选项: 所以我想出了另一种解决方案。 VisibilityDetector 是一个“小部件”,可以包装任何其他小部件并在该小部件的可见区域更改时通知。

VisibilityDetector(
   key: Key("unique key"),
   onVisibilityChanged: (VisibilityInfo info) {
       debugPrint("${info.visibleFraction} of my widget is visible");
       if(info.visibleFraction == 0){
           videoPlayerController.pause();
       }
       else{
           videoPlayerController.play();
       }
   },
   child: VideoPlayer());
)

第一个选项: 通过使用RouteObserverRouteAware,每当将另一个屏幕推到顶部或从顶部弹出时,都将通知您的窗口小部件。

首先,您需要向RouteObserver或您的MaterialApp中添加Navigator

RouteObserver<PageRoute> routeObserver = RouteObserver<PageRoute>();

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      navigatorObservers: [routeObserver], //HERE
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: MyHomePage(title: 'Flutter Demo Home Page'),
    );
  }
}

然后,您必须将RouteAware混合添加到窗口小部件,并将其订阅到RouteObserver

class VideoPlayerItem extends StatefulWidget {
  final File file;

  VideoPlayerItem(this.file);

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

class _VideoPlayerItemState extends State<VideoPlayerItem> with RouteAware {

  VideoPlayerController _videoPlayerController;

  @override
  void initState() {
    super.initState();
    _videoPlayerController = VideoPlayerController.file(widget.file);
    _videoPlayerController.initialize().then((_) {
      if (mounted) {
        setState(() {});
        _videoPlayerController.play();
      }
    });
  }

  @override
  void didChangeDependencies() {
    routeObserver.subscribe(this, ModalRoute.of(context));//Subscribe it here
    super.didChangeDependencies();
  }

  /// Called when the current route has been popped off.
  @override
  void didPop() {
    print("didPop");
    super.didPop();
  }

  /// Called when the top route has been popped off, and the current route
  /// shows up.
  @override
  void didPopNext() {
    print("didPopNext");
    _videoPlayerController.play();
    super.didPopNext();
  }

  /// Called when the current route has been pushed.
  @override
  void didPush() { 
    print("didPush");
    super.didPush();
  }

  /// Called when a new route has been pushed, and the current route is no
  /// longer visible.
  @override
  void didPushNext() {
    print("didPushNext");
    _videoPlayerController.pause();
    super.didPushNext();
  }


  @override
  Widget build(BuildContext context) {
    return _videoPlayerController?.value?.initialized ?? false
        ? AspectRatio(
            aspectRatio: _videoPlayerController.value.aspectRatio,
            child: VideoPlayer(_videoPlayerController),
          )
        : Container();
  }

  @override
  void dispose() {
    routeObserver.unsubscribe(this); //Don't forget to unsubscribe it!!!!!!
    super.dispose();
    _videoPlayerController.dispose();
  }
}

答案 3 :(得分:-1)

简单而且对我有用,我从 chewie 示例代码中得到了这个:https://pub.dev/packages/chewie/example

就在 onTap/onPressed 上使用 setState 并在此 setState 中制作 videoController.pause 或 dispose,无论您想要什么。

 onTap:() {
        setState(() {
          widget.videoController.pause();
          Navigator.of(context)
              .pushNamed(YOUR-NAVIGATION-PAGE-NAME);
        });
      },