Skip to content

Instantly share code, notes, and snippets.

@rodydavis
Created May 15, 2018 17:25
Show Gist options
  • Save rodydavis/8560ed410d8d47427fff71a43e9a0634 to your computer and use it in GitHub Desktop.
Save rodydavis/8560ed410d8d47427fff71a43e9a0634 to your computer and use it in GitHub Desktop.
Preview a video from view_player controller in Flutter.
import 'package:flutter/material.dart';
import 'package:video_player/video_player.dart';
class AspectRatioVideo extends StatefulWidget {
final VideoPlayerController controller;
AspectRatioVideo(this.controller);
@override
AspectRatioVideoState createState() => new AspectRatioVideoState();
}
class AspectRatioVideoState extends State<AspectRatioVideo> {
VideoPlayerController get controller => widget.controller;
bool initialized = false;
VoidCallback listener;
@override
void initState() {
super.initState();
listener = () {
if (!mounted) {
return;
}
if (initialized != controller.value.initialized) {
initialized = controller.value.initialized;
setState(() {});
}
};
controller.addListener(listener);
}
@override
Widget build(BuildContext context) {
if (initialized) {
final Size size = controller.value.size;
return new Center(
child: new AspectRatio(
aspectRatio: size.width / size.height,
child: new VideoPlayPause(controller),
),
);
} else {
return new Container();
}
}
}
class VideoPlayPause extends StatefulWidget {
final VideoPlayerController controller;
VideoPlayPause(this.controller);
@override
State createState() {
return new _VideoPlayPauseState();
}
}
class _VideoPlayPauseState extends State<VideoPlayPause> {
FadeAnimation imageFadeAnim =
new FadeAnimation(child: const Icon(Icons.play_arrow, size: 100.0));
VoidCallback listener;
_VideoPlayPauseState() {
listener = () {
setState(() {});
};
}
VideoPlayerController get controller => widget.controller;
@override
void initState() {
super.initState();
controller.addListener(listener);
controller.setVolume(1.0);
controller.play();
}
@override
void deactivate() {
controller.setVolume(0.0);
controller.removeListener(listener);
super.deactivate();
}
@override
Widget build(BuildContext context) {
final List<Widget> children = <Widget>[
new GestureDetector(
child: new VideoPlayer(controller),
onTap: () {
if (!controller.value.initialized) {
return;
}
if (controller.value.isPlaying) {
imageFadeAnim =
new FadeAnimation(child: const Icon(Icons.pause, size: 100.0));
controller.pause();
} else {
imageFadeAnim = new FadeAnimation(
child: const Icon(Icons.play_arrow, size: 100.0));
controller.play();
}
},
),
new Align(
alignment: Alignment.bottomCenter,
child: new VideoProgressIndicator(
controller,
allowScrubbing: true,
),
),
new Center(child: imageFadeAnim),
];
return new Stack(
fit: StackFit.passthrough,
children: children,
);
}
}
class FadeAnimation extends StatefulWidget {
final Widget child;
final Duration duration;
FadeAnimation({this.child, this.duration: const Duration(milliseconds: 500)});
@override
_FadeAnimationState createState() => new _FadeAnimationState();
}
class _FadeAnimationState extends State<FadeAnimation>
with SingleTickerProviderStateMixin {
AnimationController animationController;
@override
void initState() {
super.initState();
animationController =
new AnimationController(duration: widget.duration, vsync: this);
animationController.addListener(() {
if (mounted) {
setState(() {});
}
});
animationController.forward(from: 0.0);
}
@override
void deactivate() {
animationController.stop();
super.deactivate();
}
@override
void didUpdateWidget(FadeAnimation oldWidget) {
super.didUpdateWidget(oldWidget);
if (oldWidget.child != widget.child) {
animationController.forward(from: 0.0);
}
}
@override
void dispose() {
animationController.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return animationController.isAnimating
? new Opacity(
opacity: 1.0 - animationController.value,
child: widget.child,
)
: new Container();
}
}
typedef Widget VideoWidgetBuilder(
BuildContext context, VideoPlayerController controller);
abstract class PlayerLifeCycle extends StatefulWidget {
final VideoWidgetBuilder childBuilder;
final String dataSource;
PlayerLifeCycle(this.dataSource, this.childBuilder);
}
/// A widget connecting its life cycle to a [VideoPlayerController] using
/// a data source from the network.
class NetworkPlayerLifeCycle extends PlayerLifeCycle {
NetworkPlayerLifeCycle(String dataSource, VideoWidgetBuilder childBuilder)
: super(dataSource, childBuilder);
@override
_NetworkPlayerLifeCycleState createState() =>
new _NetworkPlayerLifeCycleState();
}
/// A widget connecting its life cycle to a [VideoPlayerController] using
/// an asset as data source
class AssetPlayerLifeCycle extends PlayerLifeCycle {
AssetPlayerLifeCycle(String dataSource, VideoWidgetBuilder childBuilder)
: super(dataSource, childBuilder);
@override
_AssetPlayerLifeCycleState createState() => new _AssetPlayerLifeCycleState();
}
abstract class _PlayerLifeCycleState extends State<PlayerLifeCycle> {
VideoPlayerController controller;
@override
/// Subclasses should implement [createVideoPlayerController], which is used
/// by this method.
void initState() {
super.initState();
controller = createVideoPlayerController();
controller.addListener(() {
if (controller.value.hasError) {
print(controller.value.errorDescription);
}
});
controller.initialize();
controller.setLooping(true);
controller.play();
}
@override
void deactivate() {
super.deactivate();
}
@override
void dispose() {
controller.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return widget.childBuilder(context, controller);
}
VideoPlayerController createVideoPlayerController();
}
class _NetworkPlayerLifeCycleState extends _PlayerLifeCycleState {
@override
VideoPlayerController createVideoPlayerController() {
return new VideoPlayerController.network(widget.dataSource);
}
}
class _AssetPlayerLifeCycleState extends _PlayerLifeCycleState {
@override
VideoPlayerController createVideoPlayerController() {
return new VideoPlayerController.asset(widget.dataSource);
}
}
/// A filler card to show the video in a list of scrolling contents.
Widget buildCard(String title) {
return new Card(
child: new Column(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
new ListTile(
leading: const Icon(Icons.airline_seat_flat_angled),
title: new Text(title),
),
new ButtonTheme.bar(
child: new ButtonBar(
children: <Widget>[
new FlatButton(
child: const Text('BUY TICKETS'),
onPressed: () {/* ... */},
),
new FlatButton(
child: const Text('SELL TICKETS'),
onPressed: () {/* ... */},
),
],
),
),
],
),
);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment