While looking for a reasonably priced free method of hosting my own videos,
I quickly came to realize that Flash Video (FLV) is the coolest kid on the block - and for good reason.
According to a few different
sources on the net, FLV is an excellent
choice for providing video. It reaches a higher audience percent than any of Windows Media, Quicktime or Real,
while also having a smaller footprint. This is the reason that You Tube and
Google Videos both use flash to deliver video content on the web.
There are lots of sites that describe how to convert video to FLV. Some methods free, some are very pricy, and
some are better than others. Find one that is easy and that you like.
My next focus was playing the video. I found a few options like
Jeroen Wijering's player but finally settled on FlowPlayer for a number of reasons.
It supports playlists, will slideshow images, and is easily skinnable. Most importantly for me, was the claim that is supports
prevention of inline linking also known as Leeching. This is when other sites directly link to content on your site, so you
pay the bandwidth but they get the views.
A sample (standard video test pattern bars and test tone) to demonstrate:
Here is how I implemented anti-leeching as demonstrated...
According to the documentation:
FlowPlayer can use authentication codes to protect against
inline linking
of video and image files. Inline linking is also known as hotlinking or
direct linking. To implement this in your site you need to use a server side script/app that
generates these authentication codes and stores them into a file
called flowplayer_auth.txt. The player reads the contents
of this file just before a protected clip is loaded and concatenates
the contents to clip's file name.
So if the code stored in the authentication file is 'asdfln83yrojfalu3rl' and
the clip's url is 'cars.flv' the player requests a file called
'asdfln83yrojfalu3rlcars.flv' from the server.
For this scheme to be effective the authentication code should change
periodically (for example once in a minute). Additionally the server script/app needs
to verify whether the incoming request contains a valid code and only
serve the file if the code is valid.
I could not find any good references online on how to actually implement this, so I figured I'd steal from myself
and copy some work I had done earlier to watermark the images on my web site. The basic idea was as follows... Create a
php handler for all .flv files in a directory and use .htaccess to rewrite the requests to it. This php file would do
the check against the auth code as well as updating it, at minimum, every 60 seconds.
The .htaccess file
Here is the .htaccess file I created for the directory where the flv files and the Flowplayer script are located
Options +FollowSymlinks
RewriteEngine on
RewriteRule .*\.flv$ /public/flowplayer/flvloader.php?pathinfo=%{REQUEST_URI}
This simply takes any requests for .flv files and passes the file URL as a parameter to the flvloader script.
The flvloader.php file
Here is the handler file:
//get actual file called for
$path_parts = pathinfo($_GET['pathinfo']);
$file = $path_parts['basename'];
//name of authorization file must match the setting in flowplayer
$authfile="flowplayer_auth.txt";
//seconds to reset the auth code
$stale=60;
//check if authfile exists and the change date
if (file_exists($authfile)) {
$expired=filemtime($authfile)+$stale;
} else
{
header("HTTP/1.0 404 Not Found");
exit();
}
//read auth code from file and rehash it to a new code if expired
$handle = @fopen($authfile, "r+");
if ($handle) {
$code = fgets($handle);
if (time()>$expired) {
rewind($handle);
fwrite($handle, md5($code));
}
fclose($handle);
} else
{
header("HTTP/1.0 404 Not Found");
exit();
}
//check authcode matches file and if so set the name to the real file otherwise 404
if (is_numeric(strpos($file,$code)))
{
$file_real = substr($file,strlen($code),strlen($file)-strlen($code));
} else
{
header("HTTP/1.0 404 Not Found");
exit();
}
//send file or 404 if not found.
if (file_exists($file_real))
{
header("Content-Type: video/x-flv");
header("Accept-Ranges: bytes");
header("Content-Length: ".filesize($file_real));
header("Cache-Control: no-cache, must-revalidate"); // HTTP/1.1
header("Expires: Mon, 26 Jul 1997 05:00:00 GMT"); // Date in the past
@readfile($file_real);
} else
{
header("HTTP/1.0 404 Not Found");
}
This simply checks how old the auth code file is, and updates the code with a hash
of itself (for the next load) if the stale value has been exceeded. Note that the web
server process bust be able to read/write the auth file.
The authorization code then checks if the code string in the authorization file is in the
the filename passed by the Flowplayer script. If so it strips it off and returns the file
(if it exists). It sets up some of the header attributes of the file: the mime type, the length
and flags it as not-cacheable.
Embedding it on the page here
Just so you have the complete package, here is the syntax of the called Flowplayer object I used.
Pretty simple. Because of the way my blog performs URL translation, I had to provide some full path information to the player. Additionally, as I wanted a "click to play" displayed at the start, I used it once as a still, then again at the end of the playlist. This let the playlist rewind itself and be ready for another click to play the video. The only problem I have is with browser caching. Sometimes the Flowplayer gets cached and uses an expired authorization code. This could be minimized by changing the authorization code expiration time, if desired.
Security
This method will not stop a person from downloading the flv file but it does a good job of stoping
an external site from hotlinking directly to the flv file, or even from hotlinking to the Flowplayer object
and running it off your site (eating up your bandwidth). Here is a direct link to the flv file
barsandtone.flv that will NOT return the flv file because of the htaccess handler.
That's it! If you found this useful or have any comments, as always, use the form.
Anti-leeching
FlowPlayer supports prevention of inline linking also known as leeching. Rob has written about his experiences implementing this on the server side using PHP. Includes a demo and some sample code! technorati tags:flash, flv, php, inline, linking
Hi, I tested this page in IE6.0 and FF2.0
but, I can't play demo video again in FF2.0
So, I checked http header, response is 404. when i clicked play button.
Currently, the script is set up to to change the code once per minute. That means that if you watch the video then come back more than a minute later you may be requesting it with the old code. Even though I have it set to sent no-cache headers, and an expiry date in the past.
It might be the applet that is doing the caching...I haven't figured that out yet
The likelihood of this can be be minimized by increasing the code change interval, but that then increases the time it will be available. As the whole point of this is anti-leeching, setting it even as high as 30 minutes should eliminate the issue almost completely, while still preventing long term hot-linking.
Thinking about it, another option would be to have a quick "the link to this video is outdated" clip that is substituted in place of the real one, rather than returning a 404....
This means if user clicks the player after 1 minute, since user may be reading the content. The video may not get played since the auth code on server will not match with one on local cache.
That's right. I have the timeout set to one minute for the purpose of this demonstration. In reality, you would set it much higher (as long as a person would be expected to sit on one page).
Justin - thanks for the comment. The point of this is not to prevent downloading (which cannot be prevented...if you can watch something you can capture the stream and download it!) The point is to prevent hotlinking from foreign websites so they serve up your content, chewing up your bandwidth while benefiting from views.
Thank you, your code is really useful for prevent hotlinking of flv file, but how can I use it to stream mp3 file instead? I'm trying to replace flv to mp3 and it didn't work for me
I've never tried mp3 file, but I would think changing/adding the htaccess redirect to mp3 files and rewriting the handler (flvloader.php) to return mp3 headers along with the mp3 file should do the trick.
Excelent job. But I would like to know how to implement on the code without playlist, with a single flv embed. How to set "protected" in a single embed file?
FlowPlayer supports prevention of inline linking also known as leeching. Rob has written about his experiences implementing this on the server side using PHP. Includes a demo and some sample code! technorati tags:flash, flv, php, inline, linking
Tracked: Feb 25, 05:11