videojs / videojs-youtube

YouTube playback technology for Video.js
1.13k stars 549 forks source link

GDPR compliance #499

Open lunanigra opened 6 years ago

lunanigra commented 6 years ago

Hi and thanks for your video player framework.

Did you already make some thoughts about GDPR compliance? There shouldn't be any request to www.youtube.com, instead use www.youtube-nocookie.com.

This is just a guess, perhaps you have a better approach... https://easyrechtssicher.de/youtube-videos-dsgvo-konform-einbinden

Any feedback welcome :)

mi-roh commented 6 years ago

Hi, I had the same problem. As fare as I know nocookie won't work in this case because the youtube-Api is only served by youtube.com and not by youtube-nocookie.com.

I wrote a videojs plugin for my case (using browserify and jquery-context) taking benifits of the commonJS-infastructure to load the videojs-youtube library after agreement of the user. As far as I know that should be GDPR-compatible.

Meybe it fits your case to, otherwise be inspired. https://github.com/mi-roh/videojs-youtubeAgreement

gkatsev commented 6 years ago

We did recently merge an option called enablePrivacyEnhancedMode that will use youtube-nocookie.com rather than youtube.com See #497. This is released in version 2.5.0. Please let us know if it works for you.

lunanigra commented 6 years ago

Hi @gkatsev, many thanks for the update.

We tried it; but based on the missing docs it's not really clear where to add the new parameter. What we see so far... Whenever we include the lib "require('videojs-youtube');" a request is done to youtube.com. Ideally this should be avoided.

mi-roh commented 6 years ago

That works like a charme. Thanks a lot.

@lunanigra: It is an option for youtube. You have to set it similar to the Youtube Options. f.e.

<video
  id="vid1"
  class="video-js vjs-default-skin"
  controls
  autoplay
  width="640" height="264"
  data-setup='{ "techOrder": ["youtube"], "sources": [{ "type": "video/youtube", "src": "https://www.youtube.com/watch?v=xjS6SftYQaQ"}], "youtube": { "enablePrivacyEnhancedMode": "true" } }'
>
</video>
lunanigra commented 6 years ago

Maybe the reason is that we do not use video tag. Video os loaded via script.

I tried it by add enablePrivacyEnhancedMode to the param list; but this did not work.

But if it works for you; it might be just something small...

window.videojs = require('video.js');
require('videojs-youtube');

// initialize videojs
videojs(
    'component-header-video-' + index,
    { aspectRatio: '16:9', nativeControlsForTouch: true, enablePrivacyEnhancedMode: true },
    function() {
        videoPlayer = this;
        $(window).on('scroll', function() {
            let top = $(window).scrollTop();
            let divBottom = $this.offset().top + $this.outerHeight();
            if (top > divBottom) {
                if (!videoPlayer.paused()) {
                    videoPlayer.pause();
                }
            }
        });

        // on end
        this.on('ended', function() {
            $posterImage.velocity('fadeIn');
            $video.hide();
            $playButton.velocity('fadeIn');
        });

        // on pause
        this.on('pause', function() {
            $playButton.velocity('fadeIn');
        });

        // on play
        this.on('play', function() {
            $playButton.velocity('fadeOut');
        });

        // show play button
        $playButton.velocity('fadeIn').on('click', function() {
            // hide poster image
            $posterImage.velocity('fadeOut');
            // make video visible
            $video.velocity('fadeIn');
            // start video
            videoPlayer.play();
        });
    }
);
brandonocasey commented 6 years ago

@lunanigra Not sure if there is another issue but you will have to make enablePrivacyEnhancedMode a key inside of a youtube object. So you options would go from this:

{ aspectRatio: '16:9', nativeControlsForTouch: true, enablePrivacyEnhancedMode: true }

To This:

{ aspectRatio: '16:9', nativeControlsForTouch: true, youtube: {enablePrivacyEnhancedMode: true }}

I also think you may need to add a techOrder option to your options so that the youtube tech is actually used (you can ignore this last one if you don't need it).

So you final list of options would be (if you need to change techOrder):

{
  techOrder: ['youtube']
  aspectRatio: '16:9', 
  nativeControlsForTouch: true,
  youtube: {enablePrivacyEnhancedMode: true }
}
lunanigra commented 6 years ago

Hi, thanks, looks better. The video itself is now loaded from www.youtube-nocookie.com.

But there is still one request to www.youtube.com (https://www.youtube.com/iframe_api). Can this also be changes to https://www.youtube-nocookie.com/iframe_api?

gkatsev commented 6 years ago

I noticed that the content of https://www.youtube.com/iframe_api and https://www.youtube-nocookie.com/iframe_api is the same, so, we could probably just make that switch for everyone? The way things are set up currently, options aren't available when we load in the iframe api.

lunanigra commented 6 years ago

@gkatsev if there is no other way of controlling the loading (of the iframe API) it sounds feasible using https://www.youtube-nocookie.com/iframe_api always.

tilt-me commented 5 years ago

@gkatsev right now https://www.youtube-nocookie.com/iframe_api returns a 404, while https://www.youtube.com/iframe_api returns a js file: am I missing something? Seems to me they are not interchangeable :disappointed:

gkatsev commented 5 years ago

Looks like youtube-nocookie doesn't return an iframe_api anymore (not sure why) but embeds still work. So, we may need to revert the change to the iframe_api but we can still embed via youtube-nocookie.

interone-ms commented 5 years ago

At the moment, Youtube.js automatically fires off an AJAX request upon module import with no way to prevent this - as soon as the webpack bundle JS is loaded, the request is made. This is unacceptable under GDPR as the user has no way to explicitly authorize this request and I as a developer cannot prevent it.

But as the load in src/Youtube.js#L782 is asynchronous anyway, it would be possible to convert this call only upon external interfaced action...