Flutter video_player 从点击开始重新启动视频
Flutter video_player restart video from start on tap
我用的是flutter video_player package to play a short video file using in my application. I inspired from the flutter cookbook: Play and pause a video.
我想让用户点击视频从头开始播放。所以我用 GestureDetector.
包装了 VideoPlayer
我目前有以下代码:
class MyVideoPlayer extends StatefulWidget {
final File videoFile;
MyVideoPlayer({Key key, this.videoFile}) : super(key: key);
@override
_MyVideoPlayerState createState() => _MyVideoPlayerState();
}
class _MyVideoPlayerState extends State<MyVideoPlayer> {
VideoPlayerController _controller;
Future<void> _initializeVideoPlayerFuture;
@override
void initState() {
_controller = VideoPlayerController.file(widget.videoFile);
_initializeVideoPlayerFuture = _controller.initialize();
super.initState();
}
@override
void dispose() {
_controller.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return FutureBuilder(
future: _initializeVideoPlayerFuture,
builder: (context, snapshot) {
print(snapshot.connectionState);
if (snapshot.connectionState == ConnectionState.done) {
// Play video once it's loaded
_controller.play();
return AspectRatio(
aspectRatio: _controller.value.aspectRatio,
child: GestureDetector(
onTap: () async {
await _controller.seekTo(Duration.zero);
_controller.play();
},
child: VideoPlayer(_controller),
),
);
} else {
return CircularProgressIndicator();
}
},
);
}
}
视频文件加载后(连接状态变为完成后)视频播放良好,但是,当我尝试点击视频再次播放时,它不会从开始。音频再次开始播放,但视频没有重新播放。有什么想法吗?
编辑 1
在 之后,我尝试将调用包装在 setState 中以再次触发构建方法:
return AspectRatio(
aspectRatio: _controller.value.aspectRatio,
child: GestureDetector(
onTap: () async {
await _controller.seekTo(Duration.zero);
setState(() {
_controller.play();
});
},
child: VideoPlayer(_controller),
),
);
但是视频还是没有重播,只有声音。还有其他想法吗?
如果您对视频播放进行了任何更改,则需要重建 VideoPlayer
。针对您的情况,最简单的解决方案是通过 setState
调用再次触发构建方法。
/// ... after some code
child: GestureDetector(
onTap: () async {
await _controller.seekTo(Duration.zero);
setState( () {
_controller.play();
} );
},
child: VideoPlayer(_controller),
),
如果视频不再播放(即视频已经播放完毕),我终于找到了解决问题的方法,方法是在点击事件的控制器上再次调用 initialize()
。
return AspectRatio(
aspectRatio: _controller.value.aspectRatio,
child: GestureDetector(
onTap: () {
if (!_controller.value.isPlaying) {
setState(() {});
_controller.initialize();
}
},
child: VideoPlayer(_controller),
),
);
我是这样解决这个问题的
GestureDetector(
onTap() {
if(_controller.value.position==_controller.value.duration){
_controller.initialize();
}
}
)
_controller.value.duration 存储视频时长,
_controller.value.position 存储视频的实际位置,如果视频到达结尾,_controller.value.position 将等于_controller.value.duration.
你可以在 onTap 上做这样的事情
/// get the duration of the video
final duration = await _controller.position;
/// check if video has ended
if (duration.inSeconds ==_controller.value.duration.inSeconds) {
/// restart the video by setting current position to 0
_controller.seekTo(Duration.zero);
} else {
_controller.value.isPlaying
? _controller.pause()
: _controller.play();
}
我用的是flutter video_player package to play a short video file using in my application. I inspired from the flutter cookbook: Play and pause a video.
我想让用户点击视频从头开始播放。所以我用 GestureDetector.
包装了 VideoPlayer我目前有以下代码:
class MyVideoPlayer extends StatefulWidget {
final File videoFile;
MyVideoPlayer({Key key, this.videoFile}) : super(key: key);
@override
_MyVideoPlayerState createState() => _MyVideoPlayerState();
}
class _MyVideoPlayerState extends State<MyVideoPlayer> {
VideoPlayerController _controller;
Future<void> _initializeVideoPlayerFuture;
@override
void initState() {
_controller = VideoPlayerController.file(widget.videoFile);
_initializeVideoPlayerFuture = _controller.initialize();
super.initState();
}
@override
void dispose() {
_controller.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return FutureBuilder(
future: _initializeVideoPlayerFuture,
builder: (context, snapshot) {
print(snapshot.connectionState);
if (snapshot.connectionState == ConnectionState.done) {
// Play video once it's loaded
_controller.play();
return AspectRatio(
aspectRatio: _controller.value.aspectRatio,
child: GestureDetector(
onTap: () async {
await _controller.seekTo(Duration.zero);
_controller.play();
},
child: VideoPlayer(_controller),
),
);
} else {
return CircularProgressIndicator();
}
},
);
}
}
视频文件加载后(连接状态变为完成后)视频播放良好,但是,当我尝试点击视频再次播放时,它不会从开始。音频再次开始播放,但视频没有重新播放。有什么想法吗?
编辑 1
在
return AspectRatio(
aspectRatio: _controller.value.aspectRatio,
child: GestureDetector(
onTap: () async {
await _controller.seekTo(Duration.zero);
setState(() {
_controller.play();
});
},
child: VideoPlayer(_controller),
),
);
但是视频还是没有重播,只有声音。还有其他想法吗?
如果您对视频播放进行了任何更改,则需要重建 VideoPlayer
。针对您的情况,最简单的解决方案是通过 setState
调用再次触发构建方法。
/// ... after some code
child: GestureDetector(
onTap: () async {
await _controller.seekTo(Duration.zero);
setState( () {
_controller.play();
} );
},
child: VideoPlayer(_controller),
),
如果视频不再播放(即视频已经播放完毕),我终于找到了解决问题的方法,方法是在点击事件的控制器上再次调用 initialize()
。
return AspectRatio(
aspectRatio: _controller.value.aspectRatio,
child: GestureDetector(
onTap: () {
if (!_controller.value.isPlaying) {
setState(() {});
_controller.initialize();
}
},
child: VideoPlayer(_controller),
),
);
我是这样解决这个问题的
GestureDetector(
onTap() {
if(_controller.value.position==_controller.value.duration){
_controller.initialize();
}
}
)
_controller.value.duration 存储视频时长, _controller.value.position 存储视频的实际位置,如果视频到达结尾,_controller.value.position 将等于_controller.value.duration.
你可以在 onTap 上做这样的事情
/// get the duration of the video
final duration = await _controller.position;
/// check if video has ended
if (duration.inSeconds ==_controller.value.duration.inSeconds) {
/// restart the video by setting current position to 0
_controller.seekTo(Duration.zero);
} else {
_controller.value.isPlaying
? _controller.pause()
: _controller.play();
}