video_widget.dart 5.57 KB
import 'package:common_utils/common_utils.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:video_player/video_player.dart';
import 'package:wow_english/common/extension/string_extension.dart';

import 'video_opera_widget.dart';

class VideoWidget extends StatefulWidget {
  const VideoWidget({super.key, this.videoUrl = '',this.typeTitle});

  final String videoUrl;
  final String? typeTitle;

  @override
  State<StatefulWidget> createState() {
    return _VideoWidgetState();
  }
}

class _VideoWidgetState extends State<VideoWidget> {
  VideoPlayerController? _controller;
  String _currentTime = '00:00';
  String _totalTime = '00:00';
  double _playDegree = 0.0;
  bool _hiddenTipView = false;
  TimerUtil? timerUtil;

  String formatDuration(Duration duration) {
    String hours = duration.inHours.toString().padLeft(2, '0');
    String minutes = duration.inMinutes.remainder(60).toString().padLeft(2, '0');
    String seconds = duration.inSeconds.remainder(60).toString().padLeft(2, '0');
    return "$hours:$minutes:$seconds";
  }

  void _addListener() {
    _controller!.addListener(() {
      if(_controller!.value.isInitialized) {
        if (_controller!.value.isPlaying) {
          setState(() {
            double currentSecond = (_controller!.value.position.inMinutes.remainder(60)*60+_controller!.value.position.inSeconds.remainder(60)).toDouble();
            int totalSecond = _controller!.value.duration.inMinutes.remainder(60)*60+_controller!.value.duration.inSeconds.remainder(60);
            _currentTime = formatDuration(_controller!.value.position);
            _playDegree = currentSecond/totalSecond;
          });
        }
      }
    });
  }

  //开始倒计时
  void startTimer()  {
    if(timerUtil == null) {
      timerUtil =  TimerUtil(mInterval: 1000,mTotalTime: 1000*10);
      timerUtil!.setOnTimerTickCallback((int tick) {
        double currentTick = tick / 1000;
        if (currentTick.toInt() == 0) {//倒计时结束
          setState(() {
            _hiddenTipView = true;
          });
          timerUtil!.cancel();
          timerUtil = null;
        }
      });
      timerUtil!.startCountDown();
    }
  }

  //取消倒计时
  void cancelTimer() {
    timerUtil!.cancel();
    timerUtil = null;
  }

  void actionType(OperationType type) async {
    if (type == OperationType.back) {
      Navigator.pop(context);
    } else if (type == OperationType.playState) {
      if (_controller!.value.isPlaying) {
        _controller!.pause();
      } else {
        _controller!.play();
      }
      setState(() {

      });
    }
  }

  @override
  void initState() {
    super.initState();
    _controller = VideoPlayerController.network(widget.videoUrl)
      ..initialize().then((_){
        startTimer();
        setState(() {
          _currentTime = formatDuration(_controller!.value.position);
          _totalTime = formatDuration(_controller!.value.duration);
          _controller!.setLooping(true);
          _controller!.setVolume(100);
          _controller!.play();
        });
        _addListener();
      });
  }

  @override
  Widget build(BuildContext context) {
    return GestureDetector(
      onTap: () {
        setState(() {
          _hiddenTipView = !_hiddenTipView;
          if(!_hiddenTipView) {
            startTimer();
          } else {
            if (timerUtil!.isActive()) {
              cancelTimer();
            }
          }
        });
      },
      onDoubleTap: () {
        if(_controller!.value.isInitialized) {
          if (_controller!.value.isPlaying) {
            _controller!.pause();
          } else {
            _controller!.play();
          }
          setState(() {

          });
        }
      },
      child: Center(
        child: _controller!.value.isInitialized ? Stack(
          alignment: Alignment.center,
          children: [
            SizedBox(
              height: double.infinity,
              width: double.infinity,
              child: AspectRatio(
                aspectRatio: _controller!.value.aspectRatio,
                child: VideoPlayer(_controller!),
              ),
            ),
            Offstage(
              offstage: _hiddenTipView,
              child: VideoOperaWidget(
                title: widget.typeTitle??'song',
                degree: _playDegree,
                totalTime: _totalTime,
                currentTime: _currentTime,
                isPlay: _controller!.value.isPlaying,
                actionEvent: (OperationType type) {
                  actionType(type);
                },
                sliderChangeEvent: (double degree) {
                  int totalSecond = _controller!.value.duration.inMinutes.remainder(60)*60+_controller!.value.duration.inSeconds.remainder(60);
                  int positionSecond = (totalSecond * degree).toInt();
                  _controller!.seekTo(Duration(seconds: positionSecond));
                },
              ),
            ),
            Offstage(
              offstage: _controller!.value.isPlaying,
              child: IconButton(
                onPressed: () {
                  _controller!.play();
                },
                icon: Image.asset(
                  'video_stop'.assetPng,
                  width: 70,
                  height: 70,
                ),
              ),
            )
          ],
        ): Container(
          color: Colors.white,
        ),
      ),
    );
  }

  @override
  void dispose() {
    _controller?.dispose();
    _controller?.removeListener(() {});
    if (timerUtil != null) {
      timerUtil!.cancel();
      timerUtil = null;
    }
    super.dispose();
  }
}