flutter_widget_from_html icon indicating copy to clipboard operation
flutter_widget_from_html copied to clipboard

iframes with data-src attribute don't load video content

Open nagash93 opened this issue 4 months ago • 18 comments

Steps to Reproduce

iframes that use the data-src attribute instead of src (common lazy loading implementation) don't render or play video content correctly in the widget.

HTML
<iframe 
  width="560" 
  height="315" 
  data-src="https://www.youtube-nocookie.com/embed/8rvRE0YGZC0?si=FSGjHOuepA_66fIv" 
  title="YouTube video player" 
  frameborder="0" 
  allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" 
  referrerpolicy="strict-origin-when-cross-origin" 
  allowfullscreen 
  src="data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEAOw==" 
  class="lazyload" 
  data-load-mode="1">
</iframe>
`HtmlWidget` configuration

 HtmlWidget(
              post.content?.rendered ?? '',
              textStyle: TextStyle(
                fontSize: 18,
                color: context.textColor(),
              ))
Tesing environment
[✓] Flutter (Channel stable, 3.35.2, on macOS 15.5 24F74 darwin-arm64, locale es-ES) [1.368ms]
    • Flutter version 3.35.2 on channel stable at /Users/fabianperez/fvm/versions/3.35.2
    • Upstream repository https://github.com/flutter/flutter.git
    • Framework revision 05db968908 (12 hours ago), 2025-08-25 10:21:35 -0700
    • Engine revision a8bfdfc394
    • Dart version 3.9.0
    • DevTools version 2.48.0
    • Feature flags: enable-web, enable-linux-desktop, enable-macos-desktop, enable-windows-desktop, enable-android, enable-ios, cli-animations, enable-lldb-debugging

[!] Android toolchain - develop for Android devices (Android SDK version 35.0.1) [1.810ms]
    • Android SDK at /Users/fabianperez/Library/Android/sdk
    • Emulator version 35.3.11.0 (build_id 12836668) (CL:N/A)
    • Platform android-36, build-tools 35.0.1
    • Java binary at: /Applications/Android Studio.app/Contents/jbr/Contents/Home/bin/java
      This is the JDK bundled with the latest Android Studio installation on this machine.
      To manually set the JDK path, use: `flutter config --jdk-dir="path/to/jdk"`.
    • Java version OpenJDK Runtime Environment (build 21.0.6+-13391695-b895.109)
    ! Some Android licenses not accepted. To resolve this, run: flutter doctor --android-licenses

[✓] Xcode - develop for iOS and macOS (Xcode 16.2) [1.680ms]
    • Xcode at /Applications/Xcode.app/Contents/Developer
    • Build 16C5032a
    • CocoaPods version 1.16.2

[✓] Chrome - develop for the web [6ms]
    • Chrome at /Applications/Google Chrome.app/Contents/MacOS/Google Chrome

[✓] Android Studio (version 2025.1) [6ms]
    • Android Studio at /Applications/Android Studio.app/Contents
    • Flutter plugin can be installed from:
      🔨 https://plugins.jetbrains.com/plugin/9212-flutter
    • Dart plugin can be installed from:
      🔨 https://plugins.jetbrains.com/plugin/6351-dart
    • Java version OpenJDK Runtime Environment (build 21.0.6+-13391695-b895.109)

[✓] VS Code (version 1.101.0) [5ms]
    • VS Code at /Applications/Visual Studio Code.app/Contents
    • Flutter extension can be installed from:
      🔨 https://marketplace.visualstudio.com/items?itemName=Dart-Code.flutter

[✓] Connected device (3 available) [6,5s]
    • iPhone 16 (mobile) • 47079FEA-73C2-4273-8DE0-2629D32F6A02 • ios            • com.apple.CoreSimulator.SimRuntime.iOS-18-2 (simulator)
    • macOS (desktop)    • macos                                • darwin-arm64   • macOS 15.5 24F74 darwin-arm64
    • Chrome (web)       • chrome                               • web-javascript • Google Chrome 139.0.7258.139

[✓] Network resources [1.185ms]
    • All expected network resources are available.

Expected results

iframes with data-src should load and display YouTube video content normally, recognizing the data-src attribute as a valid source for the iframe.

Actual results

iframes with data-src don't load video content, showing an empty or blank iframe. The library appears to not recognize or process the data-src attribute, which is commonly used in CMS systems like WordPress to implement automatic lazy loading.

nagash93 avatar Aug 26 '25 05:08 nagash93

flutter_widget_from_html v0.17.1 has been released with support for this. Please try upgrading and see whether it works for you.

daohoangson avatar Aug 31 '25 15:08 daohoangson

Hi, with the new update it doesn't work for me. Could you please try with this code?

`

`

nagash93 avatar Sep 01 '25 01:09 nagash93

IMG-20251030-WA0014.jpg

I'm getting this when using youtube embed with iframe

<iframe src="//www.youtube.com/embed/aEGxfFx9FgM" width="640" height="360" class="note-video-clip"></iframe>

The exact html used to work properly but now I'm getting this behaviour

Any solutions ?

Note: i tried to add the refererpolicy=“cross-origin-with-strict-origin” but it doesn't work

Belveloper avatar Oct 30 '25 10:10 Belveloper

IMG-20251030-WA0014.jpg

I'm getting this when using youtube embed with iframe

<iframe src="//www.youtube.com/embed/aEGxfFx9FgM" width="640" height="360" class="note-video-clip"></iframe>

The exact html used to work properly but now I'm getting this behaviour

Any solutions ?

Note: i tried to add the refererpolicy=“cross-origin-with-strict-origin” but it doesn't work

me too. flutter 3.35.1

dungtv1991 avatar Oct 30 '25 10:10 dungtv1991

IMG-20251030-WA0014.jpg

I'm getting this when using youtube embed with iframe

<iframe src="//www.youtube.com/embed/aEGxfFx9FgM" width="640" height="360" class="note-video-clip"></iframe>

The exact html used to work properly but now I'm getting this behaviour

Any solutions ?

Note: i tried to add the refererpolicy=“cross-origin-with-strict-origin” but it doesn't work

me too. flutter 3.35.1

Same problem since flutter 3.29

Same thing with flutter 3.35.7 I don't think the issue is with the flutter version

Belveloper avatar Oct 30 '25 12:10 Belveloper

The error 153 that they are reporting is not the same as what I explained in this issue; according to my research, it is happening to different libraries due to a change in YouTube's policies and cookies.

nagash93 avatar Oct 30 '25 13:10 nagash93

The error 153 that they are reporting is not the same as what I explained in this issue; according to my research, it is happening to different libraries due to a change in YouTube's policies and cookies.

I have tried changing youtube.com to youtube-nocookie.com and adding referrerpolicy="strict-origin-when-cross-origin", but it still doesn’t work.

dungtv1991 avatar Oct 31 '25 07:10 dungtv1991

This was working perfectly as expected

<iframe src="//www.youtube.com/embed/aEGxfFx9FgM" width="640" height="360" class="note-video-clip"></iframe>

But since YouTube changed their policies it stopped

Any suggestions ?

Belveloper avatar Nov 01 '25 11:11 Belveloper

This was working perfectly as expected

<iframe src="//www.youtube.com/embed/aEGxfFx9FgM" width="640" height="360" class="note-video-clip"></iframe>

But since YouTube changed their policies it stopped

Any suggestions ?

My temporary solution to this problem is to use youtube_player_iframe. Here’s an example code: if (element.localName == 'iframe' && element.attributes.containsKey('src')) { final src = element.attributes['src']!;

        final videoId = YoutubePlayerController.convertUrlToId(src);

        if (videoId != null) {
          final controller = YoutubePlayerController.fromVideoId(
            videoId: videoId,
            autoPlay: true,
            params: const YoutubePlayerParams(
              showControls: true,
              showFullscreenButton: false,
              origin: 'https://www.youtube-nocookie.com',
            ),
          );

          return Container(
            padding: const EdgeInsets.symmetric(vertical:16),
            width: double.infinity,
            child: YoutubePlayer(
              controller: controller,
              aspectRatio: 16 / 9,
            ),
          );
        }
      }

dungtv1991 avatar Nov 03 '25 03:11 dungtv1991

Same problem, <iframe src="https://www.youtube.com/embed/g-r8nFhsxnU" width="560" height="314" allowfullscreen="allowfullscreen"></iframe>

mohamedds-12 avatar Nov 05 '25 11:11 mohamedds-12

I think it's a youtube bug they should Fix it

Belveloper avatar Nov 05 '25 14:11 Belveloper

Same issue here. It's also not working when replacing the youtube.com with youtube-nocookie.com in the url.

DFelten avatar Nov 07 '25 12:11 DFelten

Did you find any solution?

Belveloper avatar Nov 12 '25 11:11 Belveloper

Did you find any solution?

The temporary solution I found is to use customWidgetBuilder together with the youtube_player_iframe package.

With this approach, you can detect <iframe> elements whose src attribute contains "youtube" and then render them using the Youtube player widget instead of a raw HTML iframe:

HtmlWidget(
  post.videoEmbed ?? '',
  customWidgetBuilder: (e) {
    if (e.localName == 'iframe') {
      final src = e.attributes['src'] ?? '';
      if (src.contains('youtube')) {
        final videoId = YoutubePlayerController.convertUrlToId(src);

        if (videoId != null) {
          final controller = YoutubePlayerController.fromVideoId(
            videoId: videoId,
            autoPlay: false,
            params: const YoutubePlayerParams(
              showControls: true,
              showFullscreenButton: false,
              origin: 'https://www.youtube-nocookie.com',
            ),
          );

          return Container(
            padding: const EdgeInsets.symmetric(vertical: 16),
            width: double.infinity,
            child: YoutubePlayer(
              controller: controller,
              aspectRatio: 16 / 9,
            ),
          );
        }
      }
    }
    return null;
  },
)

This workaround lets you properly display embedded YouTube videos, until a more permanent solution is available.

nagash93 avatar Nov 12 '25 13:11 nagash93

Unfortunately even with the YoutubePlayer and your example factory the error still remains for us. Not sure what to do here.

DFelten avatar Nov 19 '25 11:11 DFelten

Unfortunately even with the YoutubePlayer and your example factory the error still remains for us. Not sure what to do here.

I did the same thing with youtube player Same error black screen no video playing 😐

Belveloper avatar Nov 19 '25 16:11 Belveloper

It seems that only some videos are working with this workaround. Other videos just show a black screen.

DFelten avatar Nov 20 '25 07:11 DFelten

This is btw our working factory for YouTube with the package youtube_player_iframe and some adjustments. It's working for all videos since there is a bug within the package.

Cue the video instead of loading it was the solution, as it would be auto-played then. Do not initialize the controller via "YoutubePlayerController.fromVideoId" as this cannot correctly handle videos with ids that contain a "-".

Issue: https://github.com/sarbagyastha/youtube_player_flutter/issues/1060

mixin TMXYoutubeFactory on WidgetFactory {
  @override
  void parse(BuildTree meta) {
    if (meta.element.localName == 'iframe') {
      final src = meta.element.attributes['src'];

      if (src != null && src.contains('youtube')) {
        final videoId = YoutubePlayerController.convertUrlToId(src);

        if (videoId != null) {
          meta.register(
            BuildOp(
              priority: 9999,
              onRenderBlock: (_, _) => YoutubePlayerFromHtml(
                videoId: videoId,
              ),
            ),
          );
        }
      }
    }

    return super.parse(meta);
  }
}

/// A widget that renders a YouTube player from an HTML iframe element via video id.
class YoutubePlayerFromHtml extends StatefulWidget {
  const YoutubePlayerFromHtml({required this.videoId, super.key});

  /// The YouTube video ID to play.
  final String videoId;

  @override
  State<YoutubePlayerFromHtml> createState() => _YoutubePlayerFromHtmlState();
}

class _YoutubePlayerFromHtmlState extends State<YoutubePlayerFromHtml> {
  late final controller = YoutubePlayerController(
    params: const YoutubePlayerParams(
      showFullscreenButton: true,
      enableCaption: false,
      interfaceLanguage: 'de',
      origin: 'https://www.youtube-nocookie.com',
    ),
  );

  @override
  void initState() {
    controller.cueVideoById(videoId: widget.videoId);
    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    return YoutubePlayer(controller: controller);
  }

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

DFelten avatar Dec 08 '25 11:12 DFelten