My suggestion:

It would be great if we can select a nocookie-checkbox in the video_oembed media entity. With this, all youtube urls change automatic to youtube-nocookie.com urls.

Why automatically?
Because users copy the wrong URLs from youtube.

Source:
https://dri.es/how-to-remove-youtube-tracking

A step further:
Another approach for more privacy is this wordpress-variant:
https://de.wordpress.org/plugins/wp-youtube-lyte/

Comments

handkerchief created an issue. See original summary.

Version: 8.8.x-dev » 8.9.x-dev

Drupal 8.8.0-alpha1 will be released the week of October 14th, 2019, which means new developments and disruptive changes should now be targeted against the 8.9.x-dev branch. (Any changes to 8.9.x will also be committed to 9.0.x in preparation for Drupal 9’s release, but some changes like significant feature additions will be deferred to 9.1.x.). For more information see the Drupal 8 and 9 minor version schedule and the Allowed changes during the Drupal 8 and 9 release cycles.

berdir’s picture

There is a documented alter hook with this use case as an example:

/**
 * Alters an oEmbed resource URL before it is fetched.
 *
 * @param array $parsed_url
 *   A parsed URL, as returned by \Drupal\Component\Utility\UrlHelper::parse().
 * @param \Drupal\media\OEmbed\Provider $provider
 *   The oEmbed provider for the resource.
 *
 * @see \Drupal\media\OEmbed\UrlResolverInterface::getResourceUrl()
 */
function hook_oembed_resource_url_alter(array &$parsed_url, \Drupal\media\OEmbed\Provider $provider) {
  // Always serve YouTube videos from youtube-nocookie.com.
  if ($provider->getName() === 'YouTube') {
    $parsed_url['path'] = str_replace('://youtube.com/', '://youtube-nocookie.com/', $parsed_url['path']);
  }
}

That's the theory. In practice, this hook doesn't work, because it a) doesn't work with www.youtube.com, and b) replaces not the video URL but the oembed URL, resulting in: https://www.youtube-nocookie.com/oembed?url=https://www.youtube.com/watc......

You could alter the query instead, but youtube.com/oembed doesn't care about, and the embed snippet strips away the nocookie part.

The only thing that did work for me was altering the template directly:

/**
 * {@inheritdoc}
 */
function mymodule_preprocess_media_oembed_iframe(&$variables) {
  if (strpos((string) $variables['media'], 'youtube.com') !== FALSE) {
    $variables['media'] = IFrameMarkup::create(str_replace('youtube.com/', 'youtube-nocookie.com/', $variables['media']));
  }
}

That said, +1 to having this as a setting exposed to users.

seanb’s picture

As far as I could find we can not make youtube return a youtube-nocookie.com iframe we can directly embed. So I guess we have to str_replace the URL in the embed code we get back from youtube like the example Berdir posted.

I agree this would be a great setting to have in core and would even go one step further and suggest that nocookie should be our default. Any thoughts on that?

+1 from me for adding a setting and the hook.

berdir’s picture

In light of GDPR and so on, I think being respecting privacy by default makes a lot of sense.

Does anyone know how exactly this works with vimeo? When we investigates this we didn't find any good information on how much tracking that vimeo does by default and if and how you can opt out.

j-lee’s picture

I have done this by decorating the media.oembed.resource_fetcher service with an overwritten class (and load the high-res thumbnail).

use Drupal\media\OEmbed\Resource;
use Drupal\media\OEmbed\ResourceFetcher as MediaResourceFetcher;

/**
 * Overrides the oEmbed resources.
 *
 * This class override the media.oembed.resource_fetcher service from the core
 * media module.
 *
 * @see \Drupal\media\OEmbed\ResourceFetcher
 */
class ResourceFetcher extends MediaResourceFetcher {

  /**
   * @inheritDoc
   */
  protected function createResource(array $data, $url) {
    if ($data['type'] == Resource::TYPE_VIDEO && $data['provider_name'] == 'YouTube') {
      // Replace the default youtube domain with the no-cookie domain.
      $data['html'] = str_replace('youtube.com/', 'youtube-nocookie.com/', $data['html']);
      // Load the high-res thumbnail.
      $data['thumbnail_url'] = str_replace('/hqdefault.jpg', '/maxresdefault.jpg', $data['thumbnail_url']);
    }
    // Create the resource.
    return parent::createResource($data, $url);
  }
}
stillworks’s picture

GDPR requires you to introduce another click before the video loads.
After the click the video embed code should load. Not before.

Not very unfriendly but save.

Vimeo doesn't have something like youtube-nocookie

seanb’s picture

I agree this will not necessarily make a site GDPR compliant, we should definitely be very careful in how we name the checkbox to manage the expectations.

Vimeo seems to provide a dnt parameter to disable tracking: https://vimeo.zendesk.com/hc/en-us/articles/360001494447-Using-Player-Pa...

Like this: https://player.vimeo.com/video/76979871?dnt=1

Since Youtube and Vimeo are the only things we ship with, we could try to at least make these work.

Mr Iron’s picture

I do need that feature too, but don't know where to paste Berdirs code. Would be great to get a little hint..

luksak’s picture

@Mr Iron you need to copy this to one of your .module or .theme files and replace mymodule with either your module or your theme name. So lets say you theme has the name example it would work like this:

function example_preprocess_media_oembed_iframe(&$variables) {
  if (strpos((string) $variables['media'], 'youtube.com') !== FALSE) {
    $variables['media'] = IFrameMarkup::create(str_replace('youtube.com/', 'youtube-nocookie.com/', $variables['media']));
  }
}

I suggest you read those pages in case you are not familiar with that:

https://api.drupal.org/api/drupal/core%21lib%21Drupal%21Core%21Render%21...
https://api.drupal.org/api/drupal/core%21lib%21Drupal%21Core%21Render%21...

design.er’s picture

StatusFileSize
new63.39 KB

Berdir's function from #3 almost nails it.

I use the media field (with remote video) inside a paragraph but I've also tested it with a media field attached directly to a node. The result is the same: there's an iFrames with a src="/mysite/media/oembed?url=https%3A//www.youtube.com/watch%3Fv%3D-mSGwndFMp8&...". Inside this iFrame is another iFrame with a src="https://www.youtube-nocookie.com/embed/-mSGwndFMp8?feature=oembed".

I've attached a screenshot for better visualization.

The function from #3 alters the second iFrame src but not the first/parent.
This leads to the following situation: if I delete all cookies and introduce the function from #3, it initially loads only localStorage and sessionStorage entries from youtube-nocookie.com. I guess, this is how it should be. But when I reload the page a few times, it's loading the usual cookies & storage entries from google.com and youtube.com. I guess it has something to do with the parent iFrame still having youtube.com as src, instead of youtube-nocookie.com.

Can anybody reproduce the behavior?

Is there a way to rewrite the parent iFrame as well? Actually, I'm curious why it has two/nested iFrames in the first place.

anybody’s picture

Side-note: Still a very relevant point. We're planning a little helper module and formatter for iframes to provide a two-click solution, perhaps that's part of the solution for oembed, proof-of-concept or we might find people here to help:
https://www.drupal.org/project/iframe_privacy

abaier’s picture

We would also like to make the move away from video_embed_field to core's media remote video.

Until now we are using a patch for VEF to render youtube-embeds over the nocookie-domain. Also we are using VEF's lazy-load formatter, regarding GDPR, mentioned in #7.

So, thumbs up for a solution here, also regarding support for Vimeo, if possible.

Unfortunately I could not get #3 to work and got the following error inside the iFrame.

The website encountered an unexpected error. Please try again later.
Error: Class 'IFrameMarkup' not found in THEME_preprocess_media_oembed_iframe() (line 168 of themes/THEME/THEME.theme).
THEME_preprocess_media_oembed_iframe(Array, 'media_oembed_iframe', Array) (Line: 287)
Drupal\Core\Theme\ThemeManager->render('media_oembed_iframe', Array) (Line: 431)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 200)
Drupal\Core\Render\Renderer->render(Array) (Line: 170)
Drupal\media\Controller\OEmbedIframeController->Drupal\media\Controller\{closure}() (Line: 573)
Drupal\Core\Render\Renderer->executeInRenderContext(Object, Object) (Line: 171)
Drupal\media\Controller\OEmbedIframeController->render(Object)
call_user_func_array(Array, Array) (Line: 123)
Drupal\Core\EventSubscriber\EarlyRenderingControllerWrapperSubscriber->Drupal\Core\EventSubscriber\{closure}() (Line: 573)
Drupal\Core\Render\Renderer->executeInRenderContext(Object, Object) (Line: 124)
Drupal\Core\EventSubscriber\EarlyRenderingControllerWrapperSubscriber->wrapControllerExecutionInRenderContext(Array, Array) (Line: 97)
Drupal\Core\EventSubscriber\EarlyRenderingControllerWrapperSubscriber->Drupal\Core\EventSubscriber\{closure}() (Line: 151)
Symfony\Component\HttpKernel\HttpKernel->handleRaw(Object, 1) (Line: 68)
Symfony\Component\HttpKernel\HttpKernel->handle(Object, 1, 1) (Line: 57)
Drupal\Core\StackMiddleware\Session->handle(Object, 1, 1) (Line: 47)
Drupal\Core\StackMiddleware\KernelPreHandle->handle(Object, 1, 1) (Line: 106)
Drupal\page_cache\StackMiddleware\PageCache->pass(Object, 1, 1) (Line: 85)
Drupal\page_cache\StackMiddleware\PageCache->handle(Object, 1, 1) (Line: 50)
Drupal\ban\BanMiddleware->handle(Object, 1, 1) (Line: 47)
Drupal\Core\StackMiddleware\ReverseProxyMiddleware->handle(Object, 1, 1) (Line: 52)
Drupal\Core\StackMiddleware\NegotiationMiddleware->handle(Object, 1, 1) (Line: 23)
Stack\StackedHttpKernel->handle(Object, 1, 1) (Line: 708)
Drupal\Core\DrupalKernel->handle(Object) (Line: 19)
berdir’s picture

You're missing the use statement for that class: \Drupal\media\IFrameMarkup

abaier’s picture

Ah … thanks for the quick help Berdir!

Version: 8.9.x-dev » 9.1.x-dev

Drupal 8.9.0-beta1 was released on March 20, 2020. 8.9.x is the final, long-term support (LTS) minor release of Drupal 8, which means new developments and disruptive changes should now be targeted against the 9.1.x-dev branch. For more information see the Drupal 8 and 9 minor version schedule and the Allowed changes during the Drupal 8 and 9 release cycles.

hoporr’s picture

With the method show above by J-Lee, you do get access to a few more parameters, such as the thumbnail.

Just to add to J-Lee's description, what you are doing is to overwrite the default service for "media.oembed.resource_fetcher"
Besides the code above, you also have to define a service provider that alters this service.
(assuming your own service is under Drupal\my_module\OEmbed\MyModuleResourceFetcher')

namespace Drupal\mymodule;
use Drupal\Core\DependencyInjection\ContainerBuilder;
use Drupal\Core\DependencyInjection\ServiceProviderBase;

class MyModuleServiceProvider extends ServiceProviderBase {
  public function alter(ContainerBuilder $container) {
    // Overwrite the media fetcher to go through our filter
    $definition = $container->getDefinition('media.oembed.resource_fetcher');
    $definition->setClass('Drupal\my_module\OEmbed\MyModuleResourceFetcher');
  }
}
hoporr’s picture

@Berdir:

Vimeo: apparently you can give the player a setting, dnt=true (do not track)

https://developer.vimeo.com/api/oembed/videos

As it states, this setting will prevent vimeo from collecting play-stats.
I have not tried it, but found another link on GDPR that suggested the same for vimeo.

mrpauldriver’s picture

Some information about Vimeo privacy stuff. dnt needs work.

https://www.drupal.org/project/video_embed_field/issues/2998257

hoporr’s picture

@design.er

Correct, there are two iframes. It confused me, too, so here is what I found:

The outer iframe is actually generated by drupal's media system.
On my system, the generated outer iframe [It comes from the field-template] reads a bit different, like this:

< iframe ... src="/media/oembed?url=https%3A//www.youtube.com/watch%3Fv%... " ... >

The path /media/oembed is a controller in the media system.
This then loads in the second iframe, the actual iframe from youtube.

For the parts of that first iframe (html,head,body...), there is a template/preprocess: media-oembed-iframe.html.twg
so here is a way to insert further divs, or stylesheets.
(However, because of CROSS we can only affect this first iframe here, not the second one from youtube).

hoporr’s picture

@anybody:
I am also interested in the GDPR part here, where you only show the content after a click.

There is a sketched-in solution or recipe here:
https://www.1xinternet.de/en/blog/how-obtain-user-consent-prior-loading-...

As far as I can see, the trick seems to be to not load the iframe-string right away in the field-template (it would be "item.content" in the template).

Instead you store it in a data parameter of some wrapper div, using some div/CSS/JS structure.
That way, presumably, it does not execute and load anything external upon first loading.

Then, only upon an explicit click by the user, the JS moves the iframe-string from div data-attribute and builds a real DOM element, the actual iframe, at which point it would grab the external content.

You probably have to do this through the field-template and preprocess.

mrpauldriver’s picture

anybody’s picture

Please try, test and help to improve https://www.drupal.org/project/cookie_content_blocker

Of course a GDPR core integration for third party and cookie blocking would still be the best solution.

hoporr’s picture

@anybody
I saw this modules, but found the documentation very sketchy. Do you have any instructions on how make this work for this usecase? If so, please share.

anybody’s picture

Sorry, no. I'm not a maintainer of that project, but just found it some weeks ago and it looks promising. You might want to create an issue for that and help to push the project forward with some of your time wrinting documentation. That would be a nice gesture and benefit for all, even if you are not a developer. But back to topic here now please :)

hoporr’s picture

@MrPaulDriver

That recipe is somewhat similar: the iframe-src is initially loaded in the iframe as "data-src" and only after clearing the cookie does the JS load it over into "src". So it is also a sort of deferred loading...

In this recipe, there is a template for the outer iframe. In our case (with media), there is no such template; the existing media template is only for the content inside of that iframe, not the iframe tag itself. To change that outer iframe, I found that you can use template_preprocess_field, and you get to all that data as well.

jeni_dc’s picture

Not to steer this any further away from providing a solution in core for nocookie URLs, but having a look at one of those recipes it really doesn't need to be that complicated to not embed a video if the user hasn't agreed to the cookies.

I did something similar on a couple of D7 sites for a client, I would think it would be similar for 8/9. When the media is added from YouTube or Vimeo for example, an image of the video is also saved into the site's files directory to be used for thumbnails and whatnot. The trick is just to show that image since that's stored locally instead of the embed if the user hasn't consented to the right cookies. No need to worry about iframes or anything else yet.

Create one view mode of your media that only shows the thumbnail, maybe with a message about how to accept cookies to be able to watch it. I did that with a "no_cookies" view mode. Then swap the view modes depending on your cookie, or other conditions. You can do that in a hook_entity_view_mode_alter().

Once again I did this on D7, so caching may be an issue. On one site where all the users were authenticated it worked fine, on another site where all users were anonymous, and D7's caching kicked in, I needed to add the Cookie-Aware Page Cache module to make sure users were seeing the correct view mode. I'm not sure how cookies are handled with D8/D9 caching.

hoporr’s picture

Those two recipes above already gave a framework, but they left some details to be discovered. Here is how I got this to work, maybe it will help others.

1) Switch over to youtube-nocookie.com as already described above.

2) I now overwrite the template for oembed video fields,

function mymodule_theme($existing, $type, $theme, $path) {
  $theme = array();
  $theme['field__media__field_media_oembed_video__remote_video'] = [
    'base hook' => 'field',
    'template' => 'field--media--field-media-oembed-video--remote-video',
    'path' => $path . '/templates',
  ];  
  return $theme;
}

3) and preprocess it, setting various items including the thumbnail being the local image.
ALSO, very imporant: you remove the src attribute and put the youtube link in "data-src".
This will create an iframe that will not load automatically.

function mymodule_preprocess_field(&$variables, $hook){
   if ($variables['element']['#field_name'] == 'field_media_oembed_video'){
      $variables['consent_message'] = "By playing this video, .... ";
       
      // Grab the local video-thumbnail already in the system, so we can display that instead of getting the image from youtube
      $obj = $variables['element']['#object'];
      $thumbnail = $obj->get('thumbnail')->view();
      $out = \Drupal::service('renderer')->render($thumbnail);
      $variables['media_thumbnail'] = $out;
     
     // Switch over the SRC attribute to be "data-src"  so that iframe will not load external content
     $src = $variables['items'][0]['content']['#attributes']['src'];
     $variables['items'][0]['content']['#attributes']['data-src'] = $src;
     unset($variables['items'][0]['content']['#attributes']['src']);

    // You can turn on/off other things here as well.
}

4) Now prepare a new twig template that puts all this in to a special structure.
The idea is to display the GDPR consent message until some button is clicked (or a cookie setting accepted), and only then have JS reveal the iframe, and load up the src into the iframe. In the structure below, you either will show "my-module-media-consent-message" OR "my-module-media-video."

new file: field__media__field_media_oembed_video__remote_video.html.twig
this should overwrite field.html.twig,
in this case taken from the classy/stable base theme. Depending on your base-theme, this may differ

In this template, I have a "load external content" button, but alternatively you could ask to turn on a cookie-setting here explicitly (like EU_cookie-compliance category).

I only show the relevant part of the template here: you want to wrap "item.content" in this structure.

{% for item in items %}
<div{{ attributes.addClass(classes, 'field__item') }}>
    <div class="my-module-media-video">
        <div class="my-module-media-container">
           {{ item.content }}
        </div>
        
        <div class="my-module-media-consent">
          {{ media_thumbnail }}
          <div class="my-module-media-consent-message">
            <p>{{ consent_message }}</p>
            <button class="my-module-media-play-button">{{'Load External Content'|t}}</button>
          </div>
        </div>
    </div>
</div>
{% endfor %}

5) build some CSS / SASS to, by default a) hide the player div (my-module-media-video), b)show the consent div in place of the player, or on top of it (position: absolute). This part should be trivial, and I will not show the code here.

6) build some jQuery that upon click on the button a) hides the consent part, 2) shows the player part, and very important 3) loads up the src attribute for the iframe. That last part in effect then loads the video from youtube, including potentially the external cookies or local-storage items.

So create a JS in some library that gets loaded on this pages, and place something like this in it:

$('.my-module-media-play-button').click( function(){
   // Turn the respective parts on/off
   var video = $(this).closest('.my-module-media-video');
   $(video).find('.my-module-media-container').css('display', 'inline-block');
   $(video).find('.my-module-media-consent').hide();
      
   // And load up the src, so that it pulls the external content      	
   var videoIFrame = $(video).find('.my-mdoule-media-container iframe')
   var src = videoIFrame.attr("data-src");
   videoIFrame.attr('src', src);
});
 

Alternatively, your jQuery could do a test if a special cookie is set (like in Eu-Cookie-compliance you can set a category, which is then stored in "cookie-agreed-categories" or something), and only bring up the iframe after that category has been agreed to. It would follow the same mechanism.

And that's it, basically. So sprinkle in some CSS and JQuery to taste, and enjoy the recipe.

mrpauldriver’s picture

@hoporr That's an amazing bit of work you've done there.

I would much prefer it if this was wrapped up in a contrib module or better still, that core media called youtube videos from a cookieless domain.

ferst’s picture

Hello there!

I've been looking for the J-Lee #6 solution for High-Res thumbnails from Youtube, but I don't know where to insert the code.

May somebody give me a hand with this?

Thanks a lot in advance.

phenaproxima’s picture

I think that #3009003: Expose oEmbed resource object to iframe template would potentially allow this to be solved by custom code more easily, as @Berdir indicated in #3. For now, I'm leaving this issue open, but it seems like it might make sense to close this one as a duplicate.

berdir’s picture

I think in these times it makes sense to support being GDPR compatible out of the box, without custom code? The other issue would just make this easier I think, not fix it?

osopolar’s picture

There is also the module Media entity consent which might be helpful here. And it's already working in the COOKiES Consent Management Module.

Version: 9.1.x-dev » 9.2.x-dev

Drupal 9.1.0-alpha1 will be released the week of October 19, 2020, which means new developments and disruptive changes should now be targeted for the 9.2.x-dev branch. For more information see the Drupal 9 minor version schedule and the Allowed changes during the Drupal 9 release cycle.

r_h-l’s picture

the hook_oembed_resource_url_alter only alters the URL used to request the oEmbed data, but the iframe uses the 'html' attribute directly and unaltered.

The workaround we came up with was to use hook_preprocess_HOOK:

use Drupal\media\IFrameMarkup;

/**
 * Implements hook_preprocess_HOOK().
 */
function mymodule_preprocess_media_oembed_iframe(&$variables)
{
  $iFrame = $variables['media']->__toString();
  if (stripos($iFrame, 'youtube.com') !== false){
    $newFrame = str_replace('youtube.com/', 'youtube-nocookie.com/', $iFrame);
    $variables['media'] = IFrameMarkup::create($newFrame);
  }
}
berdir’s picture

@R_H-L: Isn't that basically exactly what I said in the first comment in this issue? :) And yes, at the very least, we need to fix the documentation of that hook, I'm not sure if it really serves any purpose.

r_h-l’s picture

@Berdir, you did. I think I missed it. It's been a long day.

berdir’s picture

No worry, I just meant it is yet another proof that having this documented somehow on that hook would have probably saved you and others a lot of time. We could just put an example code snippet in the hook documentation and remove the bad example, want to work on an MR/patch for that?

Version: 9.2.x-dev » 9.3.x-dev

Drupal 9.2.0-alpha1 will be released the week of May 3, 2021, which means new developments and disruptive changes should now be targeted for the 9.3.x-dev branch. For more information see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

zenimagine’s picture

I activated the Media module on my Drupal 9 website.

My website does not use any consent banner:

- I use Matomo for audience analysis with the parameters compliant with the RGPD.
- I use my own share button which supports no cookies.
- I only use contextual affiliate links (it is based on the page viewed, not on the visitor's profile).

I am currently looking for a solution for this third point.

I added a media with a YouTube URL in a node with the "Remote Video" media type.

BIG PROBLEM

When I view the page containing the YouTube video, my website is riddled with Youtube cookies.

How can I display the video without compromising the personal data of my visitors?

I see 2 solutions, but I don't know if this is possible:

1) Display the video without cookies. My video is monetized on YouTube, will this affect my income ?

2) Generate a thumbnail of the video that redirects the visitor to the video on YouTube when clicked.

I think the 2nd solution is the best. The Media module will be able to generate 2 thumbnails like in my screenshot. When the visitor hovers over the thumbnail (gray youtube logo) the logo turns red, he clicks on the thumbnail and a new tab opens to the video on Youtube.

I have videos on Youtube that I monetize and I'm afraid that by adding them to my website and blocking cookies, they will no longer be monetized.

The media module should offer 2 options, display the video or generate a thumbnail with a link to the YouTube video.

In the second case, the website would be GDPR compliant.

anybody’s picture

@zenimage: Have a look at
- https://www.drupal.org/project/cookie_content_blocker
- https://www.drupal.org/project/cookies
- https://www.drupal.org/project/gdpr_video

Back to topic now please. No off-topic discussion here please.

zenimagine’s picture

Thanks for your modules, but that doesn't solve the problem. I just want the Media module to generate a thumbnail of the YouTube video with a link to the video.
I don't want the video to upload to the Drupal site, but the link to open a YouTube tab for the video.

A visitor clicks on the video's thumbnail and a new tab opens to display it directly on YouTube.

Media should offer this option:

Upload the Youtube video to Drupal.
WHERE
Load the thumbnail with a link to the YouTube video.

Version: 9.3.x-dev » 9.4.x-dev

Drupal 9.3.0-rc1 was released on November 26, 2021, which means new developments and disruptive changes should now be targeted for the 9.4.x-dev branch. For more information see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

plessas’s picture

I 've found a related module, which shows an image and expects the consent of the user to show the embedded video:
https://www.drupal.org/project/gdpr_video

Version: 9.4.x-dev » 9.5.x-dev

Drupal 9.4.0-alpha1 was released on May 6, 2022, which means new developments and disruptive changes should now be targeted for the 9.5.x-dev branch. For more information see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

bob.hinrichs’s picture

This looked promising, but maddeningly, it does not help: https://www.drupal.org/project/oembed_providers - see https://www.drupal.org/project/oembed_providers/issues/3262248

With all of the sophistication of all of this code and the hours of puzzling over these systems, a nocookie url option is needed to comply with widely-used privacy standards.

Version: 9.5.x-dev » 10.1.x-dev

Drupal 9.5.0-beta2 and Drupal 10.0.0-beta2 were released on September 29, 2022, which means new developments and disruptive changes should now be targeted for the 10.1.x-dev branch. For more information see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

finex’s picture

Thanks for #35 :-)

Version: 10.1.x-dev » 11.x-dev

Drupal core is moving towards using a “main” branch. As an interim step, a new 11.x branch has been opened, as Drupal.org infrastructure cannot currently fully support a branch named main. New developments and disruptive changes should now be targeted for the 11.x branch, which currently accepts only minor-version allowed changes. For more information, see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

chris matthews’s picture

marcoka’s picture

Just FYI if you switch to the nocookie domain cookies get still loaded, external fonts.
Even if you link the hir-es image from youtube directly cookies are set.
The only solutions seems to be to load and use the thumb oembed itself stores in the oembed folder in /files

Here are my two cents about experiment i did

I have read simple module https://www.drupal.org/project/gdpr_video and tried to make it better.

The problem is that it removes the src="youtubevideourl" with JS to stop the video from playing. That is not realiable and if you disable JS then its not GDPR valid anymore.

I then changed the output of the oembed field using "thjeme_preprocess_media_oembed_iframe" to set the src to data-src. So the video is not loaded by default, even with JS.

Then you can click the accept button BUT you can not add the src="youtubevideo" to make it load because of CROSS
"Failed to read a named property 'document' from 'Window': Blocked a frame with origin "http://dev12.test123.de" from accessing a cross-origin frame."

I guess the problem is that we have an iframe inside an iframe. AFAIK the first wrapper iframe is for security reasons.

#28 will work BUT if you click the button the video (second iframe) will not load because data-src is also no tset to src.

Took me hours to fiddle around with this and that makes me think that it is impossible to implement this correctly at all in a module.

Solution

Found a solution. Only change the oembed (outer iframe) src to data-src. If you then change it, using js, to src back again, the inner frame gets loaded. Bonus: This also does not load the HUGE inner iframe code on pageload

ytsurk’s picture

I also decided (again) to go with a custom solution .. using data-src, the oembed thumbnail and the no-cookie domain.
(Not using a consent banner, so the cookies module seemed to heavy for me, although I did not tried)

But still I would welcome the no-cookie domain and the vimeo setting toggle (aka more privacy) for core's external video media type!

luisnicg’s picture

I applied the hook that Berdir shared in the first comment but I had to complement the solution by passing the entity id to the iframe controller, that way I could load the media entity data. In my case, I added a custom boolean field to my Remote Video media type to determine whether I should replace youtube.com with youtube-nocookie.com or not.

use Drupal\media\IFrameMarkup;

/**
 * Implements hook_preprocess_media_oembed_iframe().
 */
function mymodule_updates_preprocess_media_oembed_iframe(array &$variables) {
  if (strpos((string) $variables['media'], 'youtube.com') !== FALSE) {
    $entity_id = $variables['entity_id'];
    $remote_video = \Drupal::entityTypeManager()->getStorage('media')->load($entity_id);
    $no_cookies = $remote_video->get('field_nocookies')->value;
    if ($no_cookies) {
      $variables['media'] = IFrameMarkup::create(str_replace('youtube.com/', 'youtube-nocookie.com/', $variables['media']));
    }
  }
}
joachim namyslo’s picture

Dear Community, It's a bit of a shame that we're not pursuing this issue further. We now have Klaro! and can provide decent privacy notices, but our videos are still being loaded from youtube.com. Could we perhaps address this issue in soon and simply offer Youtube Nocookie as a third alternative Oembed provider for Drupal Core?

That would be so nice and simple. The easiest solution for users would be if they could simply paste normal URLs from YouTube Studio and the Oembed provider would have a checkbox in the formatter options to choose whether to use the normal YouTube version or no-cookie. I mean, if we're implementing data protection in Drupal, we might as well do it right, right?

Version: 11.x-dev » main

Drupal core is now using the main branch as the primary development branch. New developments and disruptive changes should now be targeted to the main branch.

Read more in the announcement.

ressa’s picture

I agree @joachim namyslo, easily configuring Drupal to respect privacy directly in Drupal core would be ideal.