Mell Stroy
Mell Stroy

Reputation: 11

Flutter: flick_video_player AnimationController.forward() called with no default duration

When i try to forward/backward the video by double tapping on the right/left OR by dragging the progress bar, I get this Error on the console and UI (until the video is loaded).

here's flick_player.dart:

class FlickPlayer extends StatefulWidget {
  final String url;
  final VideoFormat videoFormat;
  final bool isLive;
  final bool defaultFullscreen;

  const FlickPlayer({
    super.key,
    required this.url,
    required this.videoFormat,
    this.isLive = false,
    this.defaultFullscreen = false,
  });

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

class _FlickPlayerState extends State<FlickPlayer> {
  late FlickManager flickManager;
  late VideoPlayerController videoPlayerController;
  final ValueNotifier<bool> isFullscreen = ValueNotifier(false);

  @override
  void initState() {
    super.initState();

    // Initialize VideoPlayerController safely
    videoPlayerController = VideoPlayerController.networkUrl(
      Uri.parse(widget.url),
      videoPlayerOptions: VideoPlayerOptions(allowBackgroundPlayback: false),
    );

    // Initialize FlickManager after VideoPlayerController is created
    flickManager = FlickManager(
      autoPlay: true,
      videoPlayerController: videoPlayerController,
    );

    flickManager.flickControlManager?.addListener(() {
      if (flickManager.flickControlManager?.isFullscreen ?? false) {
        isFullscreen.value = true;
      } else {
        isFullscreen.value = false;
      }
    });

    // Enter fullscreen if required by defaultFullscreen
    if (widget.defaultFullscreen) {
      flickManager.flickControlManager?.enterFullscreen();
    }
  }

  @override
  void dispose() {
    flickManager.dispose();
    videoPlayerController.dispose();
    isFullscreen.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return ValueListenableBuilder<bool>(
      valueListenable: isFullscreen,
      builder: (context, isFullscreen, child) {
        // Detect when fullscreen exits and handle accordingly
        if (!isFullscreen && widget.defaultFullscreen) {
          Navigator.pop(context);
        }

        return Column(
          children: <Widget>[
            AspectRatio(
              aspectRatio: 16 / 9,
              child: Container(
                child: FlickVideoPlayer(
                  systemUIOverlayFullscreen: const [
                    SystemUiOverlay.top,
                    SystemUiOverlay.bottom,
                  ],
                  flickManager: flickManager,
                  preferredDeviceOrientationFullscreen: const [
                    DeviceOrientation.landscapeLeft,
                    DeviceOrientation.landscapeRight,
                  ],
                  flickVideoWithControls: FlickVideoWithControls(
                    backgroundColor: Colors.black,
                    playerLoadingFallback: const Center(
                      child: CircularProgressIndicator(
                        color: Colors.white,
                      ),
                    ),
                    controls: Builder(
                      builder: (context) => CustomOrientationControls(
                        isLive: widget.isLive,
                      ),
                    ),
                  ),
                  flickVideoWithControlsFullscreen: FlickVideoWithControls(
                    backgroundColor: Colors.black,
                    playerLoadingFallback: const Center(
                      child: CircularProgressIndicator(
                        color: Colors.white,
                      ),
                    ),
                    playerErrorFallback: const Center(
                      child: Icon(
                        Icons.error,
                        color: Colors.red,
                      ),
                    ),
                    videoFit: BoxFit.fitHeight,
                    controls: Builder(
                      builder: (context) => CustomOrientationControls(
                        isLive: widget.isLive,
                      ),
                    ),
                  ),
                ),
              ),
            ),
          ],
        );
      },
    );
  }
}

and the controls.dart:

class CustomOrientationControls extends StatelessWidget {
  final double iconSize;
  final double fontSize;
  final bool isLive;

  const CustomOrientationControls({
    super.key,
    this.iconSize = 20,
    this.fontSize = 12,
    this.isLive = false,
  });

  @override
  Widget build(BuildContext context) {
    final flickVideoManager = Provider.of<FlickVideoManager>(context);
    final videoPlayerController = flickVideoManager.videoPlayerController;

    // Ensure the video player controller is available
    if (videoPlayerController == null) {
      return const SizedBox.shrink();
    }

    return Stack(
      children: <Widget>[
        Positioned.fill(
          child: FlickAutoHideChild(
            child: Container(color: Colors.black38),
          ),
        ),
        Positioned.fill(
          child: FlickShowControlsAction(
              child: FlickSeekVideoAction(
            duration:
                const Duration(seconds: 1), // Adjusted duration for animation
            seekBackward: () {
              if (!isLive) {
                final currentPosition = videoPlayerController.value.position;
                final targetPosition =
                    currentPosition - const Duration(seconds: 10);
                videoPlayerController.seekTo(
                  targetPosition > Duration.zero
                      ? targetPosition
                      : Duration.zero,
                );
              }
            },
            seekForward: () {
              if (!isLive) {
                final currentPosition = videoPlayerController.value.position;
                final duration = videoPlayerController.value.duration;
                final targetPosition =
                    currentPosition + const Duration(seconds: 10);
                videoPlayerController.seekTo(
                  targetPosition <= duration ? targetPosition : duration,
                );
              }
            },
            child: Center(
              child: flickVideoManager.isBuffering
                  ? FlickAutoPlayCircularProgress(
                      colors: FlickAutoPlayTimerProgressColors(
                        backgroundColor: Colors.white30,
                        color: Colors.white,
                      ),
                    )
                  : const FlickAutoHideChild(
                      child: Row(
                        mainAxisAlignment: MainAxisAlignment.center,
                        children: <Widget>[
                          Padding(
                            padding: EdgeInsets.all(8.0),
                            child: FlickPlayToggle(size: 50),
                          ),
                        ],
                      ),
                    ),
            ),
          )),
        ),
        Positioned.fill(
          child: FlickAutoHideChild(
            showIfVideoNotInitialized: true,
            autoHide: true,
            child: Padding(
              padding: const EdgeInsets.all(8.0),
              child: Column(
                mainAxisAlignment: MainAxisAlignment.end,
                children: <Widget>[
                  Row(
                    children: <Widget>[
                      isLive
                          ? Text(
                              "LIVE",
                              style: context.appTextTheme.titleMedium?.copyWith(
                                color: Colors.red,
                                fontWeight: FontWeight.bold,
                              ),
                            )
                          : Row(
                              children: <Widget>[
                                FlickCurrentPosition(fontSize: fontSize),
                                Text(
                                  ' / ',
                                  style: TextStyle(
                                    color: Colors.white,
                                    fontSize: fontSize,
                                  ),
                                ),
                                ValueListenableBuilder<VideoPlayerValue>(
                                  valueListenable: videoPlayerController,
                                  builder: (context, value, child) {
                                    final duration = value.duration;
                                    return Text(
                                      PlayerFunctions.formatDuration(duration),
                                      style: TextStyle(
                                        color: Colors.white,
                                        fontSize: fontSize,
                                      ),
                                    );
                                  },
                                ),
                              ],
                            ),
                      Expanded(child: Container()),
                      FlickFullScreenToggle(size: iconSize),
                    ],
                  ),
                  if (!isLive)
                    Padding(
                      padding: EdgeInsets.only(bottom: Constants.padding),
                      child: FlickVideoProgressBar(
                        flickProgressBarSettings: FlickProgressBarSettings(
                          height: 5,
                          handleRadius: 5,
                          curveRadius: 50,
                          backgroundColor: Colors.white24,
                          bufferedColor: Colors.white38,
                          playedColor: Colors.red,
                          handleColor: Colors.red,
                        ),
                      ),
                    ),
                ],
              ),
            ),
          ),
        ),
      ],
    );
  }
}

Even though i added the duration and also tried multiple values but still the error is there.

Upvotes: 1

Views: 18

Answers (0)

Related Questions