chewie
chewie copied to clipboard
app crash when change playback speed when screen is not in full screen
app crash when change playback speed when screen is not in full screen
class VideoPlayerScreen extends StatefulWidget { final String vmID; final int totlaSecondShouldVIdeoPlay; Map<String, dynamic> details;
VideoPlayerScreen( {Key? key, required this.vmID, required this.details, required this.totlaSecondShouldVIdeoPlay}) : super(key: key);
@override _VideoPlayerScreenState createState() => _VideoPlayerScreenState(); }
class _VideoPlayerScreenState extends State<VideoPlayerScreen> with WidgetsBindingObserver { final BaseAPiServices _apiServices = NetworkApiService(); VideoPlayerController? _videoPlayerController; ChewieController? _chewieController; int _playedSeconds = 0; String videoUrl = ""; DateTime? _playStartTime; Duration? _totalPlayedDuration; bool _isVideoPlaying = false; int _lastPlayedSeconds = 0;
@override void initState() { super.initState(); WidgetsBinding.instance.addObserver(this); callApiOrNot(); }
sendDuration({required String duration}) { Map<String, dynamic> body = widget.details; body["duration"] = duration; if (kDebugMode) { print("json body $body"); } // return; String api = API.sendDuration; _apiServices.httpPost( api: api, parameters: body, showLoader: false, success: (sucess) { if (kDebugMode) { print("send done $sucess"); } }, failure: (error) { if (kDebugMode) { print("error error $error"); } }); }
// Pause the video playback void pauseVideo() { _videoPlayerController?.pause(); }
// Resume the video playback void resumeVideo() { _videoPlayerController?.play(); }
@override void didChangeAppLifecycleState(AppLifecycleState state) { super.didChangeAppLifecycleState(state); print("changee"); if (state == AppLifecycleState.paused) { if (_videoPlayerController != null) { pauseVideo(); sendDuration(duration: _totalPlayedDuration!.inSeconds.toString()); setState(() { _playedSeconds = 0; _lastPlayedSeconds = 0; }); return; } } else if (state == AppLifecycleState.resumed) { resumeVideo(); return; } else if (state == AppLifecycleState.detached) { if (_videoPlayerController != null) { pauseVideo(); sendDuration(duration: _totalPlayedDuration!.inSeconds.toString()); setState(() { _playedSeconds = 0; _lastPlayedSeconds = 0; }); return; } } }
// Determine whether to call the API or use cached video URL void callApiOrNot() async { try { String lastApiCall = await Pref.getTimeOfAPICall(key: widget.vmID); String videoUrlData = await Pref.getVideoUrl(key: widget.vmID); DateTime dateTime = DateTime.parse(lastApiCall); Duration difference = DateTime.now().difference(dateTime); if (difference.inHours > 1) { getStreamUrlFromVimeo(vmID: widget.vmID); } else { setState(() { videoUrl = videoUrlData; }); setVideoData(videoUrlData: videoUrl); } } catch (e) { getStreamUrlFromVimeo(vmID: widget.vmID); } }
// Fetch the video stream URL from Vimeo API void getStreamUrlFromVimeo({required String vmID}) async { await _apiServices.httpGet( api: "${API.getUrlFromVimeo}$vmID/config", showLoader: false, success: (sucess) async { String inString = json.encode(sucess); log("inString $inString"); final getUrlFromVimeo = getUrlFromVimeoFromJson(inString); setState(() { videoUrl = getUrlFromVimeo.request.files.hls.cdns.akfireInterconnectQuic.url; }); await Pref.setVideoUrl(value: videoUrl, key: widget.vmID); await Pref.setTimeOfAPICall( key: widget.vmID, value: DateTime.now().toString()); setVideoData(videoUrlData: videoUrl); }, failure: (error) { Utils.flushBarErrorMessage( message: "Something Went Wrong while playing Video", context: context, ); }, ); }
// Set the video data and initialize controllers void setVideoData({required String videoUrlData}) { _videoPlayerController = VideoPlayerController.network(videoUrlData); _chewieController = ChewieController( videoPlayerController: _videoPlayerController!, aspectRatio: 24 / 12, // Adjust according to your video aspect ratio autoPlay: true, showControls: true, zoomAndPan: true, allowFullScreen: true, fullScreenByDefault: true, allowPlaybackSpeedChanging: false, looping: false, errorBuilder: (context, errorMessage) { return Center( child: Text( errorMessage, style: const TextStyle(color: Colors.white), ), ); }, ); _videoPlayerController!.addListener(_videoPlayerListener); }
void _videoPlayerListener() { if (_videoPlayerController!.value.isPlaying) { if (!_isVideoPlaying) { setState(() { _playStartTime = DateTime.now(); _totalPlayedDuration = Duration(seconds: _lastPlayedSeconds); _isVideoPlaying = true; }); } else { final currentTime = DateTime.now(); final playedDuration = currentTime.difference(_playStartTime!); _totalPlayedDuration = _totalPlayedDuration! + playedDuration; _playStartTime = currentTime; setState(() { _playedSeconds = _totalPlayedDuration!.inSeconds; });
// Check if the video has played for the desired duration
if (_totalPlayedDuration!.inSeconds >=
widget.totlaSecondShouldVIdeoPlay) {
// Pause the video
pauseVideo();
// Exit full screen
if (_chewieController!.isFullScreen) {
_chewieController!.exitFullScreen();
}
// Call the API to send duration
sendDuration(duration: _totalPlayedDuration!.inSeconds.toString());
showDialog(
context: context,
barrierDismissible: false,
builder: (BuildContext context) {
return SubscriptionDialog(
title: "Duration Completed",
subtitle:
"Your Duration for this video is completed Thanks for be with us",
);
},
);
// Pop from the video player screen
Navigator.of(context).pop();
}
}
} else {
if (_isVideoPlaying) {
setState(() {
_isVideoPlaying = false;
_lastPlayedSeconds = _totalPlayedDuration!.inSeconds;
});
}
}
}
@override void dispose() { WidgetsBinding.instance.removeObserver(this); _videoPlayerController!.dispose(); _chewieController!.dispose(); super.dispose(); }
@override Widget build(BuildContext context) { return WillPopScope( onWillPop: () async { if (_chewieController!.isFullScreen) { _chewieController!.exitFullScreen(); return false; } if (!_chewieController!.isFullScreen) { sendDuration(duration: _totalPlayedDuration!.inSeconds.toString()); setState(() { _playedSeconds = 0; _lastPlayedSeconds = 0; }); return true; } return true; }, child: SafeArea( child: Scaffold( body: Container( color: Colors.white, child: Center( child: (_chewieController != null && _videoPlayerController != null && videoUrl.isNotEmpty) ? Container( color: AppColors.blackColor, child: Chewie( controller: _chewieController!, ), ) : const Text("Hold the Coffe ☕ Your Video 🎥 is on the Way"), ), ), ), ), ); } }
I have the same issue. Can anyone help me please?
I had the same problem, I just set the controller's allowPlaybackSpeedChanging flag to false and it worked (but I can't say why).