chewie
chewie copied to clipboard
controller copyWith not effective in fullscreen
I am changing the overlay when the video is playing. I added a listener to my controller and in it, I check the isPlaying property. If the video is playing, I change the overlay by updating the controller using the copyWith method (in a setState). It works well when the video is not in fullscreen.
When in fullscreen, the overlay doesn't get changed, although isPlaying is true and the line where I update the controller gets executed.
Can you please submit a example project demonstrating this issue? That way I can better diagnose it. Thanks.
This is my widget:
import 'package:cached_network_image/cached_network_image.dart';
...
import 'package:chewie/chewie.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:video_player/video_player.dart';
class MyVideoPlayer extends StatefulWidget {
final Video video;
final double height;
final double width;
MyVideoPlayer({required this.video, required this.height, required this.width});
@override
_MyVideoPlayerState createState() => _MyVideoPlayerState();
}
class _MyVideoPlayerState extends State<MyVideoPlayer> {
VideoPlayerController? _controller;
ChewieController? _chewieController;
bool _overlayRemoved = false;
@override
void initState() {
super.initState();
initializePlayer();
}
Future<void> initializePlayer() async {
_controller = VideoPlayerController.network(widget.video.mp4);
await Future.wait([
_controller!.initialize()
]);
_chewieController = ChewieController(
videoPlayerController: _controller!,
deviceOrientationsAfterFullScreen: [
DeviceOrientation.portraitDown,
DeviceOrientation.portraitUp
],
deviceOrientationsOnEnterFullScreen: [
DeviceOrientation.landscapeLeft,
DeviceOrientation.landscapeRight
],
autoPlay: false,
looping: false,
allowPlaybackSpeedChanging: false,
allowMuting: false,
autoInitialize: false,
overlay: Center(child: CachedNetworkImage(imageUrl: widget.video.thumbnail)),
placeholder: Center(child: CachedNetworkImage(imageUrl: widget.video.thumbnail, )),
customControls: Theme.of(context).platform == TargetPlatform.iOS ? MyCupertinoControls(
backgroundColor: const Color.fromRGBO(41, 41, 41, 0.7),
iconColor: const Color.fromARGB(255, 200, 200, 200),
) : null
);
_controller?.addListener(_controllerListener);
setState(() {});
}
void _controllerListener() {
print("isFullScreen: ${_chewieController?.isFullScreen??false}");
print("isPlaying: ${_chewieController?.isPlaying??false}");
// as soon as we're playing or in fullscreen, remove the overlay thumbnail. If we then pause the video, do nothing
if(!_overlayRemoved && ((_chewieController?.isPlaying??false) || (_chewieController?.isFullScreen??false))) {
setState(() {
_chewieController = _chewieController!.copyWith(overlay: Container());
_overlayRemoved = true;
});
}
}
@override
void dispose() {
_controller?.dispose();
_controller?.removeListener(_controllerListener);
_chewieController?.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return Container(
width: widget.width,
height: widget.height,
decoration: BoxDecoration(boxShadow: [
const BoxShadow(
color: Colors.grey,
offset: const Offset(0.0, 1.0),
blurRadius: 5.0,
)
],
),
child: Container(
decoration: BoxDecoration(
color: Colors.black,
),
child: ClipRRect(
child: _chewieController != null ?
Chewie(
controller: _chewieController!,
) : Container(),
),
),
);
}
}
Please post this in an example repo. This will help me point chewie
into a local copy and debug the code very easily.
Also, based on my initial reading, the reason it might not be working is because the overlay
Widget is final and when you enter full screen, it takes the existing ChewieController
and passes it into another route displaying the video in Full Screen.
One possible solution is to create a builder function for generating the overlay widget that is a mutable member of ChewieController
and whenever this function exists and is updated, it will call notifyListeners
inside ChewieController
, which will then rebuild the PlayerWithControls
widget and thus rebuild the computed overlay.
Bottom line, you'll have to make a change to ChewieController
to support a new builder function that has a setter that calls notifyListeners
whenever the builder function reference changes. You'll also have to make a change to _buildPlayerWithControls
in PlayerAndControls
so that it computes the resulting overlay widget from the controller's function, otherwise it falls back to the controller's overlay widget. Then display that if it exists.
I can most certainly review any PR you submit to this effect.
I needed the overlay to be updated based on if it was fullscreen or not. Added this PR #713