skip to main content.

in my last post, i wrote about how to maximize privacy for your site’s visitor. in the meantime, i programmed a mechanism which maximizes privacy when embedding youtube or vimeo videos. the idea is simple: i embed only a picture, and use javascript to replace the picture with the video player. in case javascript is disabled, the image has a link to the video, and in case javascript is there and the image is replaced by the video player, i enable autostart for the video. for the casual user, the result looks similar to just embedding the video, but the difference is that youtube or vimeo only get the visitor’s information if he wants to watch the video. here is an example:

[[for legal reasons, i do not want to include youtube videos here anymore. please click on this link to watch the video at youtube.]]

now, how do i do this? to retrieve the image, i use a php script so that the user will not interact directly with youtube or vimeo. the script obtains the url for the picture, retrieves the picture, and delivers it to the user. here’s the script:

 1 <?php
 2 // Tests a file name for being valid
 3 function isValidID($id)
 4 {
 5     return preg_match('#^([a-zA-Z0-9-_]+)$#', $id) == 1;
 6 }
 7 
 8 // Checks if the source is valid
 9 function isValidSource($source)
10 {
11     return ($source == 'youtube') || ($source == 'vimeo');
12 }
13 
14 $id = $_GET['id'];
15 $source = $_GET['source'];
16 
17 if (isValidID($id) && isValidSource($source))
18 {
19     // Find out URL
20     if ($source == 'youtube')
21     {
22         // Youtube is easy...
23         $url = "http://img.youtube.com/vi/$id/0.jpg";
24     }
25     if ($source == 'vimeo')
26     {
27         $url = "http://vimeo.com/api/v2/video/$id.php";
28         $content = @file_get_contents($url); // avoid error message on 404
29         if ($content)
30         {
31             $content = unserialize($content);
32             $url = $content[0]['thumbnail_large'];
33         }
34         else
35             $url = false;
36     }
37 }
38 else
39     $url = false;
40 
41 // Retrieve picture
42 if ($url)
43     $content = @file_get_contents($url); // avoid error message on 404
44 else
45     $content = false;
46 
47 // Send picture, or print 404
48 if ($content)
49 {
50     // Deliver file
51     header('Status: 200 OK', true, 200);
52     header('HTTP/1.0 200 OK', true, 200);
53     header('Content-Type: image/jpeg');
54     header('Content-Transfer-Encoding: binary');
55     header('Content-Length: ' . strlen($content));
56     echo $content;
57     exit(); 
58 }
59 else
60 {
61     // This results in a 404
62     require_once('index.php');
63 }

note that the 404 display at the end works thanks to wordpress. if you have the script in another directory as your wordpress installation, or you are not using wordpress at all, you have to modify that part. just replace the require_once line by

1     header('Status: 404 File Not Found', true, 404);
2     header('HTTP/1.0 404 File Not Found', true, 404);
3     echo '<html><body>Error: invalid arguments or cannot retrieve picture.</body></html>';

or something similar.

ok. so let us assume that you put the script somewhere on the server, say at /tubeimage.php as i did. then, you need to insert the following javascript code into the header of your html files. in case you use wordpress, you can write a plugin to do that for you (i did that), or modify the wp-content/themes/yourtheme/header.php file, where you replace yourtheme by the name of the theme you’re using. add the following lines:

 1 <script type="text/javascript">//<![CDATA[
 2 function youtubeClick(id, w, h)
 3 {
 4     elt = document.getElementById('youtube-' + id);
 5     elt.innerHTML = '<object class="youtube-object type="application/x-shockwave-flash" data="http://www.youtube-nocookie.com/v/' + id + '&amp;rel=0&amp;border=0&amp;autoplay=1" width="' + w + '" height="' + h + '"><param name="movie" value="http://www.youtube-nocookie.com/v/' + id + '&amp;rel=0&amp;border=0&amp;autoplay=1" /></object></div>';
 6     elt.onclick = null;
 7 }
 8 function vimeoClick(id, w, h)
 9 {
10     elt = document.getElementById('vimeo-' + id);
11     elt.innerHTML = '<object class="youtube-object" type="application/x-shockwave-flash" data="http://vimeo.com/moogaloop.swf?clip_id=' + id + '&amp;server=vimeo.com&amp;show_title=1&amp;show_byline=1&amp;show_portrait=1&amp;color=00ADEF&amp;fullscreen=1&amp;autoplay=1&amp;loop=0" width="' + w + '" height="' + h + '"><param name="movie" value="http://vimeo.com/moogaloop.swf?clip_id=' + id + '&amp;server=vimeo.com&amp;show_title=1&amp;show_byline=1&amp;show_portrait=1&amp;color=00ADEF&amp;fullscreen=1&amp;autoplay=1&amp;loop=0"/></object>';
12     elt.onclick = null;
13 }
14 //]]></script>

note that the <![CDATA[...]] is the xhtml way of hiding javascript; if you’re using plain old html, you need to use <!– … –>.

now, you can add youtube or vimeo videos to your page as follows. for example, the video above was embedded as follows: <span id="vimeo-24456787" onClick="vimeoClick('24456787', 425, 341)"><a href="http://vimeo.com/24456787" rel="external" onclick="return false;"><img src="/tubeimage.php?id=24456787&amp;source=vimeo" width="425" height="341" /></a></span> note that 24456787 is the id of the vimeo video (and appears at four places in this snippet), and the player has size 425x341 (appears at two places in this snippet). for youtube videos, you write <span id="youtube-LFtSRR0xFec" onClick="youtubeClick('LFtSRR0xFec', 425, 341)"><a href=http://www.youtube.com/watch%3Fv=LFtSRR0xFec" rel="external" onclick="return false;"><img src="/tubeimage.php?id=LFtSRR0xFec&amp;source=youtube" width="425" height="341" /></a></span> here, LFtSRR0xFec is the id of the youtube video (and appears at four places in this snippet), and the player has size 425x341 (appears at two places in this snippet). if you are using wordpress, it is a good idea to create a plugin which automatically generates all the necessary code, so you can just write something like [youtube id="LFtSRR0xFec" width="425" height="341"] in your posts.

comments.

no comments.