[英]how to show current play time of video when using video_player plugin in flutter?
目前正在使用来自给定链接的 flutter video_player
插件流式传输视频。 问题是我不得不隐藏正常的视频交互界面,这样用户就不能跳过视频。 现在大部分工作都完成了,只需要知道如何显示播放视频的时duration
和current position
。
videoController.value.duration.inSeconds
给出了duration
部分,而videoController.value.position
给出了position. But how to keep updating the results for the
position. But how to keep updating the results for the
呢?
void checkTimer(){
if(playerController.value.position == playerController.value.duration){
setState(() {
Duration duration = Duration(milliseconds: playerController?.value?.position?.inMilliseconds?.round());
nowTime = [duration.inHours, duration.inMinutes, duration.inSeconds]
.map((seg) => seg.remainder(60).toString().padLeft(2, '0'))
.join(':');
});
}
创建上面的代码是为了根据需要更新时间。 但现在的问题是如何更新时间。 我应该使用setState()
还是其他东西,因为上面的代码对我不起作用。
视频未在加载屏幕的位置加载。 当用户单击播放按钮时,它就会加载。 所以直到那个时候,我们甚至没有duration
值,因为数据仍在路上。
如何使用 ValueListenableBuilder ?
它将侦听控制器的值并在每次值更改时更新它。
这是示例:
ValueListenableBuilder(
valueListenable: playerController,
builder: (context, VideoPlayerValue value, child) {
//Do Something with the value.
return Text(value.position.toString());
},
);
试试这个:
这是代码,
const _currentVideoPositionWidth = 38.0;
const _minTwoDigitValue = 10;
class _CurrentVideoPosition extends StatefulWidget {
const _CurrentVideoPosition({
Key? key,
required this.videoPlayerController,
}) : super(key: key);
final VideoPlayerController videoPlayerController;
@override
_CurrentVideoPositionState createState() => _CurrentVideoPositionState();
}
class _CurrentVideoPositionState extends State<_CurrentVideoPosition> {
int currentDurationInSecond = 0;
@override
void initState() {
widget.videoPlayerController.addListener(
() => setState(() => currentDurationInSecond = widget.videoPlayerController.value.position.inSeconds),
);
super.initState();
}
@override
Widget build(BuildContext context) => Container(
width: _currentVideoPositionWidth,
alignment: Alignment.centerRight,
child: Text(
_formatCurrentPosition(),
style: Theme.of(context).textTheme.bodyText1?.copyWith(
color: Colors.white,
),
maxLines: 1,
),
);
String _formatCurrentPosition() =>
currentDurationInSecond < _minTwoDigitValue ? "0 : 0$currentDurationInSecond" : "0 : $currentDurationInSecond";
}
使用视频播放器插件中的内置小部件。 [在 github 上查看更多示例][https://github.com/999eagle/plugins/blob/master/packages/video_player/example/lib/main.dart]
VideoProgressIndicator(
_videoController,//controller
allowScrubbing: true,
colors: VideoProgressColors(
playedColor: primary,
bufferedColor: Colors.red,
backgroundColor: black,
),
)
[1]: https://github.com/999eagle/plugins/blob/master/packages/video_player/example/lib/main.dart
late VideoPlayerController _phenikaaVideoPlayerController;
late Future<void> _initializeVideoPlayerFuture;
@override
void initState() {
super.initState();
_phenikaaVideoPlayerController = VideoPlayerController.network(
"https://assets-phenikaa-website.s3.ap-southeast-
1.amazonaws.com/media/assets/mo-hinh-3-nha.mp4",
);
// Initialize the controller and store the Future for later use.
_initializeVideoPlayerFuture =
_phenikaaVideoPlayerController.initialize();
}
@override
void dispose() {
_phenikaaVideoPlayerController.dispose();
super.dispose();
}
FutureBuilder(
future: _initializeVideoPlayerFuture,
builder: (_, snapshot) {
if (snapshot.connectionState == ConnectionState.done) {
return Column(
children: [
// If the VideoPlayerController has finished initialization, use
// the data it provides to limit the aspect ratio of the video.
AspectRatio(
aspectRatio:
_phenikaaVideoPlayerController.value.aspectRatio,
// Use the VideoPlayer widget to display the video.
child: VideoPlayer(_phenikaaVideoPlayerController),
),
// show the video progress & scrubbing by touch event on it
VideoProgressIndicator(
_phenikaaVideoPlayerController,
allowScrubbing: true,
padding: EdgeInsets.zero,
colors: VideoProgressColors(
backgroundColor: Color(0xFF243771),
playedColor: R.colors.redFF0000,
bufferedColor: R.colors.grayF5F6F8,
),
),
SizedBox(height: R.dimens.smallSpacing),
Row(
children: [
SizedBox(width: R.dimens.smallSpacing2),
InkWell(
onTap: () {
if (_phenikaaVideoPlayerController.value.isPlaying) {
_phenikaaVideoPlayerController.pause();
} else {
_phenikaaVideoPlayerController.play();
}
},
child: ValueListenableBuilder<VideoPlayerValue>(
valueListenable: _phenikaaVideoPlayerController,
builder: (_, _videoPlayerValue, __) {
return Icon(
_videoPlayerValue.isPlaying
? Icons.pause_circle_outline_rounded
: Icons.play_circle_outline_rounded,
);
},
),
),
SizedBox(width: R.dimens.smallSpacing2),
InkWell(
onTap: () {
_phenikaaVideoPlayerController
.seekTo(Duration(seconds: 0));
_phenikaaVideoPlayerController.pause();
},
child: Icon(Icons.stop_circle_outlined),
),
SizedBox(width: R.dimens.smallSpacing2),
// render duration video with current position / total video duration
ValueListenableBuilder<VideoPlayerValue>(
valueListenable: _phenikaaVideoPlayerController,
builder: (_, _videoPlayerValue, __) {
return Text(
"00:${_videoPlayerValue.position.inSeconds.toString().padLeft(2, '0')}",
style: R.styles.titleTextStyleW500S16,
);
},
),
Text(
" / 00:${_phenikaaVideoPlayerController.value.duration.inSeconds.toString()}",
style: R.styles.titleTextStyleW500S16,
),
Spacer(),
//render Volume button
InkWell(
onTap: () {
if (_phenikaaVideoPlayerController.value.volume ==
0.0) {
_phenikaaVideoPlayerController.setVolume(1.0);
} else
_phenikaaVideoPlayerController.setVolume(0.0);
},
child: ValueListenableBuilder<VideoPlayerValue>(
valueListenable: _phenikaaVideoPlayerController,
builder: (_, _videoPlayerValue, __) {
return Icon(
_videoPlayerValue.volume == 0.0
? Icons.volume_off_outlined
: Icons.volume_up_outlined,
);
},
),
),
SizedBox(width: R.dimens.smallSpacing2),
],
),
],
);
} else {
// If the VideoPlayerController is still initializing, show a
// loading spinner.
return Container(
alignment: Alignment.center,
padding: EdgeInsets.only(top: R.dimens.mediumSpacing1),
child: CircularProgressIndicator(
color: Color(0xFF243771),
),
);
}
},
),
使用下面的图像演示跟随我的小部件树
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.