Video player widget

A widget created to play videos from links in flutter. The width and height of the widget is controlled by the parent.

Dependencies

Add the following packages in the pubspec.yaml first.

  1. video_player: ^version
  2. visibility_detector: ^version

and run the pub get command from the terminal.

Usage

Example usage with lists:

List<Widget> _videoFeed;

List<Widget> _generateUserFeed() {
    _videoFeed.add(PageView.builder(
          scrollDirection: Axis.horizontal,
          itemCount: widget.videoList.length,
          itemBuilder: (context, index) {
            return VideoPlayerWidget(
              url: widget.videoList.url,
              text: 'Video $index',
            );
          }));
    return _videoFeed;
  }


@override
  Widget build(BuildContext context) {
    return PageView(
      scrollDirection: Axis.vertical,
      children: _generateUserFeed(),
    );
  }

Parameters

@url : Mandatory. The link for the video @text : Optional. A text to overlay the video. Default is empty @isRounded : Optional. If the video widget should have rounded edges or not. Default is false @autoPlay : Optional. If the video widget should start autoplaying once visible. Default is true

Widget

class VideoPlayerWidget extends StatefulWidget {
  final String url;
  final String text;
  final isRounded;
  final autoPlay;

  VideoPlayerWidget(
      {Key key,
      @required this.url,
      this.text = '',
      this.isRounded = false,
      this.autoPlay = true})
      : super(key: key);

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

class _VideoPlayerWidgetState extends State<VideoPlayerWidget> {
  VideoPlayerController _controller;
  Future<void> _initializeVideoPlayerFuture;

  @override
  void initState() {
    _controller = VideoPlayerController.network(widget.url);
    _initializeVideoPlayerFuture = _controller.initialize();
    _controller.setLooping(true);
    if (widget.autoPlay) {
      _controller.play();
    }
    super.initState();
  }

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

  @override
  Widget build(BuildContext context) {
    return FutureBuilder(
      future: _initializeVideoPlayerFuture,
      builder: (context, snapshot) {
        if (snapshot.connectionState == ConnectionState.waiting) {
          return Container(
            height: double.infinity,
            width: double.infinity,
            color: Colors.black,
          );
        } else if (snapshot.hasError) {
          return Text("${snapshot.error}");
        } else {
          return ClipRRect(
            borderRadius: widget.isRounded
                ? BorderRadius.circular(24)
                : BorderRadius.circular(0),
            child: Container(
              color: Colors.black,
              child: GestureDetector(
                  onTap: () {
                    if (_controller.value.isPlaying) {
                      _controller.pause();
                    } else {
                      _controller.play();
                    }
                  },
                  child: VisibilityDetector(
                    key: Key(widget.url.toString()),
                    onVisibilityChanged: (VisibilityInfo info) {
                      double visiblePercentage = info.visibleFraction * 100;
                      if (visiblePercentage < 20) {
                        if (_controller.value.isPlaying) {
                          _controller.pause();
                        }
                      } else {
                        if (!_controller.value.isPlaying) {
                          _controller.play();
                        }
                      }
                    },
                    child: Stack(children: [
                      VideoPlayer(_controller),
                      Center(
                          child: Text(
                        widget.text,
                        style: TextStyle(fontSize: 20, color: Colors.white),
                      )),
                    ]),
                  )),
            ),
          );
        }
      },
    );
  }
}