【问题标题】:How do you play a video outside of the video player class?您如何在视频播放器类之外播放视频?
【发布时间】:2019-10-24 11:43:17
【问题描述】:

对不起,如果问题不是那么直截了当,我才刚刚开始。我通过颤振示例看到的每个播放视频示例都使用与视频播放器相同类的浮动操作按钮。我想在我的主屏幕上添加一个视频播放器实例,并尝试不同的方式来播放视频(点击不同的元素等。我似乎无法访问实例来访问控制器。我不确定如何实际创建一个视频播放器实例,然后从另一个地方访问视频控制器。

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


class VideoPlayerScreen extends StatefulWidget {
  VideoPlayerScreen({Key key}) : super(key: key);
  final VideoPlayerScreenState videoState = new VideoPlayerScreenState();
  @override
  VideoPlayerScreenState createState() => VideoPlayerScreenState();
}

class VideoPlayerScreenState extends State<VideoPlayerScreen> {
  VideoPlayerController controller;
  Future<void> initializeVideoPlayerFuture;  

  @override
  void 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() {
    // Ensure you dispose the VideoPlayerController to free up resources
    controller.dispose();

    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return Container(
      // Use a FutureBuilder to display a loading spinner while you wait for the
      // VideoPlayerController to finish initializing.
      child: 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());
          }
        },
      ),
    );
  }
}

//this is the button I'm calling from the app.dart file

Widget playPauseButton(VideoPlayerScreen videoPlayer){

  return IconButton(
    alignment: Alignment.center,

    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 (videoPlayer.videoState.controller.value.isPlaying) {
              videoPlayer.videoState.controller.pause();
            } else {
              // If the video is paused, play it
              videoPlayer.videoState.controller.play();
            }
          });
        },
      icon: Icon(videoPlayer.videoState.controller.value.isPlaying ? Icons.pause: Icons.play_arrow),

  );
}

【问题讨论】:

    标签: flutter dart


    【解决方案1】:

    您可以创建一个名为VideoProvider 的类,并在其中放置一个VideoPlayer 小部件。 之后,您只需要创建一个名为 controller 的参数并将其传递给您的 VideoPlayer 小部件。 controller 应该是 VideoPlayerController 的类型; 这是一个例子:

    class MySpecificPage extends StatefulWidget {
        @override
        State<StatefulWidget> createState() {
            return _MySpecificPageState();
        }
    }
    
    class _MySpecificPageState extends State<MySpecificPage> {
    
        VideoPlayerController controller;
        VoidCallback listener;
    
        @override
        void initState() {
            listener = () => setState(() {});
            videoHandler();
            super.initState();
        }
    
        void videoHandler() {
            if (controller == null) {
                controller = VideoPlayerController.network('https://flutter.github.io/assets-for-api-docs/assets/videos/butterfly.mp4')
                    ..addListener(listener)
                    ..setVolume(0.5)
                    ..initialize();
            } else {
                if (controller.value.isPlaying) {
                    controller.pause();
                } else {
                    controller.play();
                }
            }
        }
    
    
        @override
        Widget build(BuildContext context) {
            return Scaffold(
                appBar: AppBar(
                    title: Text('Videop Provider Example'),
                ),
                body:Container(
                child: Column(
                    children: <Widget>[
                        VideoProvider(controller),
                        RaisedButton(
                            child: Text('click here to play & puase the video'),
                            onPressed: () {
                                videoHandler();
                            },
                            )
                    ],
                    ),
                ),
            );
        }
    }
    
    class VideoProvider extends StatelessWidget {
        final VideoPlayerController controller;
    
        VideoProvider(this.controller);
    
        @override
        Widget build(BuildContext context) {
            return AspectRatio(
                aspectRatio: 16 / 9,
                child: VideoPlayer(
                    controller
                ),
            );
        }
    }
    

    【讨论】:

    • 感谢您的回复!您如何从另一个 dart 文件(我的主屏幕)访问控制器?我创建了一个 VideoPlayerController 并将其传递给 VideoProvider,但是当我按下我创建的新按钮时,日志只是说“null”,就好像它从未进入“_MySpecificPageState”一样。我应该从另一个 dart 文件中调用 VideoProvider 来显示视频或“MySpecificPage”吗?如果我调用 MySpecificPage,它会显示视频,但我创建并通过 VideoProvider(controller) 传递给它的任何按钮,当我按下它时按钮会一直返回 null
    • 不客气。但对不起,我只是有点困惑。你想从另一个飞镖文件访问VideoProvider 对吗?所以您应该在该文件中创建一个新的VideoPlayerController 并将其传递给您的VideoProvider 小部件。请记住,您应该在您的主页中使用StatefullWidget,该主页使用VideoProvider 小部件来更新和呈现您所做的每个操作的状态。例如暂停或播放视频。如果这不是您的答案,请向我展示一个代码,以更好地了解您的目的;)
    • 是的,这正是我想要做的。我希望能够从主屏幕暂停/播放视频,但是当我尝试使用控制器时,我一直为空。我根本没有考虑在控制器上使用 setState 。这就是我一直为空的原因吗?我现在不在家,但如果信息不足,我可以稍后回来时花费代码。我应该像在有状态视频类中一样初始化控制器吗?这也可以让我通过控制器传递视频的位置?
    • 我想通了。在状态下初始化控制器是它在玩了一段时间后让它工作的原因。我学到了很多东西,非常感谢您的帮助!
    • @MilesCortex 嘿,我知道这有点晚了,但你能解释一下你是如何解决这个问题的吗?谢谢!
    猜你喜欢
    • 1970-01-01
    • 2019-08-13
    • 2014-05-01
    • 2014-06-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多