Page 1 of 1

Implementing a system to stop BW hogs on a video sharing sit

Posted: Tue Sep 09, 2008 9:24 pm
by phice
Hey guys, I've got a dilemma here and I think that a small PHP solution would do the trick.

I've built a custom flash video hosting site and everything is nice and dandy, however anyone who looks at the source code can quickly see the .flv url and easily hotlink our video on their site and waste tons of bandwidth. This is an obvious concern for anyone not looking to waste massive amounts of money.

What I've seen done around a few other video sites is creating custom urls for the .flv file itself.

For example: /videos/js0f43023si3k3mv03i3/0003863.flv

I've come up with a solution that I think might fit this bill. When you go to the video view page, that page creates either a database row or a session variable that contains the key 'js0f43023si3k3mv03i3', as well as it's creation date. What do you guys think is the best solution for this problem? Obviously the database solution would be better.

Another thing that comes to mind, would I use header("Location: /raw/path/to/video.flv"); or would I use something similar to: print file_get_contents(<full path to video>.flv); ?

If someone loads the .flv in the url (the fake url used in the source code, with the unique key) I'd prefer that they're simply not redirected to the raw path (I don't want the raw path in the address bar, which makes this whole hack completely useless). Also, I don't want this to be too much of a strain on using PHP as the file downloader script.

What do you guys think?

Re: Implementing a system to stop BW hogs on a video sharing sit

Posted: Tue Sep 09, 2008 10:15 pm
by josh
I used sessions when I was faced with this problem. I would have just checked the referrers but our site used wmv and the plugin doesn't send any referrer tags ( I guess they want you to upgrade to their commercial streaming server to protected against hotlinking )

You've got the idea, create a unique token, store it somewhere ( session / database ), access videos through a php script only outputting the file if the token is valid, if the invalid token is passed you could spit out a low bandwidth version of an ad :wink:

Now the real challenge is both implementing this and byte range responses to allow "seeking" during playback for wmvs. FLV may be the same, since you output it through a PHP script you're bypassing apaches byte code response features that these "streaming" video plugins use to seek past the buffer. If your solution needs to scale you might want a dedicated streaming server that handles all this for you.

Also use readfile() so you're not consuming excess memory with your scripts. Those video sites can be a paaaain to host. CHeck out http://www.alphared.com though

Re: Implementing a system to stop BW hogs on a video sharing sit

Posted: Tue Sep 09, 2008 10:20 pm
by phice
Well the thing is, for the flv streaming, I've got the server installed with lighttpd meaning, in combination with secdownload + flv_streaming, the video seek feature works flawlessly. I dont know if this will screw it up or not. Also, we've got avi/divx files hosted on the server as well.

Are there any lighttpd-related plugins similar to flv_streaming/secdownload that helps reduce people stealing bandwidth?

Re: Implementing a system to stop BW hogs on a video sharing sit

Posted: Tue Sep 09, 2008 10:28 pm
by josh
hmm try making a dummy script for testing,

put: file_put_contents( print_r( $_GLOBALS ,1), 'debug.html'); and call it like you would your FLVs, see if you get referrer information. The seeking most likely will work, but not seeking past the buffer or past the point that has already loaded, as what this does is closes the current connection and issues a byte range request for binary files, since youre requesting a PHP script the script would just execute, and your script would need to check for the request byte range headers and output the appropriate part of the flv. Use the live http headers plugin for firefox to help debug. You can even use mod_rewrite to make it look like a .flv instead of a PHP script, which I think you may have to do or else the browser won't send the headers

Re: Implementing a system to stop BW hogs on a video sharing sit

Posted: Tue Sep 09, 2008 11:45 pm
by phice
There's already a solution for that and it's called xmoov-php. With lighttpd the content received is saved in cache properly. With xmoov-php, you're continuously downloading content from where you seeked from, whether you've downloaded that part previously or not.

Re: Implementing a system to stop BW hogs on a video sharing sit

Posted: Tue Sep 09, 2008 11:59 pm
by josh
Awesome, I'm going to give this a spin, personally we abandoned flvs because ffmpeg was increasing our overall bandwidth usage, so we just went with wmv files. I searched for a solution like xmoov-php for weeks!! ( but for the same thing with wmv )

Re: Implementing a system to stop BW hogs on a video sharing

Posted: Wed Sep 10, 2008 12:19 am
by phice
Wow, I'm so glad that I found a great solution.

Lighttpd has an extension called mod_secdownload (required along with mod_flv_streaming). When setup properly, you can generate random urls and have them expire within a specified amount of time.

Code: Select all

secdownload.secret = "verysecret"
secdownload.document-root = server.document-root + "/../files"
secdownload.uri-prefix = "/secure-download/"
secdownload.timeout = 300
Place that into your lighttpd.conf, change the necessary values, and use the following PHP code to generate your download URL:

Code: Select all

<?php
$secret = "verysecret";
$uri_prefix = "/dl/";
 
# filename
# please note file name starts with "/"
$f = "/secret-file.txt";
 
# current timestamp
$t = time();
 
$t_hex = sprintf("%08x", $t);
$m = md5($secret.$f.$t_hex);
 
# generate link
printf('<a href="%s%s/%s%s">%s</a>',
       $uri_prefix, $m, $t_hex, $f, $f);
?>
The PHP code provided is extremely ugly but certainly provides a fantastic way to do exactly what I wanted.

See more: Docs:ModSecDownload - lighttpd

I'll post most on this subject if I find it necessary.