Flutter无法处置VideoPlayerController

穆罕默德·沙巴尼(Mohammad Shabani)

处置VideoPlayerController后,在使用后退按钮时出现异常。

我的VideoPlayer和VideoPlayerController设置如下:

 String url;
 var plan;
_VideoPlayerScreenState(this.url,{this.plan});

 Future<Null> OnWillPop(){

_controller.dispose();

if(plan!=null)
Navigator.push(context, MaterialPageRoute(builder: (context)=>
ListSession(plan :plan)));
else
  Navigator.push(context, MaterialPageRoute(builder: (context)=>
ListMoves()));

}
VideoPlayerController _controller;
Future<void> _initializeVideoPlayerFuture;

@override
void initState() {
 _controller = VideoPlayerController.network(
  url,
 );

// Initialize the controller and store the Future for later use.
_initializeVideoPlayerFuture = _controller.initialize();

// Use the controller to loop the video.
_controller.setLooping(true);
_controller.play();
super.initState();
}

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

 @override
 Widget build(BuildContext context) {
 return WillPopScope(onWillPop: OnWillPop,child:Scaffold(

   // Use a FutureBuilder to display a loading spinner while waiting for the
   // VideoPlayerController to finish initializing.
   body: FutureBuilder(
    future: _initializeVideoPlayerFuture,
    builder: (context, snapshot) {
      if (snapshot.connectionState == ConnectionState.done) {
        // If the VideoPlayerController has finished initialization, use
        // the data it provides to limit the aspect ratio of the video.
        return Center(
          child: AspectRatio(
            aspectRatio: _controller.value.aspectRatio,
            // Use the VideoPlayer widget to display the video.
            child: VideoPlayer(_controller),
          ),
        );
      } else {
        // If the VideoPlayerController is still initializing, show a
        // loading spinner.
        return Center(child: CircularProgressIndicator());
      }
    },
  ),
 ));
}

但是当我按下后退按钮时,出现此错误:

Another exception was thrown: A VideoPlayerController was used after being disposed.

如何正确处置VideoPlayerController并加入后退按钮?

chunhunghan

您可以在下面复制粘贴运行完整的代码
并标记为未标记Navigator.push/Navigator.pushReplacement以检查效果。
在您的情况下,您不需要处理controller,因为controller此页面是本地的,您可以这样做。_controller.pause()
使用Navigator.push转到下一页意味着您pop将从下一页开始
如果您dispose controller将其设置controllernull成功,那么从下一页弹出时,您将收到错误消息,因为initState将不会再次调用它,controller也不会再次初始化

如果使用Navigator.pushReplacementdispose将被自动调用,
您可以在演示代码中看到console show _controller.dispose。


ListMove页面返回时可以看到的工作演示,视频仍然可以播放

在此处输入图片说明

完整的代码

import 'dart:async';

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

void main() => runApp(VideoPlayerApp());

class VideoPlayerApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Video Player Demo',
      home: VideoPlayerScreen(),
    );
  }
}

class VideoPlayerScreen extends StatefulWidget {
  VideoPlayerScreen({Key key}) : super(key: key);

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

class _VideoPlayerScreenState extends State<VideoPlayerScreen> {
  VideoPlayerController _controller;
  VideoPlayerController _oldController;
  Future<void> _initializeVideoPlayerFuture;

  @override
  void initState() {
    print("initState");
    // Create and store the VideoPlayerController. The VideoPlayerController
    // offers several different constructors to play videos from assets, files,
    // or the internet.
    _controller = VideoPlayerController.network(
      'https://flutter.github.io/assets-for-api-docs/assets/videos/butterfly.mp4',
    );

    // Initialize the controller and store the Future for later use.
    _initializeVideoPlayerFuture = _controller.initialize();

    // Use the controller to loop the video.
    _controller.setLooping(true);

    super.initState();
  }

  @override
  void dispose() {
    print("_controller.dispose");
    // Ensure disposing of the VideoPlayerController to free up resources.
    //_initializeVideoPlayerFuture = null;
    _controller.dispose();

    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return WillPopScope(
      onWillPop: () async {
        await _controller.pause();
        Navigator.push(
            context, MaterialPageRoute(builder: (context) => ListMoves()));

        /*Navigator.pushReplacement(
            context, MaterialPageRoute(builder: (context) => ListMoves()));*/
      },
      child: Scaffold(
        appBar: AppBar(
          title: Text('Butterfly Video'),
        ),
        // Use a FutureBuilder to display a loading spinner while waiting for the
        // VideoPlayerController to finish initializing.
        body: FutureBuilder(
          future: _initializeVideoPlayerFuture,
          builder: (context, snapshot) {
            if (snapshot.connectionState == ConnectionState.done) {
              // If the VideoPlayerController has finished initialization, use
              // the data it provides to limit the aspect ratio of the video.
              return AspectRatio(
                aspectRatio: _controller.value.aspectRatio,
                // Use the VideoPlayer widget to display the video.
                child: VideoPlayer(_controller),
              );
            } else {
              // If the VideoPlayerController is still initializing, show a
              // loading spinner.
              return Center(child: CircularProgressIndicator());
            }
          },
        ),
        floatingActionButton: FloatingActionButton(
          onPressed: () {
            // Wrap the play or pause in a call to `setState`. This ensures the
            // correct icon is shown.
            setState(() {
              // If the video is playing, pause it.
              if (_controller.value.isPlaying) {
                _controller.pause();
              } else {
                // If the video is paused, play it.
                _controller.play();
              }
            });
          },
          // Display the correct icon depending on the state of the player.
          child: Icon(
            _controller.value.isPlaying ? Icons.pause : Icons.play_arrow,
          ),
        ), // This trailing comma makes auto-formatting nicer for build methods.
      ),
    );
  }
}

class ListMoves extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('List Movies'),
      ),
      body: Center(
        child: RaisedButton(
          child: Text('Launch screen'),
          onPressed: () {},
        ),
      ),
    );
  }
}

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

Flutter video_player处置

来自分类Dev

如何在flutter中的videoplayercontroller.asset()中打印视频路径

来自分类Dev

无法访问已处置的对象错误

来自分类Dev

为什么我无法处置Runspace?

来自分类Dev

无法访问已处置的对象。与XPO

来自分类Dev

处置后无法安装MaterialPageRoute <void>

来自分类Dev

“因为DbContext已被处置,所以操作无法完成”

来自分类Dev

无法访问WCF中的已处置对象异常

来自分类Dev

Sitecore 7搜索,无法访问已处置的对象

来自分类Dev

无法访问已处置的对象。对象名称:“ ToolStripDropDownMenu”

来自分类Dev

Form.Show():无法访问已处置的对象

来自分类Dev

“因为DbContext已被处置,所以操作无法完成”#2

来自分类Dev

无法访问Blazor Server 3.0中的已处置对象

来自分类Dev

无法访问已处置的对象。插座C#

来自分类Dev

System.Text.Json无法访问处置jsonDocument

来自分类Dev

无法访问已处置的对象mysql工作台

来自分类Dev

我无法在客户端上获得内容处置

来自分类Dev

“因为DbContext已被处置,所以操作无法完成”

来自分类Dev

无法访问已处置的对象-新解决方案

来自分类Dev

该操作无法完成,因为DbContext已被处置

来自分类Dev

文件上传无法使用Android发送内容处置

来自分类Dev

关于foreach的错误无法访问已处置的对象

来自分类Dev

处置DataServiceContext?

来自分类Dev

处置CancellationTokenRegistrations

来自分类Dev

处置FileSystemWatcher

来自分类Dev

处置ObservableCollection <>

来自分类Dev

处置CancellationTokenRegistrations

来自分类Dev

处置FileInfo()

来自分类Dev

注入DbContext时无法访问ASP.NET Core中的已处置对象

Related 相关文章

热门标签

归档