sarbagyastha / youtube_player_flutter

A Flutter plugin for inline playback or streaming of YouTube videos using the official iFrame Player API.
https://youtube.sarbagyastha.com.np
BSD 3-Clause "New" or "Revised" License
699 stars 806 forks source link

The player is not loading #974

Open sourav-android opened 1 month ago

sourav-android commented 1 month ago

Is there an existing issue for this?

Package

youtube_player_flutter

What happened?

I am using the youtube_player_flutter: ^8.1.2 along with carousel_slider: ^4.2.1 but the player is never initialized. I haven't found any solution to it so far. Any help would be appreciated.

What is the expected behaviour?

it should play the video at the end of the list where I have the video url. I can see the videoId is extracted and everything works except the fact that youtube player is never initialized or ready.

How to reproduce?

environment: sdk: ">=2.18.2 <3.0.0" youtube_player_flutter: ^8.1.2 carousel_slider: ^4.2.1

Flutter Doctor Output

class PackageImageSlider extends StatefulWidget {
  final List<String> imageUrls;
  final List<String>? videoUrls;

  const PackageImageSlider({
    Key? key,
    required this.imageUrls,
    this.videoUrls,
  }) : super(key: key);

  @override
  State<PackageImageSlider> createState() => _PackageImageSlideState();
}

class _PackageImageSlideState extends State<PackageImageSlider> {
  int _currentCarouselIndex = 0;
  final CarouselController _carouselController = CarouselController();
  late YoutubePlayerController _youtubeController;
  bool _isPlayerReady = false;

  @override
  void initState() {
    super.initState();
    if (widget.videoUrls != null && widget.videoUrls!.isNotEmpty) {
      _initializeYouTubePlayer(widget.videoUrls!.first);
    }
  }

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

  void _initializeYouTubePlayer(String videoUrl) {
    final videoId = YoutubePlayer.convertUrlToId(videoUrl);
    if (videoId != null) {
      _youtubeController = YoutubePlayerController(
        initialVideoId: videoId,
        flags: const YoutubePlayerFlags(
          autoPlay: false,
          mute: false,
        ),
      )..addListener(_listener);
    } else {
      if (kDebugMode) {
        print('==> Invalid YouTube URL: $videoUrl');
      }
    }
  }

  void _listener() {
    if (_youtubeController.value.isReady && mounted && !_isPlayerReady) {
      setState(() {
        _isPlayerReady = true;
      });
    }
    if (_youtubeController.value.hasError) {
      if (kDebugMode) {
        print(
            '==> YouTube player error: ${_youtubeController.value.errorCode}');
      }
    }
  }

  @override
  Widget build(BuildContext context) {
    final hasVideo = widget.videoUrls != null && widget.videoUrls!.isNotEmpty;
    final totalItems = widget.imageUrls.length + (hasVideo ? 1 : 0);

    return Container(
      color: Colors.amberAccent,
      height: 26.h,
      child: Stack(
        children: [
          SizedBox(
            height: 26.h,
            width: MediaQuery.of(context).size.width,
            child: CarouselSlider(
              carouselController: _carouselController,
              options: CarouselOptions(
                onPageChanged: (index, reason) {
                  setState(() {
                    _currentCarouselIndex = index;
                    if (index == widget.imageUrls.length && _isPlayerReady) {
                      _youtubeController.play();
                      if (kDebugMode) {
                        print('==> Playing video at index: $index');
                      }
                    } else if (_isPlayerReady) {
                      _youtubeController.pause();
                      if (kDebugMode) {
                        print('==> Pausing video at index: $index');
                      }
                    }
                  });
                },
                enableInfiniteScroll: totalItems > 1,
                autoPlay: false,
                enlargeFactor: 0,
                viewportFraction: 0.9999,
                scrollPhysics: const BouncingScrollPhysics(), // Enable swiping
              ),
              items: [
                ...widget.imageUrls.map((e) => Container(
                      decoration: BoxDecoration(
                        image: DecorationImage(
                          image: NetworkImage(e),
                          fit: BoxFit.cover,
                        ),
                      ),
                    )),
                if (hasVideo)
                  SizedBox(
                    height: 26.h,
                    child: _isPlayerReady
                        ? YoutubePlayer(
                            controller: _youtubeController,
                            showVideoProgressIndicator: true,
                          )
                        : const Center(child: CircularProgressIndicator()),
                  ),
              ],
            ),
          ),
          Container(
            height: 26.h,
            width: MediaQuery.of(context).size.width,
            decoration: BoxDecoration(
              gradient: LinearGradient(
                begin: Alignment.topCenter,
                end: Alignment.bottomCenter,
                colors: [
                  Colors.transparent,
                  Colors.black.withOpacity(0.1),
                  Colors.black.withOpacity(0.2),
                  Colors.black.withOpacity(0.5),
                  Colors.black.withOpacity(0.8),
                ],
              ),
            ),
          ),
          Align(
            alignment: Alignment.bottomCenter,
            child: Container(
              padding: EdgeInsets.only(bottom: 2.h),
              child: AnimatedSmoothIndicator(
                count: totalItems,
                effect: const ExpandingDotsEffect(
                  dotHeight: 8,
                  dotWidth: 8,
                  dotColor: Colors.white,
                  activeDotColor: Colors.white,
                  expansionFactor: 2,
                  spacing: 4,
                ),
                onDotClicked: (index) {
                  _carouselController.animateToPage(index);
                },
                activeIndex: _currentCarouselIndex,
              ),
            ),
          ),
        ],
      ),
    );
  }
}
Reyrey14-1 commented 2 days ago

same here