簡體   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