Error when uploading multiple videos using youtube_player_iframe

598 views Asked by At

When I try to display several youtube players on the visible part of the page, the players may give an error instead of a video.

enter image description here

For example, if on the mobile version I try to build several players at once, then some give an error. And if there is only one player on the page or there are several players, but each one takes up the entire screen, then the videos load normally.

Mobile:

enter image description here

Fullscreen:

enter image description here

enter image description here

I am using https://pub.dev/packages/youtube_player_iframe

Code:

class YoutubeViewer extends StatefulWidget {
  final String videoID;

  const YoutubeViewer(this.videoID, {super.key});

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

class _YoutubeViewerState extends State<YoutubeViewer>
    with AutomaticKeepAliveClientMixin {
  late final YoutubePlayerController controller;
  bool isPlaying = false;

  @override
  bool get wantKeepAlive => true;

  @override
  void initState() {
    super.initState();
    controller = YoutubePlayerController.fromVideoId(
      params: const YoutubePlayerParams(
        enableCaption: false,
        showVideoAnnotations: false,
        playsInline: false,
        showFullscreenButton: true,
      ),
      videoId: widget.videoID,
    )..listen((event) {
      final playerState = event.playerState;

        if (playerState == PlayerState.playing) {
          setState(() {
            isPlaying = true;
          });
        } else if (playerState == PlayerState.ended ||
            playerState == PlayerState.paused ||
            playerState == PlayerState.unknown) {
          setState(() {
            isPlaying = false;
          });
        }
      });
  }

  @override
  void dispose() {
    controller.close();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    super.build(context);

    final player = YoutubePlayer(
      controller: controller,
      key: ValueKey(widget.videoID),
      gestureRecognizers:
          isPlaying ? null : <Factory<OneSequenceGestureRecognizer>>{},
    );

    return Padding(
      padding: const EdgeInsets.symmetric(horizontal: Dimensions.spacingLong),
      child: Stack(
        children: [
          player,
          Positioned.fill(
            child: PointerInterceptor(
              intercepting: !isPlaying,
              child: MouseRegion(
                cursor: SystemMouseCursors.click,
                child: GestureDetector(
                  onTap: () async => controller.playVideo(),
                ),
              ),
            ),
          ),
        ],
      ),
    );
  }
}

I tried to change key for YoutubePlayer, initialize YoutubePlayerController differently, remove const from YoutubeViewer constructor and widgets up the tree, remove AutomaticKeepAliveClientMixin.

1

There are 1 answers

0
searching9x On

I had the same problem using youtube_player_iframe. To display multiple videos on one page I used a simpler library "fwfh_webview" and displayed the videos in Iframes.

Add library: fwfh_webview: ^0.7.0+1

Write a Simple class:

import 'package:flutter/material.dart';
import 'package:flutter_widget_from_html_core/flutter_widget_from_html_core.dart';
import 'package:fwfh_webview/fwfh_webview.dart'; 
 

class SimpleHtmlYoutubeIframe extends StatelessWidget { 
  final String youtubeCode;

  const SimpleHtmlYoutubeIframe( {
    required this.youtubeCode,
    required super.key,
  });

  @override
  Widget build(BuildContext context) { 
    String content =
        '<iframe src="https://www.youtube.com/embed/$youtubeCode"></iframe>';

    return SizedBox(
      // height: height,
      // width: width,
      child: HtmlWidget(
        content,
        factoryBuilder: () => _YoutubeIframeWidgetFactory(),
      ),
    );
  }
}
 
class _YoutubeIframeWidgetFactory extends WidgetFactory with WebViewFactory {
  @override
  bool get webViewMediaPlaybackAlwaysAllow => true;
  @override
  String? get webViewUserAgent => 'Lang Learning';
}