About half a year ago I’ve changed how I embed videos here on bram.us. No, I’m not embedding responsively but I’m embedding Vimeo and YouTube clips along with its poster frame (= the image you see before the video starts playing).
Doing this will force Facebook and Google+ to show that image – and not “the first image it finds on the page”, which could be totally irrelevant – whenever someone shares a link to a video posted on bram.us. For the user visiting bram.us via his browser nothing has changed: only the video is shown.
Sharing a recent bram.us video post containing a poster image (left) vs. Sharing an older bram.us video post containing the default youtube embed code (right)
But how can one make an image only appear for Facebook and the like and not for the user visiting? Well, the trick is simple: just exploit the fact that browsers support iframes, and scrapers don’t. By putting the <img>
containing the poster frame inside the <iframe>
one can achieve just that:
- The browser will show the
<iframe>
and ingore the<img>
inside it - Scrapers will look for an
<img>
tag and will find one, albeit inside the<iframe>
but that is of no issue.
The code is something like this:
<iframe width="560" height="315" src="https://www.youtube.com/embed/xZY43QSx3Fk" frameborder="0" allowfullscreen>
<img src="https://www.example.org/thumbnail/of/the/video.jpg" />
</iframe>
Now we only need to find out how to get the poster image, in a no-hassle way.
Socially embedding YouTube videos
Using a Google Search Coupon I learned that YouTube offers direct links to poster images. The URL is always in the format of https://img.youtube.com/vi/<videoid>/maxresdefault.jpg
(Replace <videoid>
with the actual id of the video).
For the YouTube video https://www.youtube.com/watch?v=dCzI521sgqE the poster image can be found at https://img.youtube.com/vi/dCzI521sgqE/maxresdefault.jpg
The embed code will become this:
<iframe width="560" height="315" src="https://www.youtube.com/embed/dCzI521sgqE" frameborder="0" allowfullscreen>
<img src="https://img.youtube.com/vi/dCzI521sgqE/maxresdefault.jpg" />
</iframe>
💁♂️ Not all YouTube videos have the maxresdefault.jpg
image. In that case try fetching the file named 0.jpg
instead.
Socially embedding Vimeo videos
Alas Vimeo doesn’t offer direct links to poster images. You can however get to know the poster image by making an API call and extracting the needed value from it. Enter an intermediate PHP script which does the job:
<?php
/**
* Vimeo Thumbnail Script - Gets the poster frame for a Vimeo video id.
* @author Bramus Van Damme
*
* Example Request: vimeothumb.php?id=83936766
*/
// Perform a GET request to a given URL.
// Uses `allow_url_fopen` if supported, or curl as a fallback.
function get($url) {
if (ini_get('allow_url_fopen')) return file_get_contents($url);
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$result = curl_exec($ch);
curl_close($ch);
return $result;
}
// Extract ID from the URL
$id = isset($_GET['id']) ? $_GET['id'] : 0;
// Request the image hash with Vimeo
if ($id > 0) $hash = unserialize(get('http://vimeo.com/api/v2/video/' . $id . '.php'));
// Thumbnail found
if ($hash && isset($hash[0]) && isset($hash[0]['thumbnail_large'])) {
header('Content-type: image/jpeg');
echo get($hash[0]['thumbnail_large']);
}
// No thumbnail found: return a valid, but blank image
else {
header('Cache-Control: no-cache');
header('Content-type: image/gif');
header('Content-length: 43');
echo base64_decode('R0lGODlhAQABAIAAAP///wAAACH5BAEAAAAALAAAAAABAAEAAAICRAEAOw==');
}
// EOF
The script can of course be improved (referrer checking, caching, etc.) yet the gist of it is there.
Upload the script to your web server and finally embed code will become this:
<iframe width="560" height="315" src="https://player.vimeo.com/video/83936766?title=0&byline=0&portrait=0" frameborder="0" webkitallowfullscreen mozallowfullscreen allowfullscreen>
<img src="https://example.org/vimeothumb.php?id=83936766" />
</iframe>
Happy embedding!
Consider donating.
I don’t run ads on my blog nor do I do this for profit. A donation however would always put a smile on my face though. Thanks!