颤动 video_player 处置

Ans*_*llC 11 dart flutter

我正在使用providerwithvideo_player来管理状态。

VideoProvider 具有:

videoPlayerController = VideoPlayerController.network(...);
Run Code Online (Sandbox Code Playgroud)

当用户切换到新视频(同一屏幕)时,我经常更改它。如果我直接分配一个新VideoPlayerController.network(...)videoPlayerController,旧的视频仍然会播放,你可以听到声音。解决方法是videoPlayerController.pause()之后分配一个新的VideoPlayerCOntroller.network

之前的Video是被GC处理了吗?这有任何性能问题吗?我想在切换到新视频之前摆脱以前的视频和使用的资源。videoPlayerController.dispose()在切换之前我不能,因为它会导致错误。

Igo*_*din 21

当您调用dispose您的控制器时,VideoPlayer小部件仍在使用。首先,您需要确保不再使用它(将控制器的状态设置为 null),并且在调用 dispose 之后。

我不确定您是否通过 Provider 进行状态管理,但我将举一个示例,说明如何使用常规 State 来执行此操作。

  VideoPlayerController _controller;

  void _initController(String link) {
    _controller = VideoPlayerController.network(link)
      ..initialize().then((_) {
        setState(() {});
      });
  }

  Future<void> _onControllerChange(String link) async {
    if (_controller == null) {
      // If there was no controller, just create a new one
      _initController(link);
    } else {
      // If there was a controller, we need to dispose of the old one first
      final oldController = _controller;

      // Registering a callback for the end of next frame
      // to dispose of an old controller
      // (which won't be used anymore after calling setState)
      WidgetsBinding.instance.addPostFrameCallback((_) async {
        await oldController.dispose();

        // Initing new controller
        _initController(link);
      });

      // Making sure that controller is not used by setting it to null
      setState(() {
        _controller = null;
      });
    }
  }
Run Code Online (Sandbox Code Playgroud)

  • 您好,您在代码中的哪个位置调用 _onControllerChange() ? (3认同)

小智 9

我知道已经晚了,但这将帮助其他遇到同样问题的人。

我遇到了同样的问题,当用户从列表中选择新视频时,我想更改视频,经过大量研究后,我终于自己创建了一个解决方案。

按照以下步骤,您可以在同一屏幕的视频播放器中录制视频

  1. 创建一个StatefulWidget包含VideoPlayer并在方法中初始化 videoPlayerController 的类init。假设您创建了一个名为 MyVideoPlayer 的 StatefulWidget 类,然后在构造函数中接受两个变量,即 i> String videoLink ii> UniqueKey()

注意- 您必须将 UniqueKey() 传递给此类的父类,例如,

class MyVideoPlayer extends StatefulWidget {
  final String videoLink;
  final UniqueKey newKey;

  MyVideoPlayer(this.videoLink, this.newKey): super(key: newKey); // passing Unique key to dispose old class instance and create new with new data

  @override
  _MyVideoPlayerState createState() => _MyVideoPlayerState();
} ...
Run Code Online (Sandbox Code Playgroud)
  1. VideoPlayer将正在播放视频的主 dart 文件实例替换为之前创建的类 ie,MyVideoPlayer并传递 videoLink 和UniqueKey().

  2. 现在,每当您想要更改视频时,只需更新setState(() {})主 dart 文件中的 videoLink 即可,然后通过完全处理旧的 VideoPlayer 实例来创建新的 VideoPlayer 实例。

注意 - 这里的主要工作是由 UniqueKey() 完成的,通过传递 UniqueKey() 你可以说 flutter 创建这个特定类的新的唯一实例;