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 18 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
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
# Changelog

## 1.0.0

* **Breaking changes**: Add a `ChewieController` to make customizations and control from outside of the player easier.
Refer to the [README](README.md) for details on how to upgrade from previous versions.

## 0.8.0

* Update to work with `video_player: ">=0.7.0 <0.8.0` - Thanks @Sub6Resources
Expand Down
50 changes: 45 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,23 +21,63 @@ dependencies:

```dart
import 'package:chewie/chewie.dart';
final videoPlayerController = VideoPlayerController.network(
'https://flutter.github.io/assets-for-api-docs/videos/butterfly.mp4');

final playerWidget = new Chewie(
new VideoPlayerController.network(
'https://flutter.github.io/assets-for-api-docs/videos/butterfly.mp4'
),
final chewieController = ChewieController(
videoPlayerController: videoPlayerController,
aspectRatio: 3 / 2,
autoPlay: true,
looping: true,
);

final playerWidget = Chewie(
controller: chewieController,
);
```

Please make sure to dispose both controller widgets after use. For example by overriding the dispose method of the a `StatefulWidget`:
```dart
@override
void dispose() {
videoPlayerController.dispose();
chewieController.dispose();
super.dispose();
}
```

## Example

Please run the app in the [`example/`](https://github.com/brianegan/chewie/tree/master/example) folder to start playing!

## Migrating from Chewie < 1.0.0
Instead of passing the `VideoPlayerController` and your options to the `Chewie` widget you now pass them to the `ChewieController` and pass that latter to the `Chewie` widget.

```dart
final playerWidget = Chewie(
videoPlayerController,
aspectRatio: 3 / 2,
autoPlay: true,
looping: true,
);
```

becomes

```dart
final chewieController = ChewieController(
videoPlayerController: videoPlayerController,
aspectRatio: 3 / 2,
autoPlay: true,
looping: true,
);

final playerWidget = Chewie(
controller: chewieController,
);
```

## iOS Warning
## iOS warning

The video player plugin used by chewie is not functional on iOS simulators. An iOS device must be used during development/testing. Please refer to this [issue](https://github.com/flutter/flutter/issues/14647).

Expand Down
2 changes: 2 additions & 0 deletions analysis_options.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ linter:
- hash_and_equals
- iterable_contains_unrelated_type
- list_remove_unrelated_type
- sort_constructors_first
- test_types_in_equals
- unnecessary_new
- unrelated_type_equality_checks
- valid_regexps
86 changes: 59 additions & 27 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 @@ -10,10 +11,10 @@ void main() {
}

class ChewieDemo extends StatefulWidget {
final String title;

ChewieDemo({this.title = 'Chewie Demo'});

final String title;

@override
State<StatefulWidget> createState() {
return _ChewieDemoState();
Expand All @@ -22,16 +23,46 @@ class ChewieDemo extends StatefulWidget {

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

@override
void initState() {
super.initState();
_controller = VideoPlayerController.network(
'https://flutter.github.io/assets-for-api-docs/assets/videos/butterfly.mp4',
_videoPlayerController1 = VideoPlayerController.network(
'https://flutter.github.io/assets-for-api-docs/assets/videos/butterfly.mp4');
_videoPlayerController2 = VideoPlayerController.network(
'https://www.sample-videos.com/video123/mp4/480/big_buck_bunny_480p_20mb.mp4');
_chewieController = ChewieController(
videoPlayerController: _videoPlayerController1,
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
void dispose() {
_videoPlayerController1.dispose();
_videoPlayerController2.dispose();
_chewieController.dispose();
super.dispose();
}

@override
Widget build(BuildContext context) {
return MaterialApp(
Expand All @@ -48,35 +79,30 @@ 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(
'https://flutter.github.io/assets-for-api-docs/assets/videos/butterfly.mp4',
_chewieController.dispose();
_videoPlayerController2.pause();
_videoPlayerController2.seekTo(Duration(seconds: 0));
_chewieController = ChewieController(
videoPlayerController: _videoPlayerController1,
aspectRatio: 3 / 2,
autoPlay: true,
looping: true,
);
});
},
Expand All @@ -90,8 +116,14 @@ 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.dispose();
_videoPlayerController1.pause();
_videoPlayerController1.seekTo(Duration(seconds: 0));
_chewieController = ChewieController(
videoPlayerController: _videoPlayerController2,
aspectRatio: 3 / 2,
autoPlay: true,
looping: true,
);
});
},
Expand Down
1 change: 1 addition & 0 deletions lib/chewie.dart
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
library chewie;

export 'src/chewie_player.dart';
export 'src/chewie_controller.dart';
export 'src/chewie_progress_colors.dart';
165 changes: 165 additions & 0 deletions lib/src/chewie_controller.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,165 @@
import 'package:chewie/src/chewie_progress_colors.dart';
import 'package:flutter/material.dart';
import 'package:video_player/video_player.dart';

class ChewieController extends ChangeNotifier {
cbenhagen marked this conversation as resolved.
Show resolved Hide resolved
ChewieController({
this.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.customControls,
this.allowedScreenSleep = true,
this.isLive = false,
}) : assert(videoPlayerController != null,
'You must provide a controller to play a video') {
_initialize();
}

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

/// 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;

/// Defines customised controls. Check [MaterialControls] or
/// [CupertinoControls] for reference.
final Widget customControls;

/// 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;

bool _isFullScreen = false;

bool get isFullScreen => _isFullScreen;

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

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

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

await videoPlayerController.play();
}

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

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

void enterFullscreen() {
_isFullScreen = true;
notifyListeners();
}

void exitFullscreen() {
_isFullScreen = false;
notifyListeners();
}

void toggleFullscreen() {
_isFullScreen = !_isFullScreen;
notifyListeners();
}

Future<void> play() async {
await videoPlayerController.play();
}

Future<void> setLooping(bool looping) async {
await videoPlayerController.setLooping(looping);
}

Future<void> pause() async {
await videoPlayerController.pause();
}

Future<void> seekTo(Duration moment) async {
await videoPlayerController.seekTo(moment);
}

Future<void> setVolume(double volume) async {
await videoPlayerController.setVolume(volume);
}
}

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