views:

196

answers:

2

Our site contains some lists of YouTube videos with their thumbnails linked to the movies themselves. We fetch the thumbnail URLs from the YouTube API, and hotlink to them in situ on YouTube's servers. So our image tags look like:

<img src="http://i.ytimg.com/vi/o6CHqSN7O-o/2.jpg" alt="" width="133" height="78" />

The problem is that sometimes a video gets removed -- and so does the thumbnail. We don't know when that might happen, and our thumbnails just turn into broken images. How can we handle this?

There are a number of solutions:

  • Download thumbnails and store them locally -- movie won't work if it gets removed, of course, but that's ok, it will explain it was removed, and we avoid the broken image.

  • Check periodically with the API to see if the image thumbnail has changed -- if it no longer exists, substitute our own "movie removed" thumbnail. This is pretty heavy on the API calling!

  • Use JavaScript to replace broken images (don't like this one much)

Our ideal solution would be to point the img src to a location on YouTube that would display a friendly "move removed" image when a movie goes down. However, that doesn't seem to exist.

Anyone else dealt with this? Thanks!

A: 

Use PHP to request the file and only put the thumbnail there if the HTTP response code is 200. If it's 404 or some other error, put something else there (you decide).

Delan Azabani
That's a good idea for some cases, definitely. It might be a bit heavy for our purposes -- if we had 100 videos on a page, we'd be making a request for each thumbnail image each time the page loads. Or we could batch it and check periodically, but that's not much different than checking with the API periodically. Thanks for the idea, did I get the concept right? Any way to avoid all those calls?
mrjf
A: 

Request the thumbnail from YouTube on the server side, save it into a cache on your server, display cached image. That way, you'll still have the thumbnail on your server, even if the original is removed. The thumbnail will be only requested once for each video. PHP-like pseudo code:

<?php
$filename = $this->get_thumbnail_filename_from_url($url); // any way to map an image URL into a filename - e.g. strip everything except [a-zA-Z0-9] from URL
if (!file_exists($cachedir . '/' . $filename)) {
   $filename = $this->get_image_from_web_save_to_cache($url,$cachedir); // makes a HTTP request to the URL, saves the returned image (if any) into cache
}
$filename = basename($filename);
echo "<img src=\"/cache/$filename\">"; // display your cached thumbnail
?>

One pitfall: if the thumbnail changes, your cached version stays the same; not a common issue with YT videos though. This is solvable by making the cache more intelligent - but you'll have to start storing metadata (age, max-age, ...) and deal with the HTTP caching headers. Caching pseudocode:

  • is object in cache?
    • if yes, is the cached version fresh? (max-age etc.)
      • if there is a newer remote version (last-modified, etag, etc.), download and store
  • else download and store remote version
  • if "download and store" returns 404, change image to "removed"
Piskvor
I think this is pretty close to downloading the thumbnails and storing them locally as I described in the first option. That works pretty well for avoiding broken images, but it doesn't update if the video gets removed, which would be nice.
mrjf
@mrjf: Yeah, that's exactly it. Unfortunately, keeping the thumbnail updated is rather non-trivial, as it requires a more complicated caching system (as sketched in my edit below the code: "only check this thumbnail if we haven't done that recently"). Even so, you'll still get stale data from time to time.
Piskvor