Prevent HTML5 video from being downloaded (right-click saved)?

前端 未结 20 2070
醉酒成梦
醉酒成梦 2020-11-22 15:33

How can I disable \"Save Video As...\" from a browser\'s right-click menu to prevent clients from downloading a video?

Are there more complete solutions that prevent

相关标签:
20条回答
  • 2020-11-22 16:09

    The best way that I usually use is very simple, I fully disable context menu in the whole page, pure html+javascript:

     <body oncontextmenu="return false;">
    

    That's it! I do that because you can always see the source by right click.
    Ok, you say: "I can use directly the browser view source" and it's true but we start from the fact that you CAN'T stop downloading html5 videos.

    0 讨论(0)
  • 2020-11-22 16:11

    We could make that not so easy by hiding context menu, like this:

    <video oncontextmenu="return false;"  controls>
      <source src="https://yoursite.com/yourvideo.mp4" >
    </video>
    
    0 讨论(0)
  • 2020-11-22 16:11

    well, you can't protect it 100% but you can make it harder. these methods that I'm explaining, I faced them during studying protection methods in PluralSight and BestDotNetTraining. nevertheless, none of these methods stopped me from downloading what I want, but I had a hard time to curate the downloader to pass their protection.

    In addition to other mentioned methods to disable the context menu. the user still is able to use third-party tools like InternetDownload manager or other similar software to download the videos. the protection method that I'm explaining here is to mitigate those 3rd party software.

    the requirement of all of these methods is to block a user when you identify someone is downloading your videos. in this way they are able to download only one or two videos only before you banned them from accessing to your website.

    disclaimer

    I will not accept any responsibility if someone abuses these methods or use it to harm others or the websites that I mentioned as an example. it's just for sharing knowledge to help you to protect your intellectual product.

    generate links with an expiry

    the requirement for this is to create a download link per user. that one can easily be handled by azure blob storage or amazon s3. you can create a download link with twice of the video length expiry timestamp. then you need to capture that video link and the time that is requested. this is necessary for the next method. the catch for this method is you are generating the download link when the user click the play button.

    on play button event you will send a request to the server and get the link and update the source.

    throttle the video request rate

    then you monitor how fast the user request for the second video. if the user request for a download link too fast, then you block them right away. you can't put this threshold too big because you can mistakenly block users that are just browsing or skimming through the videos.

    Enable HTTP Range

    use some js library like videojs to play your video, also you need to return an AcceptRange in your header. Azure blob storage supports this out of the box. this way the browser starts to download the video chunk by chunk. usually, 32byte by 32byte. then you need to listen to videojs timeupdate change and update your server about the percentage that the video is watched. the percentage that the video is watched can't be more than the percentage that video is delivered. and if you are delivering a video content without receiving any percentage change, then you can block the user. because for sure they are downloading.

    implementing this is tricky because the user can skip the video forward or backwards so be conscious about this when you are implementing this.

    this is how BestDotnetTraining is handling the timeupdate

    myPlayer.ready(function () {
        //var player = this;
        this.src({
            type: "video/mp4",
            src: videoURL
        });
        if (videoId) {
            myPlayer.play();
            this.on('timeupdate', function () {
                var currentPercent = parseInt(100 * myPlayer.currentTime() / myPlayer.duration());//calcualte as percentage
                if (currentPercent % 5 == 0) {
                    //send percentage to server 
                    SaveVideoDurationWatched(currentPercent, videoId);
                }
            });
        }
    
    });
    

    anyway, the user is able to work around this by using some download method that downloads a file through streaming. almost c# do it out of the box and for nodejs, you can use request module. then you need to start a stopWatch, listen to a package received and compare the total byte received compare to the total size. this way you can calculate a percentage and the time spent to get that amount of percentage. then use the Thread.Sleep() or something like that to delay the thread the amount that you have to wait if you watch the video normally. also before the sleep the user can call the server and update the percentage that is received. so the server thinks that the user is actually watching a video.

    the calculation will be something like this, for example, if you calculate that you received 1 per cent so far, then you can calculate the amount that you should wait to sleep the download thread. in this way you can't download a video faster than what it's actual length is. if a video is 24 min. it will takes 24 min to download it. (plus the threshold we put in the first method)

    original video length 24 minute
    24 min *60000 = 1,440,000 miliseconds 
    1,440,000 % 100 = 14,400 milisecond is needed to download one percent
    

    check the browser agent

    when you are serving a webpage and serving the video link or accepting the progress update request you can look at the browser agent. if it's different then ban the user.

    just be aware that some old browser doesn't pass this information. so you should ignore this when there is no browser agent in both video request and webpage request. but if one request has it and another one doesn't, then you should ban the user.

    to work around this the user can set the browser agent header manually same as the headless browser that they are using to capture the download link.

    check the referer header

    when the referer is something other than your host URL or the page URL that you are serving the video, you can ban the user, because they put the download link in another tab or another application. even you can do that for the progress update request.

    the requirement for this is to has a mapping of video and the page that shows that video. you can create some convention or pattern to understand what the URL should be, it's up to your design.

    to work around it the user can set the referrer header manually equal to the download page URL when downloading the videos.

    Calculate the time between request

    if you receive so many requests that the time between them is the same, then you should block the user. you should put this to capture how much is time between the video link generation request. if they are the same (plus/minus some threshold) and it happens more than a number of times, then you can ban the user. because if there is a bot that is going to crawl your website or videos, then usually they have the same sleep time between their request. so if you receive each request, for example, every 1.3(plus/mins some deviation) minutes. then you raise an alarm. for this, you can use some statistic calculation to know the deviation between the requests.

    to workaround this, the user can put a random sleep time between the requests.

    sample code

    I have a repo PluralSight-Downloader that is doing it halfway. I created this repo almost 5 years ago. because I wrote it for study purpose and own personal use only, the repo isn't received any update so far and I'm not going to update or make it easy to work with. it's just an example of how it can be done.

    0 讨论(0)
  • 2020-11-22 16:12

    Simple answer,

    YOU CAN'T

    If they are watching your video, they have it already

    You can slow them down but can't stop them.

    0 讨论(0)
  • 2020-11-22 16:12

    Yes, you can do this in three steps:


    1. Place the files you want to protect in a subdirectory of the directory where your code is running.

      www.foo.com/player.html
      www.foo.com/videos/video.mp4

    2. Save a file in that subdirectory named ".htaccess" and add the lines below.

      www.foo.com/videos/.htaccess

      #Contents of .htaccess
      
      RewriteEngine on
      RewriteCond %{HTTP_REFERER} !^http://foo.com/.*$ [NC]
      RewriteCond %{HTTP_REFERER} !^http://www.foo.com/.*$ [NC]
      RewriteRule .(mp4|mp3|avi)$ - [F]
      

    Now the source link is useless, but we still need to make sure any user attempting to download the file cannot be directly served the file.

    1. For a more complete solution, now serve the video with a flash player (or html canvas) and never link to the video directly. To just remove the right click menu, add to your HTML:

      <body oncontextmenu="return false;">
      


    The Result:

    www.foo.com/player.html will correctly play video, but if you visit www.foo.com/videos/video.mp4:

    Error Code 403: FORBIDDEN


    This will work for direct download, cURL, hotlinking, you name it.

    This is a complete answer to the two questions asked and not an answer to the question: "can I stop a user from downloading a video they have already downloaded."

    0 讨论(0)
  • 2020-11-22 16:14

    +1 simple and cross-browser way: You can also put transparent picture over the video with css z-index and opacity. So users will see "save picture as" instead of "save video" in context menu.

    0 讨论(0)
提交回复
热议问题