فهرست منبع

Update to 0.4.0

  - Providing a new controller to Chewie now works (fixes #11)
  - Full Screen triggers Landscape on Android (fixes #12)
  - Support for video_player 0.4.0 - 0.5.0 (fixes #13)
Brian Egan 7 سال پیش
والد
کامیت
d5cd113335

+ 1 - 0
.gitignore

@@ -9,3 +9,4 @@ packages
 pubspec.lock
 .iml
 Podfile.lock
+chewie.iml

+ 0 - 23
chewie.iml

@@ -1,23 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<module type="WEB_MODULE" version="4">
-  <component name="NewModuleRootManager" inherit-compiler-output="true">
-    <exclude-output />
-    <content url="file://$MODULE_DIR$">
-      <sourceFolder url="file://$MODULE_DIR$/lib" isTestSource="false" />
-      <sourceFolder url="file://$MODULE_DIR$/test" isTestSource="true" />
-      <excludeFolder url="file://$MODULE_DIR$/.idea" />
-      <excludeFolder url="file://$MODULE_DIR$/.pub" />
-      <excludeFolder url="file://$MODULE_DIR$/build" />
-      <excludeFolder url="file://$MODULE_DIR$/chewie_example/.pub" />
-      <excludeFolder url="file://$MODULE_DIR$/chewie_example/build" />
-      <excludeFolder url="file://$MODULE_DIR$/example/.pub" />
-      <excludeFolder url="file://$MODULE_DIR$/example/build" />
-      <excludeFolder url="file://$MODULE_DIR$/example_new/.pub" />
-      <excludeFolder url="file://$MODULE_DIR$/example_new/build" />
-    </content>
-    <orderEntry type="sourceFolder" forTests="false" />
-    <orderEntry type="library" name="Dart SDK" level="project" />
-    <orderEntry type="library" name="Flutter Plugins" level="project" />
-    <orderEntry type="library" name="Dart Packages" level="project" />
-  </component>
-</module>

+ 1 - 0
example/ios/Flutter/Debug.xcconfig

@@ -1 +1,2 @@
+#include "Pods/Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig"
 #include "Generated.xcconfig"

+ 1 - 0
example/ios/Flutter/Release.xcconfig

@@ -1 +1,2 @@
+#include "Pods/Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"
 #include "Generated.xcconfig"

+ 46 - 8
example/lib/main.dart

@@ -5,19 +5,14 @@ import 'package:video_player/video_player.dart';
 
 void main() {
   runApp(
-    new ChewieDemo(
-      controller: new VideoPlayerController.network(
-        'https://flutter.github.io/assets-for-api-docs/videos/butterfly.mp4',
-      ),
-    ),
+    new ChewieDemo(),
   );
 }
 
 class ChewieDemo extends StatefulWidget {
   final String title;
-  final VideoPlayerController controller;
 
-  ChewieDemo({this.title = 'Chewie Demo', this.controller});
+  ChewieDemo({this.title = 'Chewie Demo'});
 
   @override
   State<StatefulWidget> createState() {
@@ -27,6 +22,15 @@ class ChewieDemo extends StatefulWidget {
 
 class _ChewieDemoState extends State<ChewieDemo> {
   TargetPlatform _platform;
+  VideoPlayerController _controller;
+
+  @override
+  void initState() {
+    super.initState();
+    _controller = new VideoPlayerController.network(
+      'https://flutter.github.io/assets-for-api-docs/videos/butterfly.mp4',
+    );
+  }
 
   @override
   Widget build(BuildContext context) {
@@ -44,7 +48,7 @@ class _ChewieDemoState extends State<ChewieDemo> {
             new Expanded(
               child: new Center(
                 child: new Chewie(
-                  widget.controller,
+                  _controller,
                   aspectRatio: 3 / 2,
                   autoPlay: true,
                   looping: true,
@@ -65,6 +69,40 @@ class _ChewieDemoState extends State<ChewieDemo> {
                 ),
               ),
             ),
+            new Row(
+              children: <Widget>[
+                new Expanded(
+                  child: new FlatButton(
+                    onPressed: () {
+                      setState(() {
+                        _controller = new VideoPlayerController.network(
+                          'https://flutter.github.io/assets-for-api-docs/videos/butterfly.mp4',
+                        );
+                      });
+                    },
+                    child: new Padding(
+                      child: new Text("Video 1"),
+                      padding: new EdgeInsets.symmetric(vertical: 16.0),
+                    ),
+                  ),
+                ),
+                new Expanded(
+                  child: new FlatButton(
+                    onPressed: () {
+                      setState(() {
+                        _controller = new VideoPlayerController.network(
+                          'http://www.sample-videos.com/video/mp4/720/big_buck_bunny_720p_20mb.mp4',
+                        );
+                      });
+                    },
+                    child: new Padding(
+                      padding: new EdgeInsets.symmetric(vertical: 16.0),
+                      child: new Text("Video 2"),
+                    ),
+                  ),
+                )
+              ],
+            ),
             new Row(
               children: <Widget>[
                 new Expanded(

+ 46 - 16
lib/src/chewie_player.dart

@@ -1,12 +1,12 @@
+import 'dart:async';
+
 import 'package:chewie/src/chewie_progress_colors.dart';
+import 'package:chewie/src/player_with_controls.dart';
 import 'package:flutter/material.dart';
 import 'package:flutter/services.dart';
 import 'package:flutter/widgets.dart';
-import 'package:chewie/src/player_with_controls.dart';
-import 'dart:async';
 import 'package:video_player/video_player.dart';
 
-
 /// A Video Player with Material and Cupertino skins.
 ///
 /// `video_player` is pretty low level. Chewie wraps it in a friendly skin to
@@ -56,8 +56,7 @@ class Chewie extends StatefulWidget {
     this.materialProgressColors,
     this.placeholder,
     this.showControls = true,
-  })
-      : assert(controller != null,
+  })  : assert(controller != null,
             'You must provide a controller to play a video'),
         super(key: key);
 
@@ -68,13 +67,12 @@ class Chewie extends StatefulWidget {
 }
 
 class _ChewiePlayerState extends State<Chewie> {
-  bool initialized = false;
-  VoidCallback listener;
+  VideoPlayerController _controller;
 
   @override
   Widget build(BuildContext context) {
     return new PlayerWithControls(
-      controller: widget.controller,
+      controller: _controller,
       onExpandCollapse: () => _pushFullScreenWidget(context),
       aspectRatio: widget.aspectRatio ?? _calculateAspectRatio(context),
       cupertinoProgressColors: widget.cupertinoProgressColors,
@@ -88,6 +86,7 @@ class _ChewiePlayerState extends State<Chewie> {
   @override
   void initState() {
     super.initState();
+    _controller = widget.controller;
     _initialize();
   }
 
@@ -96,9 +95,10 @@ class _ChewiePlayerState extends State<Chewie> {
     return new Scaffold(
       resizeToAvoidBottomPadding: false,
       body: new Container(
+        alignment: Alignment.center,
         color: Colors.black,
         child: new PlayerWithControls(
-          controller: widget.controller,
+          controller: _controller,
           onExpandCollapse: () =>
               new Future<dynamic>.value(Navigator.of(context).pop()),
           aspectRatio: widget.aspectRatio ?? _calculateAspectRatio(context),
@@ -124,28 +124,58 @@ class _ChewiePlayerState extends State<Chewie> {
   }
 
   Future _initialize() async {
-    await widget.controller.setLooping(widget.looping);
+    await _controller.setLooping(widget.looping);
 
     if (widget.autoInitialize || widget.autoPlay) {
-      await widget.controller.initialize();
+      await _controller.initialize();
     }
 
     if (widget.autoPlay) {
-      await widget.controller.play();
+      await _controller.play();
+    }
+  }
+
+  @override
+  void didUpdateWidget(Chewie oldWidget) {
+    super.didUpdateWidget(oldWidget);
+
+    if (widget.controller.dataSource != _controller.dataSource) {
+      _controller.dispose();
+      _controller = widget.controller;
+      _initialize();
     }
   }
 
-  Future<dynamic> _pushFullScreenWidget(BuildContext context) {
+  @override
+  void dispose() {
+    _controller.dispose();
+    super.dispose();
+  }
+
+  Future<dynamic> _pushFullScreenWidget(BuildContext context) async {
+    final isAndroid = Theme.of(context).platform == TargetPlatform.android;
     final TransitionRoute<Null> route = new PageRouteBuilder<Null>(
       settings: new RouteSettings(isInitialRoute: false),
       pageBuilder: _fullScreenRoutePageBuilder,
     );
 
     SystemChrome.setEnabledSystemUIOverlays([]);
+    if (isAndroid) {
+      SystemChrome.setPreferredOrientations([
+        DeviceOrientation.landscapeLeft,
+        DeviceOrientation.landscapeRight,
+      ]);
+    }
+
+    await Navigator.of(context).push(route);
 
-    return Navigator.of(context).push(route).then<Null>((_) {
-      SystemChrome.setEnabledSystemUIOverlays(SystemUiOverlay.values);
-    });
+    SystemChrome.setEnabledSystemUIOverlays(SystemUiOverlay.values);
+    SystemChrome.setPreferredOrientations([
+      DeviceOrientation.portraitUp,
+      DeviceOrientation.portraitDown,
+      DeviceOrientation.landscapeLeft,
+      DeviceOrientation.landscapeRight,
+    ]);
   }
 
   double _calculateAspectRatio(BuildContext context) {

+ 28 - 15
lib/src/cupertino_controls.dart

@@ -39,9 +39,10 @@ class _CupertinoControlsState extends State<CupertinoControls> {
   VideoPlayerValue _latestValue;
   double _latestVolume;
   bool _hideStuff = true;
-  bool _disposed = false;
   Timer _hideTimer;
   final marginSize = 5.0;
+  Timer _expandCollapseTimer;
+  Timer _initTimer;
 
   @override
   Widget build(BuildContext context) {
@@ -64,11 +65,17 @@ class _CupertinoControlsState extends State<CupertinoControls> {
 
   @override
   void dispose() {
-    widget.controller.removeListener(_updateState);
-    _disposed = true;
+    _dispose();
     super.dispose();
   }
 
+  void _dispose() {
+    widget.controller.removeListener(_updateState);
+    _hideTimer?.cancel();
+    _expandCollapseTimer?.cancel();
+    _initTimer?.cancel();
+  }
+
   @override
   void initState() {
     _initialize();
@@ -76,6 +83,16 @@ class _CupertinoControlsState extends State<CupertinoControls> {
     super.initState();
   }
 
+  @override
+  void didUpdateWidget(CupertinoControls oldWidget) {
+    super.didUpdateWidget(oldWidget);
+
+    if (widget.controller.dataSource != oldWidget.controller.dataSource) {
+      _dispose();
+      _initialize();
+    }
+  }
+
   AnimatedOpacity _buildBottomBar(
     Color backgroundColor,
     Color iconColor,
@@ -383,7 +400,7 @@ class _CupertinoControlsState extends State<CupertinoControls> {
       _startHideTimer();
     }
 
-    new Timer(new Duration(milliseconds: 200), () {
+    _initTimer = new Timer(new Duration(milliseconds: 200), () {
       setState(() {
         _hideStuff = false;
       });
@@ -395,12 +412,10 @@ class _CupertinoControlsState extends State<CupertinoControls> {
       _hideStuff = true;
 
       widget.onExpandCollapse().then((dynamic _) {
-        new Timer(new Duration(milliseconds: 300), () {
-          if (!_disposed) {
-            setState(() {
-              _cancelAndRestartTimer();
-            });
-          }
+        _expandCollapseTimer = new Timer(new Duration(milliseconds: 300), () {
+          setState(() {
+            _cancelAndRestartTimer();
+          });
         });
       });
     });
@@ -489,11 +504,9 @@ class _CupertinoControlsState extends State<CupertinoControls> {
 
   void _startHideTimer() {
     _hideTimer = new Timer(const Duration(seconds: 3), () {
-      if (!_disposed) {
-        setState(() {
-          _hideStuff = true;
-        });
-      }
+      setState(() {
+        _hideStuff = true;
+      });
     });
   }
 

+ 30 - 20
lib/src/material_controls.dart

@@ -32,8 +32,9 @@ class _MaterialControlsState extends State<MaterialControls> {
   VideoPlayerValue _latestValue;
   double _latestVolume;
   bool _hideStuff = true;
-  bool _disposed = false;
   Timer _hideTimer;
+  Timer _showTimer;
+  Timer _showAfterExpandCollapseTimer;
   bool _dragging = false;
 
   final barHeight = 48.0;
@@ -41,23 +42,27 @@ class _MaterialControlsState extends State<MaterialControls> {
 
   @override
   Widget build(BuildContext context) {
-    final controller = widget.controller;
-
     return new Column(
       children: <Widget>[
         _buildHitArea(),
-        _buildBottomBar(context, controller),
+        _buildBottomBar(context, widget.controller),
       ],
     );
   }
 
   @override
   void dispose() {
-    widget.controller.removeListener(_updateState);
-    _disposed = true;
+    _dispose();
     super.dispose();
   }
 
+  void _dispose() {
+    widget.controller.removeListener(_updateState);
+    _hideTimer?.cancel();
+    _showTimer?.cancel();
+    _showAfterExpandCollapseTimer?.cancel();
+  }
+
   @override
   void initState() {
     _initialize();
@@ -65,6 +70,15 @@ class _MaterialControlsState extends State<MaterialControls> {
     super.initState();
   }
 
+  @override
+  void didUpdateWidget(MaterialControls oldWidget) {
+    super.didUpdateWidget(oldWidget);
+    if (widget.controller.dataSource != oldWidget.controller.dataSource) {
+      _dispose();
+      _initialize();
+    }
+  }
+
   AnimatedOpacity _buildBottomBar(
     BuildContext context,
     VideoPlayerController controller,
@@ -229,11 +243,10 @@ class _MaterialControlsState extends State<MaterialControls> {
 
   void _cancelAndRestartTimer() {
     _hideTimer?.cancel();
+    _startHideTimer();
 
     setState(() {
       _hideStuff = false;
-
-      _startHideTimer();
     });
   }
 
@@ -248,7 +261,7 @@ class _MaterialControlsState extends State<MaterialControls> {
       _startHideTimer();
     }
 
-    new Timer(new Duration(milliseconds: 200), () {
+    _showTimer = new Timer(new Duration(milliseconds: 200), () {
       setState(() {
         _hideStuff = false;
       });
@@ -260,12 +273,11 @@ class _MaterialControlsState extends State<MaterialControls> {
       _hideStuff = true;
 
       widget.onExpandCollapse().then((dynamic _) {
-        new Timer(new Duration(milliseconds: 300), () {
-          if (!_disposed) {
-            setState(() {
-              _cancelAndRestartTimer();
-            });
-          }
+        _showAfterExpandCollapseTimer =
+            new Timer(new Duration(milliseconds: 300), () {
+          setState(() {
+            _cancelAndRestartTimer();
+          });
         });
       });
     });
@@ -293,11 +305,9 @@ class _MaterialControlsState extends State<MaterialControls> {
 
   void _startHideTimer() {
     _hideTimer = new Timer(const Duration(seconds: 3), () {
-      if (!_disposed) {
-        setState(() {
-          _hideStuff = true;
-        });
-      }
+      setState(() {
+        _hideStuff = true;
+      });
     });
   }
 

+ 46 - 24
lib/src/player_with_controls.dart

@@ -1,14 +1,13 @@
+import 'dart:async';
+import 'dart:ui';
+
 import 'package:chewie/src/chewie_progress_colors.dart';
+import 'package:chewie/src/cupertino_controls.dart';
+import 'package:chewie/src/material_controls.dart';
 import 'package:flutter/foundation.dart';
 import 'package:flutter/material.dart';
 import 'package:video_player/video_player.dart';
 
-import 'dart:async';
-
-import 'dart:ui';
-import 'package:chewie/src/material_controls.dart';
-import 'package:chewie/src/cupertino_controls.dart';
-
 class PlayerWithControls extends StatefulWidget {
   final VideoPlayerController controller;
   final Future<dynamic> Function() onExpandCollapse;
@@ -31,8 +30,7 @@ class PlayerWithControls extends StatefulWidget {
     this.materialProgressColors,
     this.placeholder,
     this.autoPlay,
-  })
-      : super(key: key);
+  }) : super(key: key);
 
   @override
   State createState() {
@@ -48,24 +46,38 @@ class _VideoPlayerWithControlsState extends State<PlayerWithControls> {
     return new Center(
       child: new Container(
         width: MediaQuery.of(context).size.width,
-        child: new AspectRatio(
-          aspectRatio: widget.aspectRatio,
-          child: new Container(
-            child: new Stack(
-              children: <Widget>[
-                widget.placeholder ?? new Container(),
-                new Hero(
-                  tag: controller,
-                  child: new AspectRatio(
-                    aspectRatio: widget.aspectRatio,
-                    child: new VideoPlayer(controller),
-                  ),
-                ),
-                _buildControls(context, controller),
-              ],
+        child: widget.fullScreen &&
+                MediaQuery.of(context).orientation == Orientation.landscape
+            ? _buildPlayerWithControls(controller, context)
+            : new AspectRatio(
+                aspectRatio: widget.aspectRatio,
+                child: _buildPlayerWithControls(controller, context),
+              ),
+      ),
+    );
+  }
+
+  Container _buildPlayerWithControls(
+      VideoPlayerController controller, BuildContext context) {
+    return new Container(
+      child: new Stack(
+        children: <Widget>[
+          widget.placeholder ?? new Container(),
+          new Center(
+            child: new Hero(
+              tag: controller,
+              child: widget.fullScreen &&
+                      MediaQuery.of(context).orientation ==
+                          Orientation.landscape
+                  ? new VideoPlayer(controller)
+                  : new AspectRatio(
+                      aspectRatio: widget.aspectRatio,
+                      child: new VideoPlayer(controller),
+                    ),
             ),
           ),
-        ),
+          _buildControls(context, controller),
+        ],
       ),
     );
   }
@@ -104,6 +116,16 @@ class _VideoPlayerWithControlsState extends State<PlayerWithControls> {
     super.initState();
   }
 
+
+  @override
+  void didUpdateWidget(PlayerWithControls oldWidget) {
+    super.didUpdateWidget(oldWidget);
+
+    if (widget.controller.dataSource != oldWidget.controller.dataSource) {
+      widget.controller.addListener(_onPlay);
+    }
+  }
+
   void _onPlay() {
     if (widget.controller.value.isPlaying) {
       setState(() {

+ 5 - 3
pubspec.yaml

@@ -1,13 +1,15 @@
 name: chewie
 description: The video player for Flutter with a heart of gold
-version: 0.3.0
+version: 0.4.0
 homepage: https://github.com/brianegan/chewie
 author: Brian Egan <brian@brianegan.com>
 
+environment:
+  sdk: ">=2.0.0-dev.28.0 <3.0.0"
+
 dependencies:
   open_iconic_flutter: ">=0.2.0 <0.3.0"
-  connectivity: ">=0.1.1 <0.2.0"
-  video_player: ">=0.4.0 <=0.5.0"
+  video_player: ">=0.4.0 <0.5.0"
   flutter:
     sdk: flutter