Flutter Video Player On Click Pass URL dynamic and Load Video to play

瘦欲@ 提交于 2021-01-24 11:32:28

问题


sample screen of video player attached below How can i make video player to play dynamically , while onclick of list play video by passing the video URL?

while on click i have passed URL and tried to reinitialise and start play its not working ,state not changing

Here is my code,

videoplayerscreen.dart,

class VideoPlayerScreen extends StatefulWidget {
  int playBackTime;
  int playBackTotalTime;
  String setPlayTime;
  String setPlayDuration;
  double aspectRatio;
  String videoUrl;
  bool isForward;
  bool isFullScreen;
  bool allowFullScreen;
  bool showControls;
  bool isAutoPlay;
  int startWithinSeconds;

  VideoPlayerScreen({
    Key key,
    this.playBackTime = 0,
    this.playBackTotalTime = 0,
    this.setPlayTime = "00:00",
    this.setPlayDuration = "00:00",
    this.aspectRatio = 16 / 9,
    this.videoUrl =
        "",
    this.isForward = true,
    this.isFullScreen = false,
    this.allowFullScreen = false,
    this.showControls = true,
    this.isAutoPlay = false,
    this.startWithinSeconds = 0,
  }) : super(key: key);

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

class _VideoPlayerScreenState extends State<VideoPlayerScreen> {
  VideoPlayerController _controller;

  void initPlayer() async {
    _controller = VideoPlayerController.network(widget.videoUrl);
    await _controller.initialize();
    _controller.setLooping(true);
    _controller.seekTo(Duration(seconds: widget.startWithinSeconds));
    if (widget.isAutoPlay) {
      _controller.play();
    }
    _controller.addListener(() {
      setState(() {
        widget.playBackTime = _controller.value.position.inSeconds;
        widget.setPlayTime = timeFormatter(widget.playBackTime);
      });
    });
  }

  @override
  void initState() {
    initPlayer();
    super.initState();
  }

 @override
  void dispose() {
    _controller.dispose();
    SystemChrome.setPreferredOrientations([
      DeviceOrientation.landscapeRight,
      DeviceOrientation.landscapeLeft,
      DeviceOrientation.portraitUp,
      DeviceOrientation.portraitDown,
    ]);
    super.dispose();
  }

In Config,

video_player: ^0.10.5

Calling in Other class CourseDetails.dart ,

             Container(
                  padding: EdgeInsets.only(left: 20.0, right: 20.0),
                  child: ClipRRect(
                    borderRadius: BorderRadius.circular(8.0),
                    child: _playUrl != null
                        ? VideoPlayerScreen(videoUrl: _playUrl)
                        : Image.asset(
                            'assets/images/test_video_player_screen.png'),
                  ),
                )
GestureDetector(
 **here i am changing the state **
      onTap: () {
        setState(() {
            _playUrl = videoLists['course_video_url'];
        });
      },
      child: Padding(
        padding:
            EdgeInsets.only(left: 10.0, right: 20.0, top: 2.0, bottom: 5.0),
        child: Row(
          mainAxisSize: MainAxisSize.max,
          mainAxisAlignment: MainAxisAlignment.start,
          children: <Widget>[
            Text(
              "${videoLists['sn_no']}",
              textAlign: TextAlign.center,
              style: TextStyle(
                  fontSize: 18,
                  fontWeight: FontWeight.bold,
                  color: Colors.black45,
                  fontFamily: 'Oswald-SemiBold'),
            ),
            Column(
              crossAxisAlignment: CrossAxisAlignment.start,
              children: <Widget>[
                Padding(
                  padding: EdgeInsets.only(left: 10.0),
                  child: Text(
                    "${videoLists['course_video_title']}",
                    textAlign: TextAlign.left,
                    style: TextStyle(
                        fontSize: 14,
                        fontWeight: FontWeight.bold,
                        color: Colors.black45,
                        fontFamily: 'Oswald-SemiBold'),
                  ),
                ),
                Row(
                  children: <Widget>[
                    Padding(
                      padding: EdgeInsets.only(left: 10.0),
                      child: Text(
                        "Video - ${videoLists['course_video_duration']}",
                        textAlign: TextAlign.left,
                        style: TextStyle(
                            fontSize: 12,
                            fontWeight: FontWeight.bold,
                            color: Colors.grey,
                            fontFamily: 'Oswald-SemiBold'),
                      ),
                    ),
                    Padding(
                        padding: EdgeInsets.only(left: 5.0),
                        child: videoLists['course_watched']
                            ? Image.asset(
                                'assets/images/green_tick_icon.png',
                                width: 12.0,
                                height: 12.0,
                              )
                            : null),
                  ],
                ),
              ],
            ),
          ],
        ),
      ),
    )

回答1:


Thanks for all the replies. I got the solution:

In Build Function, I have checked if any url changes happened or not. If changes happened, I disposed old controller and I reinitialized video controller. Then, it works fine for me.

@override
Widget build(BuildContext context) {
    if (currentObjectVideoUrl != widget.videoUrl) {
       _controller.dispose();
       initPlayer();
    }
}



回答2:


You can achieve this by creating a stateful widget passing a URL. Then inside the init method, you can do this

class ViewVideo extends StatefulWidget {
  final link;
  ViewVideo(this.link);
  @override
  _ViewVideoState createState() => _ViewVideoState(this.link);
}

class _ViewVideoState extends State<ViewVideo> {
  final link;
  _ViewVideoState(this.link);

  @override
  void initState() {
    super.initState();
    //Write your video player code here
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Container(),
    );
  }

  @override
  void dispose() {
     //Here you can close the video player
     super.dispose();
  }
}



回答3:


I've modified my response based on your comments. You just need to have your video url on a class variable that you change with the setState. Then on your Widgets have a check for the presence of the variable and decide to show the VideoPlayerScreen widget or an empty box.

String videoUrl = '';

@override
Widget build(BuildContext context) {
  return Column(
    children: <Widget>[
      videoUrl == '' ? SizedBox() : VideoPlayerScreen(videoUrl: videoUrl),
      RaisedButton(
        onPressed: () {
          setState((){
            videoUrl == videoLists['course_video_url'];
          });
        }
      ),
    ],
  );
}


来源:https://stackoverflow.com/questions/59928309/flutter-video-player-on-click-pass-url-dynamic-and-load-video-to-play

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!