WordPress & Datenschutz: YouTube wirklich sauber eingebunden

Ich muss dann doch noch mal zu YouTube zurückkommen, mir wurde nach dem letzten Beitrag das Plugin WP YouTube Lyte empfohlen. Dieses Plugin würde eine Zwei-Klick-Lösung bringen und dabei nicht das Layout zerschiessen. Also habe ich es mal getestet und es löst das Problem der externen Zugriffe fast, aber diesen letzten Zugriff kann man mit ein bisschen Code in der functions.php los werden – oder alternativ mit noch weniger Code das bereits erwähnte Embed videos and respect privacy optimieren.

info

Bitte beachten!

Ich bin kein Jurist und dieser Beitrag hier ist auch keine Rechtsberatung. Mich reizt – hier ist die DSGVO nur ein Anlass – einfach die Herausforderung, meine Site so zu verändern, dass sie maximal datensparsam ist, sowohl was die Speicherung auf der Site selbst betrifft, als auch, was die echte (und die vermeintliche) Weitergabe von persönlichen Daten angeht. Alle Informationen in diesem und den anderen Beiträgen geben meine Meinung und meinen jeweils aktuellen Wissensstand wieder und werden ohne jeden Anspruch an Aktualität und Korrektheit hier publiziert. Verlasst euch nicht auf mich, denkt bitte immer selbst ?

WP YouTube Lyte

Das Plugin stammt noch aus einer Zeit, in der die DSGVO kein Thema war, hat aber letzten Monat ein Update bekommen. Das Plugin ersetzt die eingebetten YouTube-Videos durch das Vorschaubild und lädt das Video und den Player erst nach em Klick darauf. Da das Video dann mit Autoplay nachgeladen wird, bemerkt man als Nutzer keinen Unterschied. Damit sind die externen Zugriffe auf YouTube für Seitenbesucher zwar nicht weg, aber schon mal deutlich reduziert.

YouTube

Mit dem Laden des Videos akzeptieren Sie die Datenschutzerklärung von YouTube.
Mehr erfahren

Video laden

Leider muss man sich bei WP YouTube Lyte für eine feste Videogröße entscheiden, was aber immerhin erlaubt, eine solche zu wählen, die in das eigene Theme passt. Nicht optimal, aber besser gelöst als bei Embed videos and respect privacy. Wäre da nicht dieser eine letzte Zugriff auf die Server von YouTube…

Ein Blick in das Plugin

Ich habe mir das Plugin dann mal angeschaut und siehe da: Es gibt dort eine Datei namens lyte_helper.php_example, die ein paar Beispiele enthält, wie man die vom Plugin bereit gestellten Schnittstellen nutzen kann, um ein paar individuelle Anpassungen vorzunehmen. Und dort findet sich unter anderem folgendes Stückchen Code:

/** function to override thumbnail used for a video */
// add_filter('lyte_match_thumburl','lyte_my_own_thumburl');
function lyte_my_own_thumburl($thumb) {
 return "http://images.vrt.be/mobile320/2014/08/05/8570f3aa-1c9e-11e4-b923-00163edf75b7.jpg";
}

Und das ist genau das, was man braucht, um diesen letzten Request Richtung YouTube-Server noch abzustellen.

Ein kleiner, schmutziger Hack

Über den den Filter lyte_match_thumburl können wir also – wie in dem Beispiel – die Vorschau durch ein anderes Bild ersetzen. Das könnte eine simple Grafik sein, in der kurz steht, dass aus Gründen des Datenschutzes das eigentliche Video erst nach einem Klick geladen wird.

Aber das wäre ja doch irgendwie langweilig. Man könnte doch auch einfach an dieser Stelle das Vorschaubild von den YouTube-Servern holen und dann wiederum vom eigenen Server an den Nutzer schicken. Ich habe dann mal was für meine functions.php zusammengehackt:

/** function to override thumbnail used for a video */
add_filter('lyte_match_thumburl','lyte_my_own_thumburl');
function lyte_my_own_thumburl($thumb) {
		$cache_dir	= "youtubethumbs"; // Subdirectory für die lokalen Thumbs
		$upload_dir   = wp_upload_dir(); // WordPress Upload Verzeichnis abfragen
		if ( ! empty( $upload_dir['basedir'] ) ) {
			$dirname = $upload_dir['basedir'].'/'.$cache_dir;
			if ( ! file_exists( $dirname ) ) {
		        wp_mkdir_p( $dirname );
			}
			$url = parse_url($thumb);
			if ( empty( $url['scheme'])) {
				$thumb = "https:".$thumb;
			}

			$img = $upload_dir['basedir']."/".$cache_dir."/".hash(sha256, $thumb).".".pathinfo($thumb, PATHINFO_EXTENSION);
			
			if ( ! file_exists( $img ) ) {
				if ($data = file_get_contents($thumb)) {
					file_put_contents($img, $data);
					$imgurl = $upload_dir['baseurl']."/".$cache_dir."/".hash(sha256, $thumb).".".pathinfo($thumb, PATHINFO_EXTENSION);
				} else {
					$imgurl = "https://dobschat.io/wp-content/uploads/2018/04/Ups-da-ist-was-schief-gegangen-1.jpg";
				}
			} else {
				$imgurl = $upload_dir['baseurl']."/".$cache_dir."/".hash(sha256, $thumb).".".pathinfo($thumb, PATHINFO_EXTENSION);
			}
			
			$thumb = $imgurl;

		} else {
			// basedir ist empty, ist wohl was schief gelaufen Fehlerbild zurück, das geht sicher besser :) 
			$thumb = "https://dobschat.io/wp-content/uploads/2018/04/Ups-da-ist-was-schief-gegangen-1.jpg";
		}
		
        return $thumb;
}

Ja, auf die Schnelle zusammengetippt und da ist eine Menge Verbesserungspotential drin – tut Euch keinen Zwang an ? Auf die Schnelle erklärt, was das Ding macht: Es erhält beim Aufruf die Adresse des YouTube-Vorschaubildes, es wird geprüft, ob das Verzeichnis für den lokalen Cache existiert (ich lege die Bilder in das Unterverzeichnis youtubethumbs im Upload-Verzeichnis von WordPress), checke, ob die übergebene Adresse auch ein Protokoll enthält, denn manchmal beginnen die Adressen erst mit dem // – was für Browser absolut okay ist, für meine Zwecke aber nicht ausreichend ist und ergänze ggf. noch ein https vorne. Dann bilde ich einen sha256-Hash über die Adresse, den ich als Dateinamen für meine lokale Kopie des Bildes nutze, schaue, ob ich das Bild schon auf meinem Server habe und wenn nicht, dann hole ich es, speichere es und gebe die entsprechende Adresse zurück. Im Fehlerfall gibt es ein vorbereitetes Fehlerbild.

Wie gesagt, schnell zusammen getippert und da könnte man eine Menge verbessern und es auch eleganter machen. Zum Beispiel leere ich den Cache nicht automatisch, wobei der ja auch nicht so oft geleert werden muss, das kann ich auch erstmal manuell dann und wann machen. Natürlich könnte man die Vorschaugrafik in dem Fall auch gleich noch verändern, zum Beispiel eine Grafik mit einem erklärenden Text drüber legen. Auch gibt es noch weitere Filter und einen Action Hook:

available filter hooks: lyte_settings, lyte_content_preparse, lyte_match_preparse_fragment, lyte_match_postparse_template, lyte_content_postparse, lyte_css, lyte_docaptions, lyte_match_thumburl
available action hooks; lyte_actionsfilters

Da lässt sich sicher noch ein bisschen was an der Ausgabe machen. Man könnte auch schauen, ob sich nicht Teile von WP YouTube Lyte und Embed videos and respect privacy miteinander zu einem neuen Plugin kombinieren lassen, das dann alle Wünsche erfüllt.

[su_service title=”Zur Info” icon=”https://dobschat.io/wp-content/uploads/2018/04/info-icon-1.png” icon_color=”#1d399d”]Ich hatte den Beitrag bis zu dieser Stelle geschrieben, dann fiel mir ein, dass Embed videos and respect privacy doch gar nicht so groß war und ich es mir doch mal genauer anschauen könnte und danach kam dann der folgende Text hier dazu…[/su_service]

Embed videos and respect privacy

Das Plugin ist sehr übersichtlich, was gut ist. Als erstes fiel mir der deutlich elegantere Weg für den Cache der Vorschaubilder auf – okay, das Ding im Plugin-Ordner zu platzieren ist vielleicht etwas ungeschickt, in diesem Fall aber zu verschmerzen. Kann gar nicht schaden, wenn mit jedem Plugin-Update der Cache geleert wird und vom Sitebetreiber wieder aktiviert werden muss – auf die Weise schaut wenigstens mal jemand danach.

Danach file mir der Tippfehler in dem Hinweistext auf, aber das hatte ich auf später verschoben, denn was mich ja am meisten störte war die Tatsache, dass die YouTube-Videos zu breit waren. Ein Blick in den Source des Plugins machte klar: Da waren die Standardwerte einfach falsch gesetzt. Also wieder in die functions.php, denn auch dafür gibt es eine simple Lösung per Hook, man muss sie nur kennen oder eben finden:

function dob_embed_defaults($embed_size){
 $embed_size['width'] = 680;
 $embed_size['height'] = 473;
 return $embed_size;
}
add_filter('embed_defaults', 'dob_embed_defaults');

Übrigens: Das Prefix dob_ benutze ich in der functions.php hier für alle Funktionen, die ich selbst zusammen schraube, damit vermeide ich mit hinreichender Wahrscheinlichkeit Überschneidungen mit Funktionen in Plugins, Themes und dem WordPress Core. Damit setze ich also die Standardgröße für Embeds in WordPress auf 680×473 Pixel. Noch nicht wirklich responsive, aber ein erster Schritt.

Wo ich gerade da war, dacht ich mir, dass ein Autoplay doch ganz nett wäre, damit das Video nach dem Klick sofort startet. Dazu muss nur der Parameter autoplay=1 an die Adresse des Embeds angehängt werden und natürlich Autoplay im Browser erlaubt sein (fragt nicht, wie viele wertvolle Minuten ich mit der Fehlersuche vergeudet habe, weil mein Safari Autoplay in meinem eigenen Weblog verboten hat). Das geht über eine Filter auf embed_oembed_html und für alle Fälle, falls ich doch mal wieder Jetpack nutzen sollte auch gleich auf video_embed_html. Bevor ich jetzt den Code-Schnipsel hier poste, noch etwas Text zu den weiteren Änderungen, die ich danach gemacht habe. Würde ich jeden Zwischenschritt hier rein kopieren, wäre es etwas viel ?

Mir ist dann nämlich noch ein Tippfehler in dem Infotext aufgefallen, außerdem hätte ich den gerne etwas ausführlicher gehabt. Das kann ich in der gleichen Funktion erledigen, ich muss nur dafür sorgen, dass meine Funktion erst nach der des Plugins ausgeführt wird. Da das Plugin den Filter mit der Priorität 11 aufruft, nehme ich die Priorität 12 und ersetze per str_replace den entsprechenden Text. Das ist aber meines Erachtens die denkbar schlechteste Lösung, eigentlich keine Lösung, sondern nur ein Behelf. Besser wäre es, wenn dieser Text im WordPress-Backend konfigurierbar wäre und noch besser, wenn I18n verwendet würde, das Tool der Wahl für Übersetzungen in WordPress. Schließlich betrifft das Thema Datenschutz ja nicht nur deutschsprachige Nutzer. Aber dazu müsste ich das Plugin selbst ändern und das will ich ja vermeiden (wegen Updates).

Und weil ich gerade dabei war, habe ich die Ausgabe noch in ein eigenes DIV verpackt, damit ich es anschließend leichter per CSS etwas anders formatieren kann. Denn spezifischere Regeln im CSS haben Vorrang: Während das Plugin in diesem speziellen Fall also Regeln für die Klasse .video-wrapped und .video-wrapped .video-wrapped-play definiert, definiere ich die dann für .dob-embed-container .video-wrapped und .dob-embed-container .video-wrapped .video-wrapped-play und überschreibe so die jeweiligen CSS-Anweisungen des Plugins.

Vor allem ging es mir um einen schwarzen, aber leicht transparenten Hintergrund über dem Vorschaubild und unter dem Infotext – der besseren Lesbarkeit wegen. Und wenn ich meinem DIV außen rum noch die maximale Breite von 100% verpasse, dann ist das ganze Ding beinahe schon responsive. Aber mit diesen Ergänzungen habe ich das Plugin soweit, dass ich es nutzen kann und will – ohne am Plugin selbst etwas zu ändern. Aber spätestens wenn es darum geht, diese Funktionalität auf weitere Embeds auszuweiten – denn die Mechanik funktioniert grundsätzlich mit allen Embeds (Vimeo, Twitter, externe WordPressen…) – geht es nicht mehr ohne Änderungen am Plugin selbst (oder ein neues Plugin).

Hier meine Ergänzung der functions.php in meinem Child Theme:

function dob_embed_autoplay($code){
    if(strpos($code, 'youtu.be') !== false || strpos($code, 'youtube.com') !== false || strpos($code, 'youtube-nocookie.com') !== false){
        $return = preg_replace('@embed/([^"&]*)@', 'embed/$1&rel=0&autoplay=1', $code);
        $return = str_replace('Das Video wird von Youtube eingebettet abespielt.', 'Das Video wird nach dem Klick von Youtube geladen und abgespielt, dazu baut Dein Browser eine direkte Verbindung zu den YouTube-Servern auf. ', $return);
        return '<div class="dob-embed-container">' . $return . '</div>';
    }
    return '<div class="dob-embed-container">' . $code . '</div>';
}

add_filter( 'embed_oembed_html', 'dob_embed_autoplay', 12);
add_filter( 'video_embed_html', 'dob_embed_autoplay', 12 ); // Jetpack

Und meine CSS-Ergänzungen:

.dob-embed-container .video-wrapped .video-wrapped-play {
	background: rgba(0,0,0,0.7);
	height: 100%;
	width: 100%;
	top: 0;
	padding-top: 25%;
}
.dob-embed-container .video-wrapped .video-wrapped-play:before {
	top: 24%;
	margin-left: -15px;
}
.dob-embed-container .video-wrapped .video-wrapped-play .small {
	padding-left: 20px;
	padding-right: 20px;
}
.dob-embed-container, .dob-embed-container .video-wrapped {
	max-width: 100%;
}

Jetzt aber wirklich „Yay“: YouTube-Videos werden nun so datensparsam wie nur möglich eingebunden, die IP-Adresse eines Nutzers wird erst dann an Google übermittelt, wenn dieser auch wirklich ein Video anschaut, nicht schon beim Aufruf meiner Seite.

YouTube

Mit dem Laden des Videos akzeptieren Sie die Datenschutzerklärung von YouTube.
Mehr erfahren

Video laden

[su_box title=”Mehr zum Thema” box_color=”#394972″][su_menu name=”Datenschutz” class=”dobschatcontentmenu”][/su_box]

16 Comments

Sehr hilfreich! Vielen Dank!

Auf Github gibt es eine neuere Version des Plugins, die Hinweise im Vorschaubild können damit in den Einstellungen des Plugins vorgenommen werden. Leider ist die neue Version nicht/noch nicht? über WordPress verfügbar.

Haben das Plugin auch auf unserem Blog im Einsatz. Sind aber mit der Optik noch nicht zufrieden.

Funktionieren deine Anpassungen auch, wenn Videos über den [embed] Shortcode eingebunden werden? Ich möchte die Videos gerne irgendwie responsiv eingebunden bekommen.

Viele Grüße,
Chris

Carsten Dobschat

Ja, ich habe die neuere Version auch schon hier im Einsatz – und immer noch auf der „muss ich verbloggen“-Liste :/
Hier der Link für alle Mitleser:
https://github.com/michaelzangl/wp-video-embed-privacy

Was genau meinst Du mit der Frage, ob die Anpassungen auch bei per Shortcode eingebundenen Videos funktionieren? Also grundsätzlich ja, sie setzen ja an der Stelle an, aber ohne das entsprechende Plugin ergeben sie nicht viel Sinn.

Ich musste die Videos mit [embed]linkzumvideo[/embed] einfügen, denn wenn ich nur den Link nehme, um ein Video einzubetten funktioniert das bei mir nicht (vermutlich aufgrund der Nutzung vom WPBakery PageBuilder). Daher die Frage, ob deine Anpassungen auch greifen, wenn ich die Videos so einbette.

“add_filter( ’embed_oembed_html’,” bezieht sich ja auf per Link eingebettete Videos, soweit ich das richtig verstanden habe.

“add_filter( ‘video_embed_html’,” könnte vielleicht mit dem Shortcode [embed] funktionieren.

Bin leider nicht so CSS-bewandert. 😉

Ich hoffe, ich konnte mich verständlich machen :).

Viele Grüße! Chris

Carsten Dobschat

In dem Fall ist es kein CSS, sondern PHP und die beiden Filter sind nötig für Fälle, in denen Jetpack eingesetzt wird, das biegt da nämlich ein bisschen was um.
Grundsätzlich sind beide Formen des Einbindens in WordPress gleich, ob Link oder per [embed], dahinter stehen die gleichen Funktionen. Problematisch wird es nur, wenn – zum Beispiel ein Sitbuilder oder ein anderes Plugin – hier irgendwo früher eingreift und eben zum Beispiel die Links „abfängt“ und selbst verarbeitet ? Diese Filter kann ja jedes Plugin und Theme nutzen, wenn also ein Plugin schon vor dem Privacy-Plugin die Links „abgreift“, dann kann das nicht anspringen und meine Änderungen der Ausgabe greifen dann auch nicht mehr.

Verstehe. 🙂
Jetpack bin ich aufgrund der DSGVO gerade losgeworden ;). Was mein Theme, der PageBuilder und meine anderen Plugins so machen ist natürlich eine gute Frage.
Da hilft nur eins: Probieren.
Ich geb Bescheid, ob’s geklappt hat oder nicht. Vielleicht kommt ja auch noch ein Update des Plugins an sich, dass hier nachbessert.
VG

Gedenkliste und andere Nebeneffekte › Dobschat

[…] Inhalt erst nach einem Klick lädt. Sehr praktisch, zusammen mit WP Video Embed Privacy (hier hatte ich etwas über eine ältere Version geschrieben) ist dahingehend so ziemlich alles […]

Update fuer dich,
WP Youtube Lyte kann nun auch die Vorschaubilder vom eigenen Server bereitstellen. Sprich, es wird bei Beitragserstellung das Vorschaubild “lokal” gespeichert. Der Zuriff auf Youtube ist damit auch unterbunden.

Danke für die tolle Beschreibung. Ich habe das Problem, dass der Hinweis beim Aufruf der Seite immer horizontal läuft bis ich scrolle. Und in der mobilen Ansicht hartnäckig die Seite stört. Habe noch keine Lösung…..

Danke…. Habe das YouTube Vorschaubild lokal zwischengespeichert, wie du hier gesagt hast und nun ein netten Brief bekommen. Darf nun 800€ wegen einem Urheberrechtsverstoß bezahlen…

Also eines vorweg: Ich habe nicht umsonst oben deutlich geschrieben, dass ich eben kein Jurist bin und man sich im Zweifel eben nicht auf mich und meinen Wissenstand verlassen soll. Aber lassen wir das, kommen wir zu deinem Problem: Als erstes würde ich einen Anwalt aufsuchen, der auf das Thema spezialisiert ist, Hilfe bei der Auswahl gibt es in diesem Beitrag: https://www.e-recht24.de/rechtsanwalt.html
Und hier ganz allgemein Handlungsempfehlungen in so einem Fall: https://www.abmahnung.org/was-tun/

Eine konkrete Empfehlung kann ich dir da leider nicht geben, da ich zu wenig über den Fall weiß und ich weiß auch nicht, ob du lieber einen Anwalt vor Ort willst oder ob dir Entfernung da egal ist. Marcus Dury kenne ich von SaarCamps, der würde wahrscheinlich in so einem Fall auch zu den Ersten gehöre, die ich mal fragen würde: https://www.dury.de Oder du schaust mal bei https://www.anwalt.de – die Anwälte dort werden ja auch von Mandanten bewertet.

Aber mich würden die Umstände der Abmahnung durchaus interessieren, gerne auch per Mail, das muss man ja nicht offen durch die Welt teilen, so lange die Sache noch läuft: Hast du ein eigenes Video oder ein fremdes eingebunden? In eine rein private Site (also ohne Werbung usw.) oder ist es eine irgendwie kommerzielle Site (Werbung, Shop…)? Wie war der Zusammenhang zu dem Video? Das scheint ja alles bei solchen Abmahnungen eine Rolle zu spielen: https://drschwenke.de/sharing-urheberrecht-abmahnung-vorschaubild-facebook-risikoeinschaetzung-checkliste/

Und wer hat dich abgemahnt? Der Uploader des Videos oder hat der Uploader selbst einen Urheberrechtsverstoß beim Upload begangen, den du dann quasi durch das Einbinden und das Zwischenspeichern des Vorschaubilds mitgenommen hast?

Ist das verlinkte dein Fall? Dann wäre es ja mal interessant, auf welcher Grundlage es dann zu der 800€-Zahlung kam. Sind das deine Anwaltsgebühren? Ist das das Geld für KSP/dpa? War das eine Gerichtsentscheidung oder eine außergerichtliche Einigung? Ging das alles vor Gericht? Wurde dort dann die Frage erörtert, inwiefern eine Funktion, die nur zum Zwischenspeichern dient, um den Anforderungen des Datenschutzes gerecht zu werden, überhaupt eine Urheberrechtsverletzung sein kann? Bei Kläner gibt es ja offenbar keinen Fortsetzungsbeitrag zu der Sache…

Ja, der Fall ist identisch. Schadenersatz, Dokumentationskosten, Zinsen, Rechtsanwaltsvergütung, Auslagenpauschale, …

Gibt es dazu irgendwas im Netz mit mehr Infos? Also konkret auf den Fall „YouTube-Vorschaubild“ bezogen?