Need to serve up some sample images or videos that are apparently random, but remain consistent each time you show them?
Update: this is also part of the Node.js Video Streamer I made. Though not in PHP, obviously.
I recently uploaded a Video Gallery web app I’d made (demo, code download). Unfortunately I don’t have the real videos and pictures that it was supposed to use, so I thought I’d cut some clips from the silent-but-gorgeous They Call Us Animals music video footage. But the Video Gallery has about 300 different videos in the database, and I really didn’t want to make 900 sample clips (each one in 720p, 480p and 360p). So I made about 10, which seems enough to give a little variety.
But I couldn’t just serve up any video. Using the HTTP pseudostreaming support in JW Player, the site lets users change video sizes while they’re watching, and the player will switch to a different resolution source file if one is available to improve the viewing experience. It looks good, but the effect was rather spoiled when the video selector returned a higher resolution version of a completely different clip.
So I wrote a little PHP script that would serve up an apparently random sample video consistently.
Using the code
$folder to point at the folder where the files you want to serve are located. It’s currently set up to use the folder where the file is uploaded.
The file selector will serve up jpegs, pngs and flv files from the box. If you want to allow others, add their file extensions and MIME types to the
$ext_list array. There are examples for CSS, PDF and HTML files in the source. (On a side note, please don’t add PHP to the list and use
$folder = '.' unless you don’t mind it returning itself sometimes.)
To get a random-but-consistent file, link to it as any other file
<img src="http://example.com/rotate.php?file=kittens.jpg" />
The file returned will be of that same type (flv or jpg above). It will not be kittens.flv, but you will get the same one every time you ask for kittens.flv.
After performing a few checks on the file type and allowed extensions, I used
crc32 to convert the supplied filename into an integer and ran it through the modulus operator to get a number in the range of the file count in the current folder. Then it reads the chosen file and we’re done. And that’s it.
$ext_list = array(); $ext_list['gif'] = 'image/gif'; $ext_list['jpg'] = 'image/jpeg'; $ext_list['jpeg'] = 'image/jpeg'; $ext_list['png'] = 'image/png'; $ext_list['flv'] = 'video/x-flv'; $file = null; $vid = null; $vids = null; $content_type = null; if (!isset($_GET['file'])) return; $file = pathinfo($_GET['file']); // Just in case there's other stuff in the folder too (like this file) if (!array_key_exists($file['extension'], $ext_list)) return; if (substr($folder, -1) != '/') $folder .= '/'; // Select a file based on the given extension. $vids = glob($folder . '*.' . $file['extension']); $vid = $vids[abs(crc32($file['basename'])) % count($vids)]; $content_type = 'Content-type: ' . $ext_list[$file['extension']]; header ($content_type); readfile($vid);
Fun with .htaccess
Supplying random-but-consistent videos like this changes their path, as it’s now necessary to include (at least)
consistent-random.php?file=. Not ideal, but a few lines added to .htaccess can point the original paths at the new placeholder files.
RewriteBase /video-gallery/ RewriteRule ^images/thumb/([-_a-zA-Z0-9\.]+)$ placeholder/images/thumb/consistent-random.php?file=$1 [L] RewriteRule ^images/full/([-_a-zA-Z0-9\.]+)$ placeholder/images/full/consistent-random.php?file=$1 [L] RewriteRule ^videos/([-_a-zA-Z0-9\.]+.flv)$ placeholder/videos/consistent-random.php?file=$1 [L]
And we’re done! The Video Gallery now thinks it’s supplying the videos and images as originally intended, not the placeholder ones it’s actually showing.