英文:
Flutter chewie and videoplayer issue. Even after disposing the controllers , the video still keeps playing in the background, also tried pausing video
问题
这是我的Flutter应用程序代码,我遇到一个主要问题,即使关闭包含视频播放器的小部件并确保调用了dispose方法,视频仍然在后台播放,我不知道这个问题是否与chewie控制器或视频播放器有关。
甚至尝试在dispose时暂停视频,但没有效果,我甚至认为在使用此小部件多次的情况下暂停不是正确的选项,它会增加负载。
有人可以帮助我吗?
class VideoPlayerApp extends StatefulWidget {
final String jsonLink;
final String fileTitle;
final String userId;
final String creationTime;
final bool showOnlyfile;
const VideoPlayerApp(this.jsonLink, this.fileTitle, this.userId, this.creationTime, this.showOnlyfile, {super.key});
@override
State<VideoPlayerApp> createState() => _VideoPlayerAppState();
}
class _VideoPlayerAppState extends State<VideoPlayerApp>
with AutomaticKeepAliveClientMixin {
@override
bool get wantKeepAlive => true;
String videoRootUrl = "";
late VideoPlayerController videoPlayerController;
late ChewieController chewieController;
Future<String> fetchJsonContent() async {
final jsonResponse = await http.get(Uri.parse(widget.jsonLink));
if (jsonResponse.statusCode == 200) {
var jsonContent = jsonDecode(jsonResponse.body);
videoRootUrl = jsonContent["meta"]["rootUrl"];
var files = jsonContent["files"];
if (files.length > 0) {
return videoRootUrl + files[0];
}
return "";
} else {
throw Exception('Failed to load json file of drive');
}
}
@override
void dispose() {
print("|||||||||Video Dispose Called|||||||");
videoPlayerController.dispose();
chewieController.dispose();
chewieController.videoPlayerController.pause();
chewieController.pause();
videoPlayerController.pause();
super.dispose();
}
@override
Widget build(BuildContext context) {
super.build(context);
return WillPopScope(
onWillPop: () async {
switch (contentUiPreviousPath) {
case "contentList":
Navigator.of(context).pushReplacement(MaterialPageRoute(builder: (context) => courseContent(creatorName: currentCourseCreator, courseId: currentCourseId, batchId: currentBatchId, batchTitle: currentBatchTitle, discussionChannel: discussionChannel, announcementChannnel: announcementChannnel, tabBarIndex: 1)));
break;
default:
Navigator.of(context).pop();
break;
}
return false;
},
child: Scaffold(
appBar: (widget.showOnlyfile) ? null : const CustomAppBar(networkId: 'No-Network', tempNetworkImgUrl: ""),
drawer: (widget.showOnlyfile) ? null : const CustomDrawer(),
body: bindVideoFiles(),
),
);
}
bindVideoFiles() {
return FutureBuilder(
future: fetchJsonContent(),
builder: (BuildContext context, AsyncSnapshot snapshot) {
if (snapshot.hasData) {
videoPlayerController = VideoPlayerController.networkUrl(Uri.parse(snapshot.data));
chewieController = ChewieController(
videoPlayerController: videoPlayerController,
autoPlay: false,
autoInitialize: true,
looping: false,
showControls: true,
aspectRatio: 16 / 9,
materialProgressColors: ChewieProgressColors(
backgroundColor: const Color.fromARGB(255, 4, 50, 90),
bufferedColor: const Color.fromARGB(255, 4, 66, 116),
),
errorBuilder: (context, errorMessage) {
print("Video Player error --- $errorMessage");
return const Center(
child: Icon(Icons.error, color: Colors.white,),
);
},
);
return SingleChildScrollView(
child: Column(
children: [
(widget.showOnlyfile) ? const SizedBox() : Container(
padding: const EdgeInsets.symmetric(
vertical: 13,
),
width: MediaQuery.of(context).size.width * .9,
alignment: Alignment.centerLeft,
decoration: const BoxDecoration(
border: Border(
bottom: BorderSide(
width: 2,
color: Colors.black54,
))),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
widget.fileTitle,
style: const TextStyle(
fontSize: 20,
fontWeight: FontWeight.bold,
color: Colors.black45,
),
maxLines: 1,
overflow: TextOverflow.ellipsis,
),
const SizedBox(
height: 3,
),
Text(
widget.creationTime,
style: const TextStyle(
fontSize: 12,
color: Colors.black45,
),
maxLines: 1,
textAlign: TextAlign.left,
overflow: TextOverflow.ellipsis,
),
const SizedBox(
height: 3,
),
],
),
),
Container(
height: (MediaQuery.of(context).size.width * 9) / 16,
margin: const EdgeInsets.symmetric(vertical: 20),
decoration: const BoxDecoration(color: Colors.black),
child: Chewie(
controller: chewieController,
),
),
],
),
);
} else {
return const Center(
child: CircularProgressIndicator(),
);
}
},
);
}
}
我尝试过处理和暂停视频,但没有效果。
英文:
Here is the code of my flutter app, I am facing a major issue that even after closing the widget that contains video player, making sure that dispose is being called , the video still keeps playing in the background don't know this issue is related to chewie controller or video player.
Even tried pausing the video on dispose but did not work, and I don't even think pausing is the right option incase i am using this widget multiple times it will increase the load.
Can any one help me with this???
class VideoPlayerApp extends StatefulWidget {
final String jsonLink;
final String fileTitle;
final String userId;
final String creationTime;
final bool showOnlyfile;
const VideoPlayerApp(this.jsonLink, this.fileTitle, this.userId, this.creationTime, this.showOnlyfile, {super.key});
@override
State<VideoPlayerApp> createState() => _VideoPlayerAppState();
}
class _VideoPlayerAppState extends State<VideoPlayerApp>
with AutomaticKeepAliveClientMixin {
@override
bool get wantKeepAlive => true;
String videoRootUrl = "";
late VideoPlayerController videoPlayerController;
late ChewieController chewieController;
// late VideoPlayerController videoPlayerController;
Future<String> fetchJsonContent() async {
final jsonResponse = await http.get(Uri.parse(widget.jsonLink));
if (jsonResponse.statusCode == 200) {
var jsonContent = jsonDecode(jsonResponse.body);
videoRootUrl = jsonContent["meta"]["rootUrl"];
var files = jsonContent["files"];
if (files.length > 0) {
return videoRootUrl + files[0];
}
return "";
} else {
throw Exception('Failed to load json file of drive');
}
}
@override
void dispose() {
print("|||||||||Video Dispose Called|||||||");
videoPlayerController.dispose();
chewieController.dispose();
chewieController.videoPlayerController.pause();
chewieController.pause();
videoPlayerController.pause();
super.dispose();
}
@override
Widget build(BuildContext context) {
super.build(context);
return WillPopScope(
onWillPop: ()async{
switch(contentUiPreviousPath){
case "contentList":
Navigator.of(context).pushReplacement(MaterialPageRoute(builder: (context)=>courseContent(creatorName: currentCourseCreator, courseId: currentCourseId, batchId: currentBatchId, batchTitle: currentBatchTitle, discussionChannel: discussionChannel, announcementChannnel: announcementChannnel, tabBarIndex: 1)));
break;
default:
Navigator.of(context).pop();
break;
}
return false;
},
child: Scaffold(
appBar: (widget.showOnlyfile)?null:const CustomAppBar(networkId: 'No-Network',tempNetworkImgUrl: ""),
drawer: (widget.showOnlyfile)?null:const CustomDrawer(),
body: bindVideoFiles()),
);
}
bindVideoFiles() {
return FutureBuilder(
future: fetchJsonContent(),
builder: (BuildContext context, AsyncSnapshot snapshot) {
if (snapshot.hasData) {
videoPlayerController = VideoPlayerController.networkUrl(Uri.parse(snapshot.data));
chewieController = ChewieController(
videoPlayerController: videoPlayerController,
autoPlay: false,
autoInitialize: true,
looping: false,
showControls: true,
aspectRatio: 16 / 9,
materialProgressColors: ChewieProgressColors(
backgroundColor: const Color.fromARGB(255, 4, 50, 90),
bufferedColor: const Color.fromARGB(255, 4, 66, 116),
),
errorBuilder: (context, errorMessage) {
print("Video Player error --- $errorMessage");
return const Center(
child: Icon(Icons.error,color: Colors.white,),
);
},
);
return SingleChildScrollView(
child: Column(
children: [
(widget.showOnlyfile)?const SizedBox():Container(
padding: const EdgeInsets.symmetric(
vertical: 13,
),
width: MediaQuery.of(context).size.width * .9,
alignment: Alignment.centerLeft,
decoration: const BoxDecoration(
border: Border(
bottom: BorderSide(
width: 2,
color: Colors.black54,
))),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
widget.fileTitle,
style: const TextStyle(
fontSize: 20,
fontWeight: FontWeight.bold,
color: Colors.black45,
),
maxLines: 1,
overflow: TextOverflow.ellipsis,
),
const SizedBox(
height: 3,
),
Text(
widget.creationTime,
style: const TextStyle(
fontSize: 12,
color: Colors.black45,
),
maxLines: 1,
textAlign: TextAlign.left,
overflow: TextOverflow.ellipsis,
),
const SizedBox(
height: 3,
),
],
),
),
Container(
height: (MediaQuery.of(context).size.width * 9) / 16,
margin: const EdgeInsets.symmetric(vertical: 20),
decoration: const BoxDecoration(color: Colors.black),
child: Chewie(
controller: chewieController,
)),
],
),
);
} else {
return const Center(
child: CircularProgressIndicator(),
);
}
},
);
}
}
I tried disposing and pausing the video , but did not work.
答案1
得分: 1
以下是您提供的代码的翻译部分:
class VideoPlayerApp extends StatefulWidget {
final String jsonLink;
final String fileTitle;
final String userId;
final String creationTime;
final bool showOnlyfile;
const VideoPlayerApp(this.jsonLink, this.fileTitle, this.userId, this.creationTime, this.showOnlyfile, {super.key});
@override
State<VideoPlayerApp> createState() => _VideoPlayerAppState();
}
class _VideoPlayerAppState extends State<VideoPlayerApp> {
bool keepLoading = true;
String videoRootUrl = "";
late ChewieController chewieController;
Future<String> fetchJsonContent() async {
final jsonResponse = await http.get(Uri.parse(widget.jsonLink));
if (jsonResponse.statusCode == 200) {
var jsonContent = jsonDecode(jsonResponse.body);
videoRootUrl = jsonContent["meta"]["rootUrl"];
var files = jsonContent["files"];
if (files.length > 0) {
return videoRootUrl + files[0];
}
return "";
} else {
throw Exception('Failed to load json file of drive');
}
}
@override
void dispose() {
print("|||||||||Video Dispose Called|||||||");
chewieController.videoPlayerController.pause();
chewieController.dispose();
super.dispose();
}
void initState(){
super.initState();
initailSetup();
}
void initailSetup()async{
String tempUrl = await fetchJsonContent();
chewieController = ChewieController(
videoPlayerController: VideoPlayerController.networkUrl(Uri.parse(tempUrl),videoPlayerOptions: VideoPlayerOptions(allowBackgroundPlayback: false),),
autoPlay: false,
autoInitialize: true,
looping: false,
showControls: true,
aspectRatio: 16 / 9,
materialProgressColors: ChewieProgressColors(
backgroundColor: const Color.fromARGB(255, 4, 50, 90),
bufferedColor: const Color.fromARGB(255, 4, 66, 116),
),
errorBuilder: (context, errorMessage) {
print("Video Player error --- $errorMessage");
return const Center(
child: Icon(Icons.error,color: Colors.white,),
);
},
);
print("Chewie controller set ----");
setState(() {
keepLoading = false;
});
}
@override
Widget build(BuildContext context) {
return WillPopScope(
onWillPop: ()async{
switch(contentUiPreviousPath){
case "contentList":
Navigator.of(context).pushReplacement(MaterialPageRoute(builder: (context)=>courseContent(creatorName: currentCourseCreator, courseId: currentCourseId, batchId: currentBatchId, batchTitle: currentBatchTitle, discussionChannel: discussionChannel, announcementChannnel: announcementChannnel, tabBarIndex: 1)));
break;
default:
Navigator.of(context).pop();
break;
}
return false;
},
child: Scaffold(
appBar: (widget.showOnlyfile)?null:CustomAppBar(networkId: 'No-Network',tempNetworkImgUrl: ""),
drawer: (widget.showOnlyfile)?null:const CustomDrawer(),
body: (keepLoading)?const Center(child: CircularProgressIndicator(),)
:Column(
children: [
(widget.showOnlyfile)?const SizedBox():Container(
padding: const EdgeInsets.symmetric(
vertical: 13,
),
width: MediaQuery.of(context).size.width * .9,
alignment: Alignment.centerLeft,
decoration: const BoxDecoration(
border: Border(
bottom: BorderSide(
width: 2,
color: Colors.black54,
))),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
widget.fileTitle,
style: const TextStyle(
fontSize: 20,
fontWeight: FontWeight.bold,
color: Colors.black45,
),
maxLines: 1,
overflow: TextOverflow.ellipsis,
),
const SizedBox(height: 3,),
Text(
widget.creationTime,
style: const TextStyle(
fontSize: 12,
color: Colors.black45,
),
maxLines: 1,
textAlign: TextAlign.left,
overflow: TextOverflow.ellipsis,
),
const SizedBox(height: 3,),
],
),
),
Container(
height: (MediaQuery.of(context).size.width * 9) / 16,
margin: const EdgeInsets.symmetric(vertical: 20),
decoration: const BoxDecoration(color: Colors.black),
child: Chewie(
controller: chewieController,
)),
],
)),
);
}
}
请注意,代码中的注释和标识符(如变量名和函数名)没有被翻译。如果您需要进一步的翻译或有其他问题,请随时提出。
英文:
Well I changed some things and now i am able to pause the player and dispose it - following are the things i changed- removed wantkeepAlive, removed future builder, changed dispose a bit and did not create any video player controller directly.
here is my code if anyone need it in future
class VideoPlayerApp extends StatefulWidget {
final String jsonLink;
final String fileTitle;
final String userId;
final String creationTime;
final bool showOnlyfile;
const VideoPlayerApp(this.jsonLink, this.fileTitle, this.userId, this.creationTime, this.showOnlyfile, {super.key});
@override
State<VideoPlayerApp> createState() => _VideoPlayerAppState();
}
class _VideoPlayerAppState extends State<VideoPlayerApp> {
bool keepLoading = true;
String videoRootUrl = "";
late ChewieController chewieController;
Future<String> fetchJsonContent() async {
final jsonResponse = await http.get(Uri.parse(widget.jsonLink));
if (jsonResponse.statusCode == 200) {
var jsonContent = jsonDecode(jsonResponse.body);
videoRootUrl = jsonContent["meta"]["rootUrl"];
var files = jsonContent["files"];
if (files.length > 0) {
return videoRootUrl + files[0];
}
return "";
} else {
throw Exception('Failed to load json file of drive');
}
}
@override
void dispose() {
print("|||||||||Video Dispose Called|||||||");
chewieController.videoPlayerController.pause();
chewieController.dispose();
super.dispose();
}
void initState(){
super.initState();
initailSetup();
}
void initailSetup()async{
String tempUrl = await fetchJsonContent();
chewieController = ChewieController(
videoPlayerController: VideoPlayerController.networkUrl(Uri.parse(tempUrl),videoPlayerOptions: VideoPlayerOptions(allowBackgroundPlayback: false),),
autoPlay: false,
autoInitialize: true,
looping: false,
showControls: true,
aspectRatio: 16 / 9,
materialProgressColors: ChewieProgressColors(
backgroundColor: const Color.fromARGB(255, 4, 50, 90),
bufferedColor: const Color.fromARGB(255, 4, 66, 116),
),
errorBuilder: (context, errorMessage) {
print("Video Player error --- $errorMessage");
return const Center(
child: Icon(Icons.error,color: Colors.white,),
);
},
);
print("Chewie controller set ----");
setState(() {
keepLoading = false;
});
}
@override
Widget build(BuildContext context) {
return WillPopScope(
onWillPop: ()async{
switch(contentUiPreviousPath){
case "contentList":
Navigator.of(context).pushReplacement(MaterialPageRoute(builder: (context)=>courseContent(creatorName: currentCourseCreator, courseId: currentCourseId, batchId: currentBatchId, batchTitle: currentBatchTitle, discussionChannel: discussionChannel, announcementChannnel: announcementChannnel, tabBarIndex: 1)));
break;
default:
Navigator.of(context).pop();
break;
}
return false;
},
child: Scaffold(
appBar: (widget.showOnlyfile)?null:CustomAppBar(networkId: 'No-Network',tempNetworkImgUrl: ""),
drawer: (widget.showOnlyfile)?null:const CustomDrawer(),
body: (keepLoading)?const Center(child: CircularProgressIndicator(),)
:Column(
children: [
(widget.showOnlyfile)?const SizedBox():Container(
padding: const EdgeInsets.symmetric(
vertical: 13,
),
width: MediaQuery.of(context).size.width * .9,
alignment: Alignment.centerLeft,
decoration: const BoxDecoration(
border: Border(
bottom: BorderSide(
width: 2,
color: Colors.black54,
))),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
widget.fileTitle,
style: const TextStyle(
fontSize: 20,
fontWeight: FontWeight.bold,
color: Colors.black45,
),
maxLines: 1,
overflow: TextOverflow.ellipsis,
),
const SizedBox(height: 3,),
Text(
widget.creationTime,
style: const TextStyle(
fontSize: 12,
color: Colors.black45,
),
maxLines: 1,
textAlign: TextAlign.left,
overflow: TextOverflow.ellipsis,
),
const SizedBox(height: 3,),
],
),
),
Container(
height: (MediaQuery.of(context).size.width * 9) / 16,
margin: const EdgeInsets.symmetric(vertical: 20),
decoration: const BoxDecoration(color: Colors.black),
child: Chewie(
controller: chewieController,
)),
],
)),
);
}
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论