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.

‼ 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.

Aktivieren Sie JavaScript um das Video zu sehen.
https://www.youtube.com/watch?v=b4810hS8weQ

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://www.dobschat.de/wp-content/uploads/2018/04/Ups-da-ist-was-schief-gegangen.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://www.dobschat.de/wp-content/uploads/2018/04/Ups-da-ist-was-schief-gegangen.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.

Zur Info Zur Info
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…

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.

Aktivieren Sie JavaScript um das Video zu sehen.
https://www.youtube.com/watch?v=b4810hS8weQ

 

Ähnliche Artikel

Neues Plugin: D64 LSR-Stopper Man sollte ja mit PlugIns sparsam sein bei WordPress, aber dieses PlugIn sollte jeder installieren: D64 LSR-Stopper (mehr Infos). Ja, es geht um bzw...
Von Serendipity zu WordPress Für den Fall, dass auch mal jemand ein Weblog von Serendipity nach WordPress umstellen will: es gibt da ein Import-Plugin, das auch einwandfrei f...
WordPress und Datenschutz: Emojis und Gravatare Da schaute ich so intensiv auf die diversen Plugins und habe fast übersehen, dass WordPress schon von Haus aus Fremdinhalte einbindet. Also unter Umst...

Schreibe einen Kommentar

Pflichtfelder sind mit * markiert.