Open ItsVeridian opened 1 week ago
Fixed.
Please try the new version 3.1.1
I tried the new version, but for some reason, I can only get looping if I implement it manually like this:
_controller.setLooping(false);
_controller.addListener(() {
if(_controller.value.isCompleted) {
_controller.play();
}
});
Full code of my widget:
import 'dart:io';
import 'package:flutter/material.dart';
import 'package:video_player_win/video_player_win.dart';
import 'package:visibility_detector/visibility_detector.dart';
class VideoView extends StatefulWidget {
const VideoView(this.file, {super.key, this.controller, this.fit = BoxFit.cover})
: assert(controller != null || file != null, 'Controller and File cannot both be null!');
final File? file;
final BoxFit fit;
final WinVideoPlayerController? controller;
@override
State<VideoView> createState() => _VideoViewState();
}
class _VideoViewState extends State<VideoView> {
late final WinVideoPlayerController _controller;
@override
void initState() {
super.initState();
if (widget.controller == null) {
_controller = WinVideoPlayerController.file(widget.file!);
} else {
_controller = widget.controller!;
}
if (_controller.value.isInitialized) return;
initializeController(_controller).then(
(value) {
_controller.play();
_controller.setVolume(0);
_controller.setLooping(false);
_controller.addListener(() {
if(_controller.value.isCompleted) {
_controller.play();
}
});
setState(() {});
},
);
}
Future<void> initializeController(WinVideoPlayerController controller) async {
while(!controller.value.isInitialized && !_controller.value.isInitialized) {
await controller.initialize();
}
}
@override
Widget build(BuildContext context) {
return VisibilityDetector(
key: ValueKey(widget.file?.path),
onVisibilityChanged: (info) {
if (!_controller.value.isInitialized) return;
if (info.visibleFraction == 0) {
_controller.pause();
} else {
_controller.play();
}
},
child: FittedBox(
fit: widget.fit,
clipBehavior: Clip.hardEdge,
child: SizedBox(
width: _controller.value.size.width,
height: _controller.value.size.height,
child: Texture(
textureId: _controller.textureId_,
filterQuality: FilterQuality.low,
),
),
),
);
}
@override
void dispose() {
super.dispose();
}
}
In your sample code, you called _controller.setLooping(false);
Is there any problem for passing true
into _controller.setLooping(true);
?
I think the following code snippet is working, could you give it a try ? Just copy and paste it, without any modification.
_controller = WinVideoPlayerController.file(File(widget.file!));
_controller!.initialize().then((value) {
if (_controller!.value.isInitialized) {
_controller!.play();
_controller!.setLooping(true);
}
}
I'm making a gallery app, so I create a controller to be passed to both the gallery and single image view, so video playback continues across the navigation:
if (_images[i].isVideo) {
_images[i].videoController = WinVideoPlayerController.file(_images[i].file);
}
If I modify the video widget code similar to yours:
_controller.initialize().then(
(value) {
_controller.play();
_controller.setVolume(0);
_controller.setLooping(true);
setState(() {});
},
);
It seems to work, but sometimes videos don't play, or play too fast, before returning to normal. It could have something to do with the VisibilityDetector, or the FlutterListView packages, but I'm not sure.
I think for now I'm going to stick to my original code.
I noticed that you are making a gallery app, it may have multiple video files opened at the same time. So, I try to improve the solution, and push to github.
Please try it with the following dependency, and let me know if it works for you:
dependencies:
video_player_win:
git:
url: https://github.com/jakky1/video_player_win.git
ref: master
Hi! It seems to be looping normally, but I'm struggling a bit to optimize the videos in the gallery. I'm not sure if it's because of the FlutterListView, but I'm having issues with the videos not being garbage collected properly. Can you double check if this package's dispose is working correctly?
I have tested: create -> dispose -> create , loops 300 times, and from the Windows source monitor, the memory usage of the application has not increased significantly.
(But I can only test the situation where there is only one video at the same time.)
Please check whether the following text appears in the log window every time you think the video is disposed:
[video_player_win][native] ~MyPlayer() destroyed
If it appears every time when dispose()
called, it means it was garbage collected normally.
Please make sure that when you generate a controller in initState() in a StatefulWidget, you also call controller.dispose in the dispose() function in the widget.
For example:
class MyVideoWidget extends StatefulWidget {
const MyVideoWidget({
Key? key,
required String path
}) : super(key: key);
@override
State<MyVideoWidget> createState() => _MyVideoWidgetState();
}
class _MyVideoWidgetState extends State<MyVideoWidget> {
WinVideoPlayerController? controller;
@override
void initState() {
super.initState();
controller = VideoPlayerController.file(File(widget.path));
}
@override
void dispose() {
super.dispose();
controller?.dispose();
}
}
I swear it worked before, but now it just stops at the end