繁体   English   中英

在 flutter 中使用 video_player 插件时如何显示视频的当前播放时间?

[英]how to show current play time of video when using video_player plugin in flutter?

目前正在使用来自给定链接的 flutter video_player插件流式传输视频。 问题是我不得不隐藏正常的视频交互界面,这样用户就不能跳过视频。 现在大部分工作都完成了,只需要知道如何显示播放视频的时durationcurrent 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());
  },
);

试试这个:

  1. 创建一个新的 Stateful Widget 来显示当前位置的计数器,
  2. 将 videoPlayerController 作为参数传递到小部件中,
  3. 在initState中监听videoPlayerController,监听值加上setSate

这是代码,

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM