Flutter chewie and videoplayer issue. Even after disposing the controllers , the video still keeps playing in the background, also tried pausing video

huangapple go评论74阅读模式
英文:

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&lt;VideoPlayerApp&gt; createState() =&gt; _VideoPlayerAppState();
}
class _VideoPlayerAppState extends State&lt;VideoPlayerApp&gt;
with AutomaticKeepAliveClientMixin {
@override
bool get wantKeepAlive =&gt; true;
String videoRootUrl = &quot;&quot;;
late VideoPlayerController videoPlayerController;
late  ChewieController chewieController;
// late VideoPlayerController videoPlayerController;
Future&lt;String&gt; fetchJsonContent() async {
final jsonResponse = await http.get(Uri.parse(widget.jsonLink));
if (jsonResponse.statusCode == 200) {
var jsonContent = jsonDecode(jsonResponse.body);
videoRootUrl = jsonContent[&quot;meta&quot;][&quot;rootUrl&quot;];
var files = jsonContent[&quot;files&quot;];
if (files.length &gt; 0) {
return videoRootUrl + files[0];
}
return &quot;&quot;;
} else {
throw Exception(&#39;Failed to load json file of drive&#39;);
}
}
@override
void dispose() {
print(&quot;|||||||||Video Dispose Called|||||||&quot;);
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 &quot;contentList&quot;:
Navigator.of(context).pushReplacement(MaterialPageRoute(builder: (context)=&gt;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: &#39;No-Network&#39;,tempNetworkImgUrl: &quot;&quot;),
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(&quot;Video Player error --- $errorMessage&quot;);
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&lt;VideoPlayerApp&gt; createState() =&gt; _VideoPlayerAppState();
}
class _VideoPlayerAppState extends State&lt;VideoPlayerApp&gt; {
bool keepLoading = true;
String videoRootUrl = &quot;&quot;;
late  ChewieController chewieController;
Future&lt;String&gt; fetchJsonContent() async {
final jsonResponse = await http.get(Uri.parse(widget.jsonLink));
if (jsonResponse.statusCode == 200) {
var jsonContent = jsonDecode(jsonResponse.body);
videoRootUrl = jsonContent[&quot;meta&quot;][&quot;rootUrl&quot;];
var files = jsonContent[&quot;files&quot;];
if (files.length &gt; 0) {
return videoRootUrl + files[0];
}
return &quot;&quot;;
} else {
throw Exception(&#39;Failed to load json file of drive&#39;);
}
}
@override
void dispose() {
print(&quot;|||||||||Video Dispose Called|||||||&quot;);
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(&quot;Video Player error --- $errorMessage&quot;);
return const Center(
child: Icon(Icons.error,color: Colors.white,),
);
},
);
print(&quot;Chewie controller set ----&quot;);
setState(() {
keepLoading = false;
});
}
@override
Widget build(BuildContext context) {
return WillPopScope(
onWillPop: ()async{
switch(contentUiPreviousPath){
case &quot;contentList&quot;:
Navigator.of(context).pushReplacement(MaterialPageRoute(builder: (context)=&gt;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: &#39;No-Network&#39;,tempNetworkImgUrl: &quot;&quot;),
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,
)),
],
)),
);
}
}

huangapple
  • 本文由 发表于 2023年7月31日 18:36:20
  • 转载请务必保留本文链接:https://go.coder-hub.com/76802790.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定