I have four files
- home_page.dart: home_page.dart showcases images and text. Upon clicking, it passes the video URL to webview_page.dart.
- webview_page.dart: Upon receiving the nativeVid (video URL) from home_page.dart, webview_page.dart forwards this information to video_player.dart.
- video_player.dart: video_player.dart utilizes the nativeVid (video URL) to initiate video playback.
- video_tv_fullscreen.dart: When the player enters fullscreen mode, video_tv_fullscreen.dart takes effect.
Question: The functionality operates smoothly until the transition to fullscreen mode. Upon initiating fullscreen, the dispose method in video_player.dart is triggered, video can't be play anymore. Why does this occur? If there is not in fullscreen mode the video works well.
home_page.dart
import 'package:xxxxx/pages/webview/webview_page.dart';
...
String webviewUrl = Constant.shareUrl + '12345';
Navigator.of(context).push(SlideAnimationRoute(
builder: (_) {
return WebViewPage(webviewUrl, isFromNative: true);
},
));
webview_page.dart
import 'package:xxxxx/pages/webview/video_player.dart';
...
@override
Widget build(BuildContext context) {
return WillPopScope(
child: Stack(
children: <Widget>[
Scaffold(
backgroundColor: Colors.transparent,
body: Builder(builder: (BuildContext context) {
return Container(
height: MediaQuery.of(context).size.width * 9.0 / 16,
child: VideoPlayer(
key: _refreshKey,
VideoDetailPageParamsBean.createInstance(
vid: nativeVid,
enterSource:
VideoDetailsEnterSource.VideoDetailsEnterSourceHome,
),
webviewVid: nativeVid,
),
);
}),
),
],
),
);
}
video_player.dart:
import 'package:xxxxx/pages/video/player/video_tv_fullscreen.dart';
class _VideoPlayerState extends State<VideoPlayer>
with SingleTickerProviderStateMixin, RouteAware, WidgetsBindingObserver {
VideoPlayerController? _videoPlayerController;
ChewieController? _chewieController;
void initState() {
super.initState();
.....
_initPageData();
}
void _initPageData() async {
.....
_initVideoPlayers(
_videoDetailPageParamsBean.getVideoSource, false, startAt);
.....
}
Future<void> _initVideoPlayers(
String videoUrl, bool isFullScreen, Duration startAt) async {
_isVideoReportSuccess = false;
_videoPlayerController = VideoPlayerController.network(videoUrl);
_hasReportedVideoPlay = false;
_videoLoadStartTime = DateTime.now();
try {
await _videoPlayerController?.initialize().then((_) {
setState(() {
_chewieController = ChewieController(
videoPlayerController: _videoPlayerController!,
aspectRatio: _videoPlayerController?.value.aspectRatio,
autoPlay: true,
startAt: startAt,
looping: false,
showControlsOnInitialize: false,
allowMuting: false,
isLive: _videoPlayerController?.value.duration == Duration.zero,
routePageBuilder: VideoTvFullScreenBuilder.of(
_videoPlayerController?.value.aspectRatio ?? 0),
deviceOrientationsAfterFullScreen: [DeviceOrientation.portraitUp],
isInitFullScreen: isFullScreen,
);
_isVideoChangedInit = true;
_videoPlayerController?.addListener(videoPlayerChanged);
});
});
} catch (e) {
print('Error $e');
}
}
@override
Widget build(BuildContext context) {
......
}
@override
void dispose() {
WidgetsBinding.instance.removeObserver(this);
VideoDetailDataMgr.instance.clearCachedDataByKey(_pageFlag);
routeObserver.unsubscribe(this);
_chewieController?.dispose();
clearVideoPlayerController();
super.dispose();
}
void clearVideoPlayerController() {
_videoPlayerController?.pause();
_videoPlayerController?.dispose();
}
}
video_tv_fullscreen.dart
import 'package:flutter/material.dart';
import 'package:chewie/chewie.dart';
class VideoTvFullScreenBuilder {
final double aspect;
VideoTvFullScreenBuilder(this.aspect);
AnimatedWidget build(BuildContext context, Animation<double> animation,
Animation<double> secondaryAnimation, dynamic controllerProvider) {
return AnimatedBuilder(
animation: animation,
builder: (BuildContext context, Widget? child) {
return _buildFullScreenVideo(context, animation, controllerProvider);
},
);
}
Widget _buildFullScreenVideo(BuildContext context,
Animation<double> animation, dynamic controllerProvider) {
return Scaffold(
resizeToAvoidBottomInset: false,
body: Container(
alignment: Alignment.center,
decoration: BoxDecoration(
gradient: LinearGradient(
begin: Alignment.topCenter,
end: Alignment.bottomCenter,
colors: [Color.fromRGBO(84, 84, 84, 1.0), Colors.black],
),
),
child: Container(
height: MediaQuery.of(context).size.width / aspect,
child: ClipRect(
child: controllerProvider,
))),
);
}
static ChewieRoutePageBuilder of(double aspect) {
return VideoTvFullScreenBuilder(aspect).build;
}
}
It sounds like you're facing an issue where enabling fullscreen mode in your app leads to a screen rotation and recreation of the activity, causing your player to be disposed.