Giter Club home page Giter Club logo

smooth_video_progress's People

Contributors

timcreatedit avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar

smooth_video_progress's Issues

Video player window disappears when dragging progress bar

Hey, awesome package! The video im using is 6 min so the un-smoothness of the slider track movement is unnoticable; I was just using this package cause its progress bar looks better than the default VideoProgressIndicator(). For some reason the video disappeared on my website when showing my friend (who was using chrome on a mac) when dragging the progress bar. I use chrome on linux, idk why it happened for him, but he sent me a short video (see below). I resolved this for myself by just using the slider in this part of your example, but i thought I'd still let you know.

Video:
https://github.com/timcreatedit/smooth_video_progress/assets/13493467/fb5ab9fb-7b8c-47af-b7b2-86b422b7f464
sidenote: facebook wouldn't let me download it cause "URL signature expired", so it a recording of a recording.

My website's code doesn't show the video player unless _controller.value.isInitialized is true, so I hypothesize moving the progress bar causes this to be false.

Relevant Code:

import 'package:flutter/material.dart';
import 'package:video_player/video_player.dart';
import 'package:smooth_video_progress/smooth_video_progress.dart';

class VideoPlayerWidget extends StatefulWidget {
  final String filepath;
  final double width;

  VideoPlayerWidget(this.filepath, {required this.width});

  @override
  _VideoPlayerWidgetState createState() => _VideoPlayerWidgetState();
}

class _VideoPlayerWidgetState extends State<VideoPlayerWidget> {
  late VideoPlayerController _controller;
  late Duration _currentPosition;
  bool showVideoControls = false;
  bool showInitialPlayButton = true;

  @override
  void initState() {
    super.initState();
    _controller = VideoPlayerController.network(widget.filepath,
        videoPlayerOptions: VideoPlayerOptions(
          mixWithOthers: true,
        ))
      ..addListener(() {
        setState(() {
          _currentPosition = _controller.value.position;
        });
      })
      ..initialize().then((_) {
        // Ensure the first frame is shown after the video is initialized, even before the play button has been pressed.
        setState(() {});
      });
  }

  @override
  void dispose() {
    super.dispose();
    _controller.dispose();
  }

  String formatTime(Duration duration) {
    return duration.inHours == 0
        ? "${duration.inMinutes}:${duration.inSeconds.remainder(60).toString().padLeft(2, '0')}"
        : "${duration.inHours}:${duration.inMinutes.remainder(60).toString().padLeft(2, '0')}:${duration.inSeconds.remainder(60).toString().padLeft(2, '0')}";
    // if (duration.inHours == 0) {
    //   return "${duration.inMinutes}:${duration.inSeconds.toString().padLeft(2, '0')}";
    // } else {
    //   return "${duration.inHours}:${duration.inMinutes.toString().padLeft(2, '0')}:${duration.inSeconds.toString().padLeft(2, '0')}";
    // }

    // // Format the duration into hh:mm:ss format
    // String twoDigits(int n) => n.toString().padLeft(2, '0');
    // String twoDigitMinutes = twoDigits(duration.inMinutes.remainder(60));
    // String twoDigitSeconds = twoDigits(duration.inSeconds.remainder(60));
    // return "${twoDigits(duration.inHours)}:$twoDigitMinutes:$twoDigitSeconds";
  }

  @override
  Widget build(BuildContext context) {
    return Container(
        width: widget.width,
        child: MouseRegion(
            onEnter: (e) => setState(() {
                  if (!showInitialPlayButton) {
                    showVideoControls = true;
                  }
                }),
            onExit: (e) => setState(() {
                  showVideoControls = false;
                }),
            child: Stack(children: [
              _controller.value.isInitialized
                  ? AspectRatio(
                      aspectRatio: _controller.value.aspectRatio,
                      child: VideoPlayer(_controller),
                    )
                  : Container(),
              if (showInitialPlayButton)
                Positioned.fill(
                    child: Center(
                  child: IconButton(
                    onPressed: () {
                      setState(() {
                        showInitialPlayButton = false;
                        showVideoControls = true;
                        _controller.play();
                      });
                    },
                    splashRadius: 0.01,
                    iconSize: widget.width * 0.20,
                    color: Theme.of(context).canvasColor.withOpacity(0.50),
                    icon: Icon(Icons.play_circle),
                  ),
                )),
              if (showVideoControls)
                Positioned.fill(
                    child: Align(
                        alignment: Alignment.bottomCenter,
                        child: SizedBox(
                            height: 40,
                            child: Row(children: [
                              IconButton(
                                onPressed: () {
                                  setState(() {
                                    _controller.value.isPlaying
                                        ? _controller.pause()
                                        : _controller.play();
                                  });
                                },
                                splashRadius: 0.01,
                                icon: Icon(
                                  _controller.value.isPlaying
                                      ? Icons.pause
                                      : Icons.play_arrow,
                                ),
                              ),
                              Text(
                                  "${formatTime(_currentPosition)} / ${formatTime(_controller.value.duration)}",
                                  style: TextStyle(
                                      color: Theme.of(context).canvasColor)),
                              Expanded(
                                child: SmoothVideoProgress(
                                  controller: _controller,
                                  builder: (context, position, duration, _) =>
                                      Slider(
                                    min: 0,
                                    max: duration.inMilliseconds.toDouble(),
                                    value: position.inMilliseconds.toDouble(),
                                    onChanged: (value) => _controller.seekTo(
                                        Duration(milliseconds: value.toInt())),
                                    onChangeStart: (_) => _controller.pause(),
                                    onChangeEnd: (_) => _controller.play(),
                                  ),
                                ),
                                // child: ValueListenableBuilder<VideoPlayerValue>(
                                //   valueListenable: _controller,
                                //   builder: (context, value, _) => Slider(
                                //     min: 0,
                                //     max: value.duration.inMilliseconds
                                //         .toDouble(),
                                //     value: value.position.inMilliseconds
                                //         .toDouble(),
                                //     onChanged: (value) => _controller.seekTo(
                                //         Duration(milliseconds: value.toInt())),
                                //     onChangeStart: (_) => _controller.pause(),
                                //     onChangeEnd: (_) => _controller.play(),
                                //   ),
                                // ),
                              ),
                            ])))),
            ])));
  }
}

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.