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.
- video_player: ^version
- 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),
)),
]),
)),
),
);
}
},
);
}
}