youtube_player_flutter icon indicating copy to clipboard operation
youtube_player_flutter copied to clipboard

[BUG] YoutubePlayerIFrame scrolling issue (flutter Web)

Open ozz-rjq opened this issue 3 years ago • 22 comments

Describe the bug If you put YoutubePlayerIFrame inside the listview, hover over the widget and try to scroll - it doesn't work.

To Reproduce Steps to reproduce the behavior:

  1. Create a flutter app
  2. Add youtube_player_iframe package
  3. Create a listview, add some test elements and YoutubePlayerIFrame widget.
  4. Scrolling does not work when a mouse is over the YoutubePlayerIFrame widget. Looks like it intercepts all the gestures.

Expected behavior ListView should be scrollable like in the native apps.

Technical Details:

  • Device: [Flutter Web]

ozz-rjq avatar Feb 03 '21 08:02 ozz-rjq

Try adding this code to prevent that the webview into the component try to handle the scroll events

YoutubePlayerIFrame(
      gestureRecognizers: <Factory<OneSequenceGestureRecognizer>>{},
      controller: _controller,
),

In mobile works fine 🔥, regards!

Jairolaya12x avatar Feb 26 '21 15:02 Jairolaya12x

      gestureRecognizers: <Factory<OneSequenceGestureRecognizer>>{},

This solution doesn't work on web.

I have the same issue.

FerBueroTrebino avatar Mar 23 '21 21:03 FerBueroTrebino

I have the same issue, is there anyone who can have the solution for this?

quangvtvp avatar Jun 03 '21 04:06 quangvtvp

I have the same issue, is there anyone who can have the solution for this?

@quangvtvp my solution was to change to the package youtube_plyr_iframe.

FerBueroTrebino avatar Jun 03 '21 10:06 FerBueroTrebino

I have the same issue, is there anyone who can have the solution for this?

@quangvtvp my solution was to change to the package youtube_plyr_iframe.

@FerBueroTrebino its also not working on web, have you used any specific configuration

deepakrana0011 avatar Jun 09 '21 11:06 deepakrana0011

@deepakrana0011 Did you try to add the Scrollbar widget?

Here is the code of my implementation:

class YoutubePlayer extends StatefulWidget {
  final String videoID;
  YoutubePlayer(this.videoID);
  @override
  _YoutubePlayerState createState() => _YoutubePlayerState();
}

class _YoutubePlayerState extends State<YoutubePlayer> {
  @override
  Widget build(BuildContext context) {
    return Material(
      color: Colors.transparent,
      child: InkWell(
        onTap: () {
          _showDialog(
            context,
            widget.videoID,
          );
        },
        child: Stack(
          alignment: Alignment.center,
          children: <Widget>[
            Stack(
              children: <Widget>[
                LayoutBuilder(
                  builder: (context, constraints) {
                    if (kIsWeb && constraints.maxWidth > 800) {
                      return Container(
                        color: Colors.transparent,
                        padding: EdgeInsets.all(5),
                        width: MediaQuery.of(context).size.width / 2,
                        child: ClipRRect(
                          borderRadius: BorderRadius.circular(10.0),
                          child: new Image.network(
                            YoutubePlayerController.getThumbnail(
                                videoId: widget.videoID,
                                // todo: get thumbnail quality from list
                                quality: ThumbnailQuality.max),
                            fit: BoxFit.fill,
                          ),
                        ),
                      );
                    } else {
                      return Container(
                        color: Colors.transparent,
                        padding: EdgeInsets.all(5),
                        width: MediaQuery.of(context).size.width * 2,
                        child: ClipRRect(
                          borderRadius: BorderRadius.circular(10.0),
                          child: new Image.network(
                            YoutubePlayerController.getThumbnail(
                                videoId: widget.videoID,
                                // todo: get thumbnail quality from list
                                quality: ThumbnailQuality.max,
                                webp: false),
                            fit: BoxFit.fill,
                          ),
                        ),
                      );
                    }
                  },
                ),
              ],
            ),
            Icon(
              Icons.play_circle_filled,
              color: Colors.white,
              size: 55.0,
            ),
          ],
        ),
      ),
    );
  }

FerBueroTrebino avatar Jun 09 '21 12:06 FerBueroTrebino

@deepakrana0011 Did you try to add the Scrollbar widget?

Here is the code of my implementation:

class YoutubePlayer extends StatefulWidget {
  final String videoID;
  YoutubePlayer(this.videoID);
  @override
  _YoutubePlayerState createState() => _YoutubePlayerState();
}

class _YoutubePlayerState extends State<YoutubePlayer> {
  @override
  Widget build(BuildContext context) {
    return Material(
      color: Colors.transparent,
      child: InkWell(
        onTap: () {
          _showDialog(
            context,
            widget.videoID,
          );
        },
        child: Stack(
          alignment: Alignment.center,
          children: <Widget>[
            Stack(
              children: <Widget>[
                LayoutBuilder(
                  builder: (context, constraints) {
                    if (kIsWeb && constraints.maxWidth > 800) {
                      return Container(
                        color: Colors.transparent,
                        padding: EdgeInsets.all(5),
                        width: MediaQuery.of(context).size.width / 2,
                        child: ClipRRect(
                          borderRadius: BorderRadius.circular(10.0),
                          child: new Image.network(
                            YoutubePlayerController.getThumbnail(
                                videoId: widget.videoID,
                                // todo: get thumbnail quality from list
                                quality: ThumbnailQuality.max),
                            fit: BoxFit.fill,
                          ),
                        ),
                      );
                    } else {
                      return Container(
                        color: Colors.transparent,
                        padding: EdgeInsets.all(5),
                        width: MediaQuery.of(context).size.width * 2,
                        child: ClipRRect(
                          borderRadius: BorderRadius.circular(10.0),
                          child: new Image.network(
                            YoutubePlayerController.getThumbnail(
                                videoId: widget.videoID,
                                // todo: get thumbnail quality from list
                                quality: ThumbnailQuality.max,
                                webp: false),
                            fit: BoxFit.fill,
                          ),
                        ),
                      );
                    }
                  },
                ),
              ],
            ),
            Icon(
              Icons.play_circle_filled,
              color: Colors.white,
              size: 55.0,
            ),
          ],
        ),
      ),
    );
  }

@FerBueroTrebino as per code you are showing only thumbnail of the youtube video where you are playing the youtube video

deepakrana0011 avatar Jun 10 '21 06:06 deepakrana0011

Same here, I really don't know what to do.... Iv made a player from scratch to VIMEO and works fine, using video player from flutter itself, but all the players from youtube all have to much issues that nobody can answer how to fix

Katekko avatar Jul 07 '21 18:07 Katekko

anyUpdate on scroll issue ? or aything else works for web? i tried something like this : StackOverflow

yeasin50 avatar Jul 16 '21 11:07 yeasin50

Any update on this I am facing the same issue on the web.?

jigarfumakiya avatar Mar 17 '22 14:03 jigarfumakiya

same issue

deepak786 avatar Apr 08 '22 15:04 deepak786

any fix? I have same problem on production...

yustapps avatar Oct 23 '22 19:10 yustapps

Same issue still on most recent version. Also, I cannot make it unclickable using IgnorePointer

DexEze avatar Nov 02 '22 06:11 DexEze

https://github.com/sarbagyastha/youtube_player_flutter/issues/585#issuecomment-1377707071

Fy-Rakotondrabe avatar Jan 10 '23 18:01 Fy-Rakotondrabe

The suggested methods above don't work for web and the scrolling is blocked by the video frame. Does anyone have a solution? The documentation of gestureRecognizers states: "This is ignored on web." Is there a specific reason why? It is not a nice UX for users to get stuck on scrolling because of the video frames. We are using YoutubePlayer

aytunch avatar Apr 25 '23 16:04 aytunch

A solution here would be very valuable from the community. Having to choose between scroll functionality and interacting with the iFrame is a bit of a deal breaker for this package. A fix like this will greatly contribute!

sir-adam-smith avatar Aug 13 '23 14:08 sir-adam-smith

Any luck on this?

DavidOrakpo avatar Aug 24 '23 14:08 DavidOrakpo

I used thumbnails on list and played video on dialog 😅. You can check this

yeasin50 avatar Aug 24 '23 15:08 yeasin50

The fundamental problem here is nothing to do with the widget per se. The issue is that an embedded iFrame in Flutter Web steals all the events and so the scroll event is not registered.

"Due to security restrictions with cross-origin iframe elements, Flutter cannot dispatch pointer events to an HTML view. If an iframe is the target of an event, the window containing the is not notified of the event. In particular, this means that any pointer events which land on an iframe will not be seen by Flutter, and so the HTML view cannot participate in gesture detection with other widgets."

This widget happens to use an html embedded iFrame because that is the standard way youTube videos are played (some people have tried to circumvent this, but it is a nightmare to support as they rely on a custom api to get the source url from the embed code and this is dependent upon too many factors that may change over time).

So the options are:

  1. Stuck with scroll not working, but other events being OK in the iFrame/player
  2. Overlay in a Stack with a widget using PointerInterceptor to stop any events going to the iFrame. This enables the scolling but stops all other events like click events.

The same is true of all schemes that use the flutter_inappwebview package, as the most recent beta version 6.0.0-beta.25 of this package - which now supports Flutter Web - uses an iFrame at its base.

It's a real pain. Hopefully sometime this will be fixed in the future, but in the meantime it looks like the earlier suggestions of using a thumbnail of the video and opening a popup window to play the video look like the best bet.

icecandy avatar Nov 14 '23 11:11 icecandy

I used thumbnails on list and played video on dialog 😅. You can check this

I ended up doing the same

themattman18 avatar Nov 16 '23 00:11 themattman18

I'm using a hack that is good enough for my needs:

Stack(
  children: [
    YoutubePlayer(
      enableFullScreenOnVerticalDrag: false,
      controller: controller,
      aspectRatio: 16 / 9,
    ),
    if (showOverlay)
      Positioned.fill(
        child: PointerInterceptor(
          child: GestureDetector(
            onTap: () {
              setState(() {
                showOverlay = false;
              });
              controller.playVideo();
            },
            child: Container(
              color: Colors.transparent,
            ),
          ),
        ),
      ),
  ],
)

Basically it needs one tap to dismiss the overlay and start playing the video. After the first tap we end up in the same issue, but at least like this we can scroll the list before the first click.

adsonpleal avatar Jan 23 '24 19:01 adsonpleal

any updates? I still have that issue

sgruhier avatar Feb 26 '24 15:02 sgruhier