Comments (6)
Hey hey :) I'm not quite sure Chewie is the right tool for audio playback. It relies on the video_player
plugin, which is tailor-made for delivering video content to a Flutter app by forwarding texture information from ExoPlayer or AVPlayer, and doesn't officially support audio playback and all of the intricacies involved with that (and there are a lot). Since these two tools support audio, it works, but I really feel it's using the wrong tool for the job.
In addition, I don't know if it's a great idea to support both audio and video from this one package. I could see many use-cases making sense for audio but not video and vice-versa, and supporting all of those throughout the code with if
statements is going to be a maintenance headache going forward.
I think it would make more sense to fork Chewie and use a proper audio-player plugin that doesn't incur the overhead of trying to deliver video content to Flutter, and gives the flexibility of delivering an experience that can really focus on audio (sleep timers, 2x playback, background playing, not going into full screen mode when the device is rotated, etc).
from chewie.
Hey @brianegan and @cbenhagen, just wanted to let you know I've created a fork of Chewie for audio only playback that hides the video box. It's published at https://pub.dev/packages/chewie_audio.
I've tentatively kept both of you as authors of the package on Pub, since most of the codebase comes from your contributions. I'm not sure if Pub notifies all authors or just uploaders when a new version is pushed, so let me know if you would like to be removed as an author for the package.
from chewie.
I have finished the implementation. How should I submit the pull request?
Here is the diff from v0.5.0.
diff --git a/lib/src/chewie_player.dart b/lib/src/chewie_player.dart
index b249a82..1a04e45 100644
--- a/lib/src/chewie_player.dart
+++ b/lib/src/chewie_player.dart
@@ -27,6 +27,9 @@ class Chewie extends StatefulWidget {
/// Whether or not to show the controls
final bool showControls;
+ /// Whether or not to display a video box
+ final bool showVideoBox;
+
/// The Aspect Ratio of the Video. Important to get the correct size of the
/// video!
///
@@ -56,6 +59,7 @@ class Chewie extends StatefulWidget {
this.materialProgressColors,
this.placeholder,
this.showControls = true,
+ this.showVideoBox = true,
}) : assert(controller != null,
'You must provide a controller to play a video'),
super(key: key);
@@ -80,6 +84,7 @@ class _ChewiePlayerState extends State<Chewie> {
placeholder: widget.placeholder,
autoPlay: widget.autoPlay,
showControls: widget.showControls,
+ showVideoBox: widget.showVideoBox,
);
}
diff --git a/lib/src/cupertino_controls.dart b/lib/src/cupertino_controls.dart
index 2a08c2f..112b98f 100644
--- a/lib/src/cupertino_controls.dart
+++ b/lib/src/cupertino_controls.dart
@@ -18,6 +18,7 @@ class CupertinoControls extends StatefulWidget {
final bool fullScreen;
final ChewieProgressColors progressColors;
final bool autoPlay;
+ final bool hasVideo;
CupertinoControls({
@required this.backgroundColor,
@@ -27,6 +28,7 @@ class CupertinoControls extends StatefulWidget {
@required this.fullScreen,
@required this.progressColors,
@required this.autoPlay,
+ this.hasVideo = true,
});
@override
@@ -53,13 +55,15 @@ class _CupertinoControlsState extends State<CupertinoControls> {
final barHeight = orientation == Orientation.portrait ? 30.0 : 47.0;
final buttonPadding = orientation == Orientation.portrait ? 16.0 : 24.0;
+ List<Widget> widgets = [];
+ if (widget.hasVideo) {
+ widgets.add(_buildTopBar(backgroundColor, iconColor, controller, barHeight, buttonPadding));
+ widgets.add(_buildHitArea());
+ }
+ widgets.add(_buildBottomBar(backgroundColor, iconColor, controller, barHeight));
+
return new Column(
- children: <Widget>[
- _buildTopBar(
- backgroundColor, iconColor, controller, barHeight, buttonPadding),
- _buildHitArea(),
- _buildBottomBar(backgroundColor, iconColor, controller, barHeight),
- ],
+ children: widgets,
);
}
@@ -80,6 +84,7 @@ class _CupertinoControlsState extends State<CupertinoControls> {
void initState() {
_initialize();
+ if (! widget.hasVideo) _hideStuff = false;
super.initState();
}
@@ -385,7 +390,7 @@ class _CupertinoControlsState extends State<CupertinoControls> {
setState(() {
_hideStuff = false;
- _startHideTimer();
+ if (widget.hasVideo) _startHideTimer();
});
}
@@ -397,7 +402,7 @@ class _CupertinoControlsState extends State<CupertinoControls> {
if ((widget.controller.value != null &&
widget.controller.value.isPlaying) ||
widget.autoPlay) {
- _startHideTimer();
+ if (widget.hasVideo) _startHideTimer();
}
_initTimer = new Timer(new Duration(milliseconds: 200), () {
@@ -409,7 +414,7 @@ class _CupertinoControlsState extends State<CupertinoControls> {
void _onExpandCollapse() {
setState(() {
- _hideStuff = true;
+ if (widget.hasVideo) _hideStuff = true;
widget.onExpandCollapse().then((dynamic _) {
_expandCollapseTimer = new Timer(new Duration(milliseconds: 300), () {
@@ -431,7 +436,7 @@ class _CupertinoControlsState extends State<CupertinoControls> {
_hideTimer?.cancel();
},
onDragEnd: () {
- _startHideTimer();
+ if (widget.hasVideo) _startHideTimer();
},
colors: widget.progressColors ??
new ChewieProgressColors(
@@ -505,7 +510,7 @@ class _CupertinoControlsState extends State<CupertinoControls> {
void _startHideTimer() {
_hideTimer = new Timer(const Duration(seconds: 3), () {
setState(() {
- _hideStuff = true;
+ if (widget.hasVideo) _hideStuff = true;
});
});
}
diff --git a/lib/src/material_controls.dart b/lib/src/material_controls.dart
index 5c01696..cb68ae7 100644
--- a/lib/src/material_controls.dart
+++ b/lib/src/material_controls.dart
@@ -13,6 +13,7 @@ class MaterialControls extends StatefulWidget {
final Future<dynamic> Function() onExpandCollapse;
final ChewieProgressColors progressColors;
final bool autoPlay;
+ final bool hasVideo;
MaterialControls({
@required this.controller,
@@ -20,6 +21,7 @@ class MaterialControls extends StatefulWidget {
@required this.onExpandCollapse,
@required this.progressColors,
@required this.autoPlay,
+ this.hasVideo = true,
});
@override
@@ -44,7 +46,7 @@ class _MaterialControlsState extends State<MaterialControls> {
Widget build(BuildContext context) {
return new Column(
children: <Widget>[
- _buildHitArea(),
+ widget.hasVideo ? _buildHitArea() : Container(),
_buildBottomBar(context, widget.controller),
],
);
@@ -65,6 +67,7 @@ class _MaterialControlsState extends State<MaterialControls> {
@override
void initState() {
+ if (!widget.hasVideo) _hideStuff = false;
_initialize();
super.initState();
@@ -243,7 +246,7 @@ class _MaterialControlsState extends State<MaterialControls> {
void _cancelAndRestartTimer() {
_hideTimer?.cancel();
- _startHideTimer();
+ if (widget.hasVideo) _startHideTimer();
setState(() {
_hideStuff = false;
@@ -258,7 +261,7 @@ class _MaterialControlsState extends State<MaterialControls> {
if ((widget.controller.value != null &&
widget.controller.value.isPlaying) ||
widget.autoPlay) {
- _startHideTimer();
+ if (widget.hasVideo) _startHideTimer();
}
_showTimer = new Timer(new Duration(milliseconds: 200), () {
@@ -270,7 +273,7 @@ class _MaterialControlsState extends State<MaterialControls> {
void _onExpandCollapse() {
setState(() {
- _hideStuff = true;
+ if (widget.hasVideo) _hideStuff = true;
widget.onExpandCollapse().then((dynamic _) {
_showAfterExpandCollapseTimer =
@@ -306,7 +309,7 @@ class _MaterialControlsState extends State<MaterialControls> {
void _startHideTimer() {
_hideTimer = new Timer(const Duration(seconds: 3), () {
setState(() {
- _hideStuff = true;
+ if (widget.hasVideo) _hideStuff = true;
});
});
}
@@ -335,7 +338,7 @@ class _MaterialControlsState extends State<MaterialControls> {
_dragging = false;
});
- _startHideTimer();
+ if (widget.hasVideo) _startHideTimer();
},
colors: widget.progressColors ??
new ChewieProgressColors(
diff --git a/lib/src/player_with_controls.dart b/lib/src/player_with_controls.dart
index 34e2a8d..dbd3977 100644
--- a/lib/src/player_with_controls.dart
+++ b/lib/src/player_with_controls.dart
@@ -18,6 +18,7 @@ class PlayerWithControls extends StatefulWidget {
final double aspectRatio;
final bool autoPlay;
final bool showControls;
+ final bool showVideoBox;
PlayerWithControls({
Key key,
@@ -26,6 +27,7 @@ class PlayerWithControls extends StatefulWidget {
@required this.aspectRatio,
this.fullScreen = false,
this.showControls = true,
+ this.showVideoBox = true,
this.cupertinoProgressColors,
this.materialProgressColors,
this.placeholder,
@@ -43,43 +45,67 @@ class _VideoPlayerWithControlsState extends State<PlayerWithControls> {
Widget build(BuildContext context) {
final controller = widget.controller;
- return new Center(
- child: new Container(
- width: MediaQuery.of(context).size.width,
- child: widget.fullScreen &&
- MediaQuery.of(context).orientation == Orientation.landscape
- ? _buildPlayerWithControls(controller, context)
- : new AspectRatio(
- aspectRatio: widget.aspectRatio,
- child: _buildPlayerWithControls(controller, context),
- ),
- ),
- );
+ if (widget.showVideoBox) {
+ return new Center(
+ child: new Container(
+ width: MediaQuery.of(context).size.width,
+ child: widget.fullScreen &&
+ MediaQuery.of(context).orientation == Orientation.landscape
+ ? _buildPlayerWithControls(controller, context)
+ : new AspectRatio(
+ aspectRatio: widget.aspectRatio,
+ child: _buildPlayerWithControls(controller, context),
+ ),
+ ),
+ );
+ }
+ else {
+ return new Center(
+ 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),
- ),
+ if (widget.showVideoBox) {
+ return new Container(
+ color:Colors.black,
+ 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),
- ],
- ),
- );
+ _buildControls(context, controller),
+ ],
+ ),
+ );
+ }
+ else {
+ return new Container(
+ child: new Stack(
+ children: <Widget>[
+ new Container(
+ height:48.0,
+ width:double.infinity,
+ child: new VideoPlayer(controller),
+ ),
+ _buildControls(context, controller),
+ ],
+ ),
+ );
+ }
}
Widget _buildControls(
@@ -94,6 +120,7 @@ class _VideoPlayerWithControlsState extends State<PlayerWithControls> {
fullScreen: widget.fullScreen,
progressColors: widget.materialProgressColors,
autoPlay: widget.autoPlay,
+ hasVideo: widget.showVideoBox,
)
: new CupertinoControls(
backgroundColor: new Color.fromRGBO(41, 41, 41, 0.7),
@@ -103,6 +130,7 @@ class _VideoPlayerWithControlsState extends State<PlayerWithControls> {
fullScreen: widget.fullScreen,
progressColors: widget.cupertinoProgressColors,
autoPlay: widget.autoPlay,
+ hasVideo: widget.showVideoBox,
)
: new Container();
}
from chewie.
I agree that a full-fledged audio player app should allow for sleep timers, background playing, etc, but I also think that Flutter needs a simple "plug and play" solution for media.
I'd like to see the video_player and audioplayer plugins get merged into a unified API so that media handling is as easy as image handling. The plugin should provide for accelerated playback, background playback, etc, and then plugins like chewie can focus on the display side of things.
Bottom line, I'm using chewie for this because the API is well-designed and because the visual controls are already there. I don't want to reinvent a wheel that just needs to be polished!
Thanks for your consideration anyway.
from chewie.
What do you think @brianegan & @jeffmikels, should we leave this open?
from chewie.
Hey there -- I'm sympathetic to the original goal, but I still feel Chewie is the wrong tool for audio playback since it relies on video_player, and I don't think we should support it.
from chewie.
Related Issues (20)
- Pip issue in Chewei Player and adding ads like youtube
- 'video/avc' not play HOT 1
- Unable to play local video in macOS
- Plugin does not support cache HOT 1
- How to disable wakelock on IOS side? HOT 1
- i need to change Chewie video player for flutter take up the whole screen size regardless of video dimensions?
- Zoom not working in fullscreen HOT 2
- Bug: App Orientation Does Not Return to Portrait on Exiting Full Screen Mode
- Chewie Video Player Stuck On Loading Forever
- How to play from beginning?
- Videos very rarely playing on Firefox on Android phone
- Controls UI Overlap Issue
- Does chewie honor the `closedCaptionFile` in VideoPlayerController?
- no sound when playing videos using Chewie HOT 2
- I can't play a live hls video in my app
- [iOS] privacy manifest HOT 2
- Error: Member not found: 'SystemChrome.setEnabledSystemUIOverlays'. HOT 1
- App crashed Due to listview chewie
- Could not find com.android.tools.build:gradle:8.1.2.
- when I play a url with "m3u8" on iPhone device,it a living url, when I start ,the center button alaways is replay button, the function is ok ,just the icon is alaways replay button, how to resolve this problem! HOT 1
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from chewie.