Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ChewieController #99

Merged
merged 24 commits into from
Jan 24, 2019
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
58 changes: 35 additions & 23 deletions example/lib/main.dart
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import 'package:chewie/chewie.dart';
import 'package:chewie/src/chewie_controller.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:video_player/video_player.dart';
Expand All @@ -22,14 +23,33 @@ class ChewieDemo extends StatefulWidget {

class _ChewieDemoState extends State<ChewieDemo> {
TargetPlatform _platform;
VideoPlayerController _controller;
VideoPlayerController _videoPlayerController;
ChewieController _chewieController;

@override
void initState() {
super.initState();
_controller = VideoPlayerController.network(
_videoPlayerController = VideoPlayerController.network(
'https://flutter.github.io/assets-for-api-docs/assets/videos/butterfly.mp4',
);
_chewieController = ChewieController(
_videoPlayerController, aspectRatio: 3 / 2,
autoPlay: true,
looping: true,
// Try playing around with some of these other options:

// showControls: false,
// materialProgressColors: ChewieProgressColors(
// playedColor: Colors.red,
// handleColor: Colors.blue,
// backgroundColor: Colors.grey,
// bufferedColor: Colors.lightGreen,
// ),
// placeholder: Container(
// color: Colors.grey,
// ),
// autoInitialize: true,
);
}

@override
Expand All @@ -48,34 +68,24 @@ class _ChewieDemoState extends State<ChewieDemo> {
Expanded(
child: Center(
child: Chewie(
_controller,
aspectRatio: 3 / 2,
autoPlay: true,
looping: true,

// Try playing around with some of these other options:

// showControls: false,
// materialProgressColors: ChewieProgressColors(
// playedColor: Colors.red,
// handleColor: Colors.blue,
// backgroundColor: Colors.grey,
// bufferedColor: Colors.lightGreen,
// ),
// placeholder: Container(
// color: Colors.grey,
// ),
// autoInitialize: true,
controller: _chewieController,
),
),
),
FlatButton(
onPressed: () {
_chewieController.enterFullscreen();
},
child: Text('Fullscreen'),
),
Row(
children: <Widget>[
Expanded(
child: FlatButton(
onPressed: () {
setState(() {
_controller = VideoPlayerController.network(
_chewieController.videoPlayerController =
VideoPlayerController.network(
'https://flutter.github.io/assets-for-api-docs/assets/videos/butterfly.mp4',
);
});
Expand All @@ -90,8 +100,10 @@ class _ChewieDemoState extends State<ChewieDemo> {
child: FlatButton(
onPressed: () {
setState(() {
_controller = VideoPlayerController.network(
'https://www.sample-videos.com/video123/mp4/480/big_buck_bunny_480p_20mb.mp4',
_chewieController.videoPlayerController =
VideoPlayerController.network(
'https://flutter.github.io/assets-for-api-docs/assets/videos/bee.mp4',
// 'https://www.sample-videos.com/video123/mp4/480/big_buck_bunny_480p_20mb.mp4',
);
});
},
Expand Down
182 changes: 182 additions & 0 deletions lib/src/chewie_controller.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,182 @@
import 'package:chewie/src/chewie_progress_colors.dart';
import 'package:flutter/material.dart';
import 'package:video_player/video_player.dart';

/// The state of the [ChewieController].
@immutable
class ChewieValue {
ChewieValue(
this.videoPlayerController, {
this.isFullScreen = false,
});

/// True if the video is currently playing fullscreen
final bool isFullScreen;

/// The controller for the video you want to play
final VideoPlayerController videoPlayerController;

ChewieValue copyWith({
VideoPlayerController videoPlayerController,
bool isFullScreen,
}) {
return ChewieValue(
videoPlayerController ?? this.videoPlayerController,
isFullScreen: isFullScreen ?? this.isFullScreen,
);
}

@override
String toString() {
return '$runtimeType('
'isFullscreen: $isFullScreen, '
'videoPlayerController: $videoPlayerController, ';
}
}

class ChewieController extends ValueNotifier<ChewieValue> {
cbenhagen marked this conversation as resolved.
Show resolved Hide resolved
ChewieController(
VideoPlayerController videoPlayerController, {
this.aspectRatio,
this.autoInitialize = false,
this.autoPlay = false,
this.startAt,
this.looping = false,
this.fullScreenByDefault = false,
this.cupertinoProgressColors,
this.materialProgressColors,
this.placeholder,
this.showControls = true,
this.allowedScreenSleep = true,
this.isLive = false,
}) : assert(videoPlayerController != null,
'You must provide a controller to play a video'),
super(ChewieValue(videoPlayerController)) {
_initialize();
}

/// Initialize the Video on Startup. This will prep the video for playback.
final bool autoInitialize;

/// Play the video as soon as it's displayed
final bool autoPlay;

/// Start video at a certain position
final Duration startAt;

/// Whether or not the video should loop
final bool looping;

/// Whether or not to show the controls
final bool showControls;

/// The Aspect Ratio of the Video. Important to get the correct size of the
/// video!
///
/// Will fallback to fitting within the space allowed.
final double aspectRatio;

/// The colors to use for controls on iOS. By default, the iOS player uses
/// colors sampled from the original iOS 11 designs.
final ChewieProgressColors cupertinoProgressColors;

/// The colors to use for the Material Progress Bar. By default, the Material
/// player uses the colors from your Theme.
final ChewieProgressColors materialProgressColors;

/// The placeholder is displayed underneath the Video before it is initialized
/// or played.
final Widget placeholder;

/// Defines if the player will start in fullscreen when play is pressed
final bool fullScreenByDefault;

/// Defines if the player will sleep in fullscreen or not
final bool allowedScreenSleep;

/// Defines if the controls should be for live stream video
final bool isLive;

Future _initialize() async {
await value.videoPlayerController.setLooping(looping);

if (autoInitialize || autoPlay) {
await value.videoPlayerController.initialize();
}

if (autoPlay) {
if (fullScreenByDefault) {
enterFullscreen();
}

await value.videoPlayerController.play();
}

if (startAt != null) {
await value.videoPlayerController.seekTo(startAt);
}

if (fullScreenByDefault) {
value.videoPlayerController.addListener(() async {
if (await value.videoPlayerController.value.isPlaying &&
!value.isFullScreen) {
enterFullscreen();
}
});
}
}

void enterFullscreen() {
value = value.copyWith(isFullScreen: true);
}

void exitFullscreen() {
value = value.copyWith(isFullScreen: false);
}

void toggleFullscreen() {
value = value.copyWith(isFullScreen: !value.isFullScreen);
}

void play() {
value.videoPlayerController.play();
}

void pause() {
value.videoPlayerController.pause();
}

// TODO: Do we really need the ability to change the controller?
set videoPlayerController(VideoPlayerController controller) {
cbenhagen marked this conversation as resolved.
Show resolved Hide resolved
if (value.videoPlayerController.dataSource != controller.dataSource) {
// FIXME: The VideoPlayer widget still tries to access the controller
value.videoPlayerController.dispose();
value = value.copyWith(videoPlayerController: controller);
exitFullscreen();
_initialize();
}
}
}

class ChewieControllerProvider extends InheritedWidget {
const ChewieControllerProvider({
Key key,
@required this.controller,
@required Widget child,
}) : assert(controller != null),
assert(child != null),
super(key: key, child: child);

final ChewieController controller;

static ChewieController of(BuildContext context) {
cbenhagen marked this conversation as resolved.
Show resolved Hide resolved
final ChewieControllerProvider chewieControllerProvider =
context.inheritFromWidgetOfExactType(ChewieControllerProvider);

return chewieControllerProvider.controller;
}

@override
bool updateShouldNotify(ChewieControllerProvider old) =>
controller != old.controller;
}
Loading