Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Chewie Video Player Stuck On Loading Forever #816

Open
TahaHamad opened this issue Mar 2, 2024 · 0 comments
Open

Chewie Video Player Stuck On Loading Forever #816

TahaHamad opened this issue Mar 2, 2024 · 0 comments

Comments

@TahaHamad
Copy link

Hey Chewie Community!

I am trying to implement the Chewie Flutter package into my app as a custom widget and I got everything down and made it as customizable as possible. It complies well, but when I run it on the web, android, or any device possible all I get is this loading screen:

chewie-video-player-stuck-on-loading-forever-v0-blk59l15mvlc1

Here's my custom widget code, it's really simple. All I did was get Pubdev Chewie package code, add dependencies, add as many params as possible that will define the autoplay, looping, etc as per Chewie's documentation, and remove the unnecessary appbar and bottom texts in the pubdev code.

I also have videoPath and videosList just in case if the user would like to use a playlist or just one video path. The pubdev code uses a list, so I used a list and would check if the param is null, if so it'll use the videoPath singular link as the first index instead. I commented that code out and hardcoded a video link that I found on Chewie's Pubdev page and several other ones with no hope.

The code:

import '/flutter_flow/flutter_flow_theme.dart';
import '/flutter_flow/flutter_flow_util.dart';
import '/custom_code/widgets/index.dart'; // Imports other custom widgets
import '/custom_code/actions/index.dart'; // Imports custom actions
import '/flutter_flow/custom_functions.dart'; // Imports custom functions
import 'package:flutter/material.dart';
// Begin custom widget code

import 'package:chewie/chewie.dart';
import 'package:video_player/video_player.dart';
import 'dart:io';

class ChewieVideoPlayer extends StatefulWidget {
  ChewieVideoPlayer({
    Key? key,
    this.width,
    this.height,
    this.videoPath,
    this.videosList,
    this.isAutoPlay,
    this.isLooping,
    this.hideControlsAfter,
    this.currentPlayIndex,
    this.startTime,
    this.videoPlatform,
    this.hideControls,
    this.aspectRatio,
    this.disableFullScreen,
    this.isLive,
    this.disableZoomAndPan,
    this.hideOptions,
    this.allowScreenSleep,
    this.disableMuting,
    this.disablePlaybackSpeedChanging,
    this.disableAutoInitialize,
    this.fullScreenByDefault,
    this.playbackSpeedList,
    this.progressIndicatorDelay,
    this.nonDraggableProgressBar,
  }) : super(key: key);

  final double? width;
  final double? height;
  final String? videoPath;
  final List<String>? videosList;
  final bool? isAutoPlay;
  final bool? isLooping;
  final int? hideControlsAfter;
  int? currentPlayIndex;
  final double? startTime;
  final String? videoPlatform;
  final bool? hideControls;
  final double? aspectRatio;
  final bool? disableFullScreen;
  final bool? isLive;
  final bool? disableZoomAndPan;
  final bool? hideOptions;
  final bool? allowScreenSleep;
  final bool? disableMuting;
  final bool? disablePlaybackSpeedChanging;
  final bool? disableAutoInitialize;
  final bool? fullScreenByDefault;
  final List<double>? playbackSpeedList;
  final int? progressIndicatorDelay;
  final bool? nonDraggableProgressBar;
  @override
  State<ChewieVideoPlayer> createState() => _ChewieVideoPlayerState();
}

class _ChewieVideoPlayerState extends State<ChewieVideoPlayer> {
  TargetPlatform? _platform;
  late VideoPlayerController _videoPlayerController1;
  late VideoPlayerController _videoPlayerController2;
  ChewieController? _chewieController;
  late List<String> srcs;

  //Initializing the widget state
  @override
  void initState() {
    super.initState();
    initializePlayer();
    /* srcs = widget.videosList ??
        [
          widget.videoPath ??
          'https://assets.mixkit.co/videos/preview/mixkit-daytime-city-traffic-aerial-view-56-large.mp4']; */
     srcs = [
      'https://assets.mixkit.co/videos/preview/mixkit-daytime-city-traffic-aerial-view-56-large.mp4'
    ];
  }

  //Function to clear the memory to avoid leaks
  @override
  void dispose() {
    _videoPlayerController1.dispose();
    _videoPlayerController2.dispose();
    _chewieController?.dispose();
    super.dispose();
  }

  //Function to initialize the player
  Future<void> initializePlayer() async {
    _videoPlayerController1 = VideoPlayerController.networkUrl(
        Uri.parse(srcs[widget.currentPlayIndex ?? 0]));
    _videoPlayerController2 = VideoPlayerController.networkUrl(
        Uri.parse(srcs[widget.currentPlayIndex ?? 0]));
    await Future.wait([
      _videoPlayerController1.initialize(),
      _videoPlayerController2.initialize()
    ]);

    _createChewieController();
    setState(() {});
  }

//Function that creates ChewieController and custmoize it (e.g. set color, autoplay, looping,etc)
  void _createChewieController() {
    // Check if videoPlatform is provided and set the platform accordingly
    if (widget.videoPlatform != null) {
      switch (widget.videoPlatform) {
        case 'android':
          _platform = TargetPlatform.android;
          break;
        case 'ios':
          _platform = TargetPlatform.iOS;
          break;
        case 'windows':
          _platform = TargetPlatform.windows;
          break;
        default:
          // Handle other cases or leave platform as null
          break;
      }
    }
    final subtitles = [
      Subtitle(
        index: 0,
        start: Duration.zero,
        end: const Duration(seconds: 10),
        text: const TextSpan(
          children: [
            TextSpan(
              text: 'Hello',
              style: TextStyle(color: Colors.red, fontSize: 22),
            ),
            TextSpan(
              text: ' from ',
              style: TextStyle(color: Colors.green, fontSize: 20),
            ),
            TextSpan(
              text: 'subtitles',
              style: TextStyle(color: Colors.blue, fontSize: 18),
            )
          ],
        ),
      ),
      Subtitle(
        index: 0,
        start: const Duration(seconds: 10),
        end: const Duration(seconds: 20),
        text: 'Whats up? :)',
      ),
    ];

    _chewieController = ChewieController(
      videoPlayerController: _videoPlayerController1,
      autoPlay: widget.isAutoPlay ?? false,
      looping: widget.isLooping ?? false,
      hideControlsTimer: Duration(seconds: widget.hideControlsAfter ?? 3),
      showControls: widget.hideControls ?? true,
      startAt: widget.startTime != null
          ? Duration(milliseconds: (widget.startTime! * 1000).toInt())
          : null,
      aspectRatio: widget.aspectRatio ?? 1.7,
      allowFullScreen: !(widget.disableFullScreen ?? false),
      isLive: widget.isLive ?? false,
      zoomAndPan: !(widget.disableZoomAndPan ?? false),
      showOptions: !(widget.hideOptions ?? false),
      allowedScreenSleep: widget.allowScreenSleep ?? false,
      allowMuting: !(widget.disableMuting ?? false),
      allowPlaybackSpeedChanging:
          !(widget.disablePlaybackSpeedChanging ?? false),
      autoInitialize: !(widget.disableAutoInitialize ?? false),
      fullScreenByDefault: widget.fullScreenByDefault ?? false,
      draggableProgressBar: !(widget.nonDraggableProgressBar ?? false),
      playbackSpeeds:
          widget.playbackSpeedList ?? [0.25, 0.5, 0.75, 1, 1.25, 1.5, 1.75, 2],
      progressIndicatorDelay: widget.progressIndicatorDelay != null
          ? Duration(milliseconds: (widget.progressIndicatorDelay!))
          : null,
      additionalOptions: (context) {
        return <OptionItem>[
          OptionItem(
            onTap: toggleVideo,
            iconData: Icons.live_tv_sharp,
            title: 'Next Video',
          ),
        ];
      },
      subtitle: Subtitles(subtitles),
      subtitleBuilder: (context, dynamic subtitle) => Container(
        padding: const EdgeInsets.all(10.0),
        child: subtitle is InlineSpan
            ? RichText(
                text: subtitle,
              )
            : Text(
                subtitle.toString(),
                style: const TextStyle(color: Colors.black),
              ),
      ),
    );
  }

  //Function to switch to the next video in list
  Future<void> toggleVideo() async {
    await _videoPlayerController1.pause();
    widget.currentPlayIndex = (widget.currentPlayIndex ?? 0) + 1;
    if (widget.currentPlayIndex! >= srcs.length) {
      widget.currentPlayIndex = 0;
    }
    await initializePlayer();
  }

  //Building the widget
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      theme: AppTheme.light.copyWith(
        platform: _platform ?? Theme.of(context).platform,
      ),
      home: Scaffold(
        body: Column(
          children: <Widget>[
            Expanded(
              child: Center(
                child: _chewieController != null && _chewieController!
                  .videoPlayerController.value.isInitialized
                  ? Chewie(controller: _chewieController!,)
                const Column(
                  mainAxisAlignment: MainAxisAlignment.center,
                  children: [
                    CircularProgressIndicator(),
                    SizedBox(height: 20),
                    Text('Loading'),
                    ],
                  ),
                ),
              ),
            ],
          ),
        ),
      );
    }
  }

// Theme
class AppTheme {
  static final light = ThemeData(
    brightness: Brightness.light,
    useMaterial3: true,
    colorScheme: const ColorScheme.light(secondary: Colors.red),
    disabledColor: Colors.grey.shade400,
    visualDensity: VisualDensity.adaptivePlatformDensity,
  );

  static final dark = ThemeData(
    brightness: Brightness.dark,
    colorScheme: const ColorScheme.dark(secondary: Colors.red),
    disabledColor: Colors.grey.shade400,
    useMaterial3: true,
    visualDensity: VisualDensity.adaptivePlatformDensity,
  );
}````

So I tried to download the app, run it on the web, run it on Android Studio, etc with no hope. I was expecting to simply have the video player playing the videosList if it's not empty, and if it's empty then it'll instead use the videoPath as its first entry and play that video. I tried to remove all of that logic and instead hardcode the video and tried several different ones used in Chewie's official documentation with no hope.

If anyone can figure out what might be causing this problem I will greatly appreciate you. I spent the last 8 hours on this so any help would be appreciated xD
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant