Search code examples
phphtml.htaccesshotlinking

.htaccess .mp4 hotlinking mobile video doesn't play


Hi So I have a bunch of video's which users should only be able to see on a videos.php page with has a html5 tag. When you directly access the mp4 file it should redirect you to the homepage. This works fine using the code below.

I made use of this code :

RewriteEngine on
RewriteCond %{HTTP_REFERER} !^http(s)?://(www\.)?mydomain.com [NC]
RewriteRule \.(mp4)$ - [NC,F,L]

However on any mobile device the redirect works but the videos stopped playing once I've implemented the new rule. So I found this code from somewhere in hopes it will work:

# for android/ipad/iphone/BlackBerry/Nokia/Samsung/Windows Phone
RewriteCond %{HTTP_USER_AGENT} !(Android|iPad|iPhone|BlackBerry|Nokia|SAMSUNG|Windows\ Phone)

Still no luck, the hotlinking on mobile and desktop works except on mobile the video files don't play. I've reverted back to the original code:

RewriteEngine on   

RewriteCond %{HTTP_REFERER} !^http(s)?://(www\.)?mydomain.com [NC]
RewriteRule \.(mp4|jpg|gif)$ - [NC,F,L]

If anyone can help me understand why the video's don't play with hotlinking I would appreciate it!


Solution

  • So after trying everything I came to my solution to the problem. Instead of using .htaccess I did the following:

    Create a unique folder name for your videos. e.g. KV93BGYFQW9024J so the url will be to the video : (potentially you can recreate this every day keeping it in a database as reference)

    mydomain.com/KV93BGYFQW9024J/video.mp4
    

    Now create a php file that looks like this :

    <?php
            $video = "video.mp4" //Video name can be retrieved from database using a token passed to this page
    
        $auth=true; // Authentication can be done here;
    
        if($auth){
            $path = "KV93BGYFQW9024J/";
            header("Content-type: video/mp4");
            header("Content-Length: ".filesize($path)); // provide file size
            header("Expires: -1");
            header("Cache-Control: no-store, no-cache, must-revalidate");
            header("Cache-Control: post-check=0, pre-check=0", false);
            readfile($path);
        }else{
            echo "Not Authenticated";
        }
    ?>
    

    And then lastly on the actual page you can have this

    <video id="example_video_1" controls preload="none" autoplay="false" >
          <source src="video.php?id=ISHF298YFGY25H01" type='video/mp4' />  
    </video>
    

    The token should reference the name of the video. I know this is just a throw-off but helps to avoid sneaky users from sniffing out other videos. All and all you cannot directly access the video without authentication and if you do manage to get hold of the folder you could as mention randomly re-generate the name every 1-12hours depending on the video length.

    If anyone else could give me a better solution to this it would be appreciated. This will help for now my I still see the folder even with a random generated name every 2 hours (in my case) being a security loophole.

    Thanks

    Oh yes problem here thanks to a friend of mine, the file will load fully into the server ram meaning if you have a 20mb file the whole files loads into the ram and then is streamed to user. If you have 1000 concurrent connections, you would run out of ram. Any additions on this subject would be appreciated as well.