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
690 stars 766 forks source link

[BUG] YoutubePlayerIFrame scrolling issue (flutter Web) #434

Open ozz-rjq opened 3 years ago

ozz-rjq commented 3 years ago

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:

Jairolaya12x commented 3 years ago

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!

FerBueroTrebino commented 3 years ago
      gestureRecognizers: <Factory<OneSequenceGestureRecognizer>>{},

This solution doesn't work on web.

I have the same issue.

quangvtvp commented 3 years ago

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

FerBueroTrebino commented 3 years ago

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.

deepakrana0011 commented 3 years ago

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

FerBueroTrebino commented 3 years ago

@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,
            ),
          ],
        ),
      ),
    );
  }
deepakrana0011 commented 3 years ago

@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

Katekko commented 3 years ago

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

yeasin50 commented 3 years ago

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

jigarfumakiya commented 2 years ago

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

deepak786 commented 2 years ago

same issue

yustapps commented 1 year ago

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

DexEze commented 1 year ago

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

Fy-Rakotondrabe commented 1 year ago

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

aytunch commented 1 year ago

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

sir-adam-smith commented 1 year ago

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!

DavidOrakpo commented 11 months ago

Any luck on this?

yeasin50 commented 11 months ago

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

icecandy commented 9 months ago

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.

themattman18 commented 9 months ago

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

I ended up doing the same

adsonpleal commented 6 months ago

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.

sgruhier commented 5 months ago

any updates? I still have that issue

Abdulazeez-Raja commented 1 week ago

any update ?