chewie
chewie copied to clipboard
Video disappear on exiting full screen
Flutter Web
Video plays absolutely fine in normal screen, but fails to play after exiting from Full screen Flutter_Web
tested in iOS Simulator. it is the same. Video disappears on exiting full screen
I encountered the same. I will investigate ASAP. Maybe something with the old fashioned InheritedWidget. Maybe we should change to Provider or Riverpod here.
following. also experiencing this In flutter web
Same here for flutter web.
@Ahmadre any workaround for this issue?
I spend the last two days rewriting the existing code in order to make the fullscreen work on Flutter Web. The problem is that its somehow not working correctly if there is only 1 instance of VideoPlayerController used. So, you would need a separate instance of a ChewieController for the fullscreen widget and also for the default widget. Each instance needs to be initialized separately.
Unfortunately it is not that easy to implement because the entire code is written to work only with a single instance. If someone is interested I can share it, but had not yet the time to clean it up and optimize it.
Currently, the only workaround that I found in building this is to use HTML concept in a flutter.
Widget _iframeWidget;
html.VideoElement iFrameWidgets;
So in the initState you can define widget
iFrameWidgets = html.VideoElement();
iFrameWidgets.src = "link";
iFrameWidgets.controls = true;
use dart:ui as ui
ui.platformViewRegistry.registerViewFactory( 'videoElement, (int viewId) => iFrameWidgets, );
And then render it
_iframeWidget = HtmlElementView( key: UniqueKye(), viewType: "videoElement", );
I spend the last two days rewriting the existing code in order to make the fullscreen work on Flutter Web. The problem is that its somehow not working correctly if there is only 1 instance of VideoPlayerController used. So, you would need a separate instance of a ChewieController for the fullscreen widget and also for the default widget. Each instance needs to be initialized separately.
Unfortunately it is not that easy to implement because the entire code is written to work only with a single instance. If someone is interested I can share it, but had not yet the time to clean it up and optimize it.
That would be great, if you would share it! Thanks in advance!
Greetings, any update or tips for this one?
Do you have any solution for this problem?
Is there any solution to this problem?
I encountered the same problem. Is there a solution yet?
Same problem facing. Please Provide solution or Tip ASAP. Thank you
You can use the listener and reinitialize the chewiecontroller it will work fine
chewieController.addListener(() { if (_chewieController.isFullScreen) { // can leave empty } else { print("Full screen exit"); // initialize controller again } });
Here's a complete workaround Widget without using dart:html. It might have a small glitch on exiting the full screen (because of re-initialization and seeking), but is acceptable for now.
import 'package:flutter/material.dart';
import 'package:video_player/video_player.dart';
import 'package:chewie/chewie.dart';
class MyVideoPlayer extends StatefulWidget {
const MyVideoPlayer({Key? key, required this.videoUrl}) : super(key: key);
final String videoUrl;
@override
_MyVideoPlayerState createState() => _MyVideoPlayerState();
}
class _MyVideoPlayerState extends State<MyVideoPlayer> {
late VideoPlayerController _videoController;
late ChewieController _chewieController;
Duration _currentPosition = Duration.zero;
bool _isPlaying = false;
void _initControllers() {
_videoController = VideoPlayerController.network(widget.videoUrl)
..initialize().then((value) {
_videoController.seekTo(_currentPosition);
setState(() {});
});
_chewieController = ChewieController(
videoPlayerController: _videoController,
)..addListener(_reInitListener);
if (_isPlaying) {
_chewieController.play();
}
}
void _reInitControllers() {
_chewieController.removeListener(_reInitListener);
_currentPosition = _videoController.value.position;
_isPlaying = _chewieController.isPlaying;
_initControllers();
}
void _reInitListener() {
if (!_chewieController.isFullScreen) {
_reInitControllers();
}
}
@override
void initState() {
super.initState();
_initControllers();
}
@override
Widget build(BuildContext context) {
return Container(
child: _videoController.value.isInitialized
? Chewie(controller: _chewieController)
: null,
);
}
@override
void dispose() {
_videoController.dispose();
_chewieController.dispose();
super.dispose();
}
}
This unfortunately does not work for me. Would love for this to just work straight out of the package :-(.
Any updates???
It's 2023! still the same issue.
Any updates on this issue? This issue makes this package almost unusable for Flutter Web apps 😞
Here is the workaround I found for it. It's a minimal example which you can adapt to your own case.
Key steps :
- Create a separate widget containing the
Chewiecomponent, in this case, namedVideoView. - Pass a callback function (
refresh()in this example) to theVideoViewwidget. This callback is used to handle the specific moment when the bug occurs. - Add a listener to the
ChewieControllerto track changes in fullscreen mode. - When exiting the full screen, store the
_controller.position(here in a globalgStartAt). - Fire the callback function (
refresh()) to handle the bug at this specific moment.
Now, when using the VideoView:
- Wrap it into a
StatefulBuilder(not necessary if you already use aStatefulWidgetas a parent) - By passing
setStateas a callback function and changing thekey, it creates a new Instance of theVideoViewdirectly from the parent - The video will
autoplayifgStartAt!=null - When popping it from the
AppBar, setgStartAt = null.
import 'dart:math';
import 'package:flutter/material.dart';
import 'package:chewie/chewie.dart';
import 'package:video_player/video_player.dart';
Duration? gStartAt;
class HomePage extends StatelessWidget {
const HomePage({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return Scaffold(
body: StatefulBuilder(
builder: (context, setState) {
Key key = Key('${Random().nextInt(100000)}');
return VideoView(
key: key,
refreshing: () => setState(() {}),
);
},
),
);
}
}
class VideoView extends StatefulWidget {
final Function() refreshing;
const VideoView({
Key? key,
required this.refreshing,
}) : super(key: key);
@override
_VideoViewState createState() => _VideoViewState();
}
class _VideoViewState extends State<VideoView> {
late final VideoPlayerController _controller;
late final ChewieController _chewieController;
@override
void initState() {
super.initState();
_controller = VideoPlayerController.networkUrl(Uri.parse('your_url_here'),);
_chewieController = ChewieController(
videoPlayerController: _controller,
autoPlay: gStartAt != null,
autoInitialize: true,
startAt: gStartAt,
)..addListener(() async {
if (!_chewieController.isFullScreen) {
gStartAt = await _controller.position;
widget.refreshing();
}
});
}
@override
void dispose() {
_controller.dispose();
_chewieController.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.black,
appBar: AppBar(
leading: IconButton(
onPressed: () {
gStartAt = null;
Navigator.pop(context);
},
icon: const Icon(Icons.arrow_back_ios),
),
),
body: Chewie(
controller: _chewieController,
),
);
}
}
Here is the workaround I found for it. It's a minimal example which you can adapt to your own case.
Key steps :
- Create a separate widget containing the
Chewiecomponent, in this case, namedVideoView.- Pass a callback function (
refresh()in this example) to theVideoViewwidget. This callback is used to handle the specific moment when the bug occurs.- Add a listener to the
ChewieControllerto track changes in fullscreen mode.- When exiting the full screen, store the
_controller.position(here in a globalgStartAt).- Fire the callback function (
refresh()) to handle the bug at this specific moment.Now, when using the
VideoView:
- Wrap it into a
StatefulBuilder(not necessary if you already use aStatefulWidgetas a parent)- By passing
setStateas a callback function and changing thekey, it creates a new Instance of theVideoViewdirectly from the parent- The video will
autoplayifgStartAt!=null- When popping it from the
AppBar, setgStartAt = null.import 'dart:math'; import 'package:flutter/material.dart'; import 'package:chewie/chewie.dart'; import 'package:video_player/video_player.dart'; Duration? gStartAt; class HomePage extends StatelessWidget { const HomePage({Key? key}) : super(key: key); @override Widget build(BuildContext context) { return Scaffold( body: StatefulBuilder( builder: (context, setState) { Key key = Key('${Random().nextInt(100000)}'); return VideoView( key: key, refreshing: () => setState(() {}), ); }, ), ); } } class VideoView extends StatefulWidget { final Function() refreshing; const VideoView({ Key? key, required this.refreshing, }) : super(key: key); @override _VideoViewState createState() => _VideoViewState(); } class _VideoViewState extends State<VideoView> { late final VideoPlayerController _controller; late final ChewieController _chewieController; @override void initState() { super.initState(); _controller = VideoPlayerController.networkUrl(Uri.parse('your_url_here'),); _chewieController = ChewieController( videoPlayerController: _controller, autoPlay: gStartAt != null, autoInitialize: true, startAt: gStartAt, )..addListener(() async { if (!_chewieController.isFullScreen) { gStartAt = await _controller.position; widget.refreshing(); } }); } @override void dispose() { _controller.dispose(); _chewieController.dispose(); super.dispose(); } @override Widget build(BuildContext context) { return Scaffold( backgroundColor: Colors.black, appBar: AppBar( leading: IconButton( onPressed: () { gStartAt = null; Navigator.pop(context); }, icon: const Icon(Icons.arrow_back_ios), ), ), body: Chewie( controller: _chewieController, ), ); } }
your key recreate widget and it impossibe to continue play video
any updates without flickering?
Same problem here