阻止下载HTML5视频(右键单击保存)?

2020/10/22 02:02 · javascript ·  · 0评论

如何从浏览器的右键菜单中禁用“将视频另存为...”,以防止客户端下载视频?

是否有更完整的解决方案可以阻止客户端直接访问文件路径?

你不能这是因为这就是浏览器的目的:提供内容但是,您可以使其更难下载

首先,您可以禁用contextmenu事件,也就是“右键单击”。这样可以防止常规滑轨者通过右键单击并另存为来公然翻录视频。但是随后他们可以禁用JS并解决此问题,或者通过浏览器的调试器找到视频源。再加上这是糟糕的用户体验。上下文菜单中有很多合法的东西,而不仅仅是“另存为”。

您也可以使用自定义视频播放器库。它们中的大多数都实现了视频播放器,可根据您的喜好自定义上下文菜单。因此,您不会获得默认的浏览器上下文菜单。而且,如果他们确实提供类似于“另存为”的菜单项,则可以将其禁用。但同样,这是一个JS解决方法。弱点类似于上一个选项。

另一种方法是使用HTTP Live Streaming提供视频它本质上所做的就是将视频切成小块,一个接一个地提供。这就是大多数流媒体网站如何提供视频的方式。因此,即使您设法另存为,也只能保存一部分,而不是整个视频。使用一些专用软件来收集所有块并将它们缝在一起将需要花费更多的精力。

另一种技术是<video><canvas>在此技术中,通过使用一些JavaScript,您在页面上看到的是一个<canvas>元素,元素从hidden渲染框架<video>并且因为它是<canvas>,所以上下文菜单将使用<img>的菜单,而不是的菜单<video>您将获得“另存图像为”而不是“视频另存为”。

您也可以使用CSRF令牌以发挥自己的优势。您将需要在页面上发送令牌给服务器。然后,您可以使用该令牌来获取视频。您的服务器在投放视频之前会检查其是否为有效令牌,或者获取HTTP 401这个想法是,只有拥有令牌,您才能获得视频,只有当您来自页面时才能获得令牌,而不能直接访问视频URL。

归根结底,我只是将视频上传到第三方视频网站,例如YouTube或Vimeo。他们拥有良好的视频管理工具,可以优化设备的播放,并且可以尽最大努力防止视频被盗用。

对于那些只希望从html5视频中删除右键单击“保存”选项的用户来说,这是一个简单的解决方案

$(document).ready(function(){
   $('#videoElementID').bind('contextmenu',function() { return false; });
});

简单的答案,

你不能

如果他们正在观看您的视频,他们已经有

您可以放慢它们,但不能阻止它们。

是的,您可以通过三个步骤执行此操作:


  1. 将要保护的文件放在运行代码的目录的子目录中。

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

  2. 将文件保存在名为“ .htaccess”的子目录中,然后添加以下行。

    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]
    

现在,源链接已无用,但是我们仍然需要确保不能将任何试图下载文件的用户直接提供给文件。

  1. 获得更完整的解决方案,现在可以使用Flash Player(或html canvas)提供视频,并且永远不要直接链接到视频。要仅删除右键菜单,请添加到HTML:

    <body oncontextmenu="return false;">
    

结果:

www.foo.com/player.html将正确播放视频,但是如果您访问www.foo.com/videos/video.mp4:

错误代码403:禁止

您可以将其直接下载,使用cURL,进行热链接。

这是对所问两个问题的完整答案,而不是对以下问题的答案:“我可以阻止用户下载他们已经下载的视频吗?”

我通常使用的最好方法是非常简单的,我完全禁用了整个页面的上下文菜单,即纯html + javascript:

 <body oncontextmenu="return false;">

而已!我这样做是因为您始终可以通过右键单击来查看源。

好的,您说:“我可以直接使用浏览器视图源”,这是真的,但是我们从您
不能停止下载html5视频这一事实开始

作为客户端开发人员,我建议使用blob URL,blob URL是引用二进制对象的客户端URL。

<video id="id" width="320" height="240"  type='video/mp4' controls  > </video>

在HTML中将视频src留空,而在JS中使用AJAX提取视频文件,请确保响应类型为blob

window.onload = function() {
    var xhr = new XMLHttpRequest();
    xhr.open('GET', 'mov_bbb.mp4', true);
    xhr.responseType = 'blob'; //important
    xhr.onload = function(e) {
        if (this.status == 200) {
            console.log("loaded");
            var blob = this.response;
            var video = document.getElementById('id');
            video.oncanplaythrough = function() {
                console.log("Can play through video without stopping");
                URL.revokeObjectURL(this.src);
            };
            video.src = URL.createObjectURL(blob);
            video.load();
        }
    };
    xhr.send();
}

注意:不建议将此方法用于大文件

编辑

  • 使用跨域阻止来避免直接下载

  • 如果视频是通过API传递的,请使用其他方法(PUT / POST)而不是“ GET”

PHP将html5视频标签与会话一起发送,该会话的键是随机字符串,值是文件名。

ini_set('session.use_cookies',1);
session_start();
$ogv=uniqid(); 
$_SESSION[$ogv]='myVideo.ogv';
$webm=uniqid(); 
$_SESSION[$webm]='myVideo.webm';
echo '<video autoplay="autoplay">'
    .'<source src="video.php?video='.$ogv.' type="video/ogg">'
    .'<source src="video.php?video='.$webm.' type="video/webm">'
    .'</video>'; 

现在,要求PHP发送视频。PHP恢复文件名;删除会话并立即发送视频。此外,所有“无缓存”和mime类型的标头都必须存在。

ini_set('session.use_cookies',1);
session_start();
$file='myhiddenvideos/'.$_SESSION[$_GET['video']];
$_SESSION=array();
$params = session_get_cookie_params();
setcookie(session_name(),'', time()-42000,$params["path"],$params["domain"],
                                         $params["secure"], $params["httponly"]);
if(!file_exists($file) or $file==='' or !is_readable($file)){
  header('HTTP/1.1 404 File not found',true);
  exit;
  }
readfile($file);
exit:

现在,如果用户将URL复制到新选项卡中或使用上下文菜单,那么他将没有运气。

您至少可以阻止不懂技术的人使用右键单击上下文菜单下载视频。您可以使用oncontextmenu属性为任何元素禁用上下文菜单。

oncontextmenu="return false;"

这适用于body元素(整个页面)或仅在video标签内使用body元素的单个视频。

<video oncontextmenu="return false;" controls>...</video>

我们最终使用了带有到期URL的AWS CloudFront。视频将加载,但是到用户右键单击并选择“另存为”视频URL时,他们最初收到的URL已过期。搜索CloudFront原始访问身份。

制作视频URL需要可以在AWS CLI中创建的密钥对。仅供参考,这不是我的代码,但效果很好!

$resource = 'http://cdn.yourwebsite.com/videos/yourvideourl.mp4';
$timeout = 4;

//This comes from key pair you generated for cloudfront
$keyPairId = "AKAJSDHFKASWERASDF";

$expires = time() + $timeout; //Time out in seconds
$json = '{"Statement":[{"Resource":"'.$resource.'","Condition" {"DateLessThan":{"AWS:EpochTime":'.$expires.'}}}]}';     

//Read Cloudfront Private Key Pair
$fp=fopen("/absolute/path/to/your/cloudfront_privatekey.pem","r"); 
$priv_key=fread($fp,8192); 
fclose($fp); 

//Create the private key
$key = openssl_get_privatekey($priv_key);
if(!$key)
{
    echo "<p>Failed to load private key!</p>";
    return;
}

//Sign the policy with the private key
if(!openssl_sign($json, $signed_policy, $key, OPENSSL_ALGO_SHA1))
{
    echo '<p>Failed to sign policy: '.openssl_error_string().'</p>';
    return;
}

//Create url safe signed policy
$base64_signed_policy = base64_encode($signed_policy);
$signature = str_replace(array('+','=','/'), array('-','_','~'), $base64_signed_policy);

//Construct the URL
$url = $resource.'?Expires='.$expires.'&Signature='.$signature.'&Key-Pair-Id='.$keyPairId;

return '<div class="videowrapper" ><video autoplay controls style="width:100%!important;height:auto!important;"><source src="'.$url.'" type="video/mp4">Your browser does not support the video tag.</video></div>';

我们可以通过隐藏上下文菜单来简化操作,如下所示:

<video oncontextmenu="return false;"  controls>
  <source src="https://yoursite.com/yourvideo.mp4" >
</video>

您可以使用

<video src="..." ... controlsList="nodownload">

https://developer.mozilla.org/zh-CN/docs/Web/API/HTMLMediaElement/controlsList

它不会阻止保存视频,但是会删除上下文菜单中的下载按钮和“另存为”选项。

使用Vimeo之类的服务:登录Vimeo > Goto Video > Settings > Privacy > Mark as Secured,然后选择嵌入域。设置嵌入域后,除非从指定的域进行连接,否则不允许任何人嵌入视频或通过浏览器显示视频。因此,如果您的服务器上有一个安全的页面,该页面在iframe中加载了Vimeo播放器,则很难解决。

+1简单的跨浏览器方式:您还可以使用css z-index和opacity在视频上放置透明图片。因此,用户将在上下文菜单中看到“将图片另存为”而不是“保存视频”。

首先,要意识到不可能完全阻止视频的下载,您所要做的就是使其变得更加困难也就是说,您隐藏了视频的来源。

网络浏览器会暂时将视频下载到缓冲区中,因此,如果可以阻止下载,那么您也将无法观看视频。

您还应该知道,世界上只有不到1%的人口能够理解源代码,因此无论如何它都相当安全。这并不意味着你不应该在源隐藏它,以及-你应该

您不应该禁用右键单击功能,更不要说显示一条消息了"You cannot save this video for copyright reasons. Sorry about that."正如这个答案所建议的

对于用户而言这可能非常烦人和令人困惑。除此之外; 如果他们在浏览器上禁用了JavaScript,无论如何他们可以右键单击并保存。

这是您可以使用的CSS技巧:

video {
    pointer-events: none;
}

无法在浏览器中关闭CSS,以保护您的视频而无需实际禁用右键单击。但是,一个问题是controls也无法启用,也就是说,必须将其设置为false如果您要添加自己的播放/暂停功能或使用API​​的按钮与video标签分开,那么这是一个可行的选择。

controls 还具有下载按钮,因此使用它也不是一个好主意。

这是一个JSFiddle示例。


如果您要使用JavaScript禁用右键单击功能,那么还将视频源也存储在JavaScript中。这样,如果用户禁用JavaScript(允许右键单击),则视频将不会加载(这也会更好地隐藏视频源)。

TxRegex答案

<video oncontextmenu="return false;" controls>
    <source type="video/mp4" id="video">
</video>

现在,通过JavaScript添加视频:

document.getElementById("video").src = "https://www.w3schools.com/html/mov_bbb.mp4";

功能性JSFiddle


防止右键单击的另一种方法涉及使用embed标签。但是,这并未提供运行视频的控件,因此需要将其替换为JavaScript:

<embed src="https://www.w3schools.com/html/mov_bbb.mp4"></embed>

<body oncontextmenu="return false;"> 

不再有效。截至2018年6月,Chrome和Opera在时间轴上都有一个子菜单,可以直接下载,因此用户无需右键单击即可下载该视频。有趣的是Firefox和Edge没有这个...

好吧,您不能100%保护它,但可以使其变得更难。我正在解释这些方法,我在研究PluralSightBestDotNetTraining中的保护方法时遇到了它们但是,这些方法都没有阻止我下载我想要的东西,但是我很难安排下载器通过他们的保护。

除了提到的其他禁用上下文菜单的方法。用户仍然可以使用第三方工具(例如InternetDownload Manager或其他类似软件)下载视频。我在这里解释的保护方法是缓解那些第三方软件。

所有这些方法的要求是,当您确定某人正在下载视频时阻止该用户。这样,在您禁止他们访问您的网站之前,他们只能下载一个或两个视频。

免责声明

如果有人滥用这些方法或将其用于损害他人或我作为示例提及的网站,我将不承担任何责任。这仅仅是为了共享知识,以帮助您保护自己的知识产品。

生成过期的链接

要求是为每个用户创建一个下载链接。可以通过天蓝色blob存储或Amazon s3轻松处理。您可以创建一个具有两倍于视频时长到期时间戳记的下载链接。那么您需要捕获该视频链接和所需的时间。这是下一种方法所必需的。该方法的不足之处在于,当用户单击播放按钮时,您正在生成下载链接。

在播放按钮事件中,您将向服务器发送请求并获取链接并更新源。

限制视频请求率

然后监视用户请求第二个视频的速度。如果用户要求下载链接的速度太快,则可以立即将其阻止。您不能将此阈值设置得太大,因为您可能会错误地阻止仅浏览或浏览视频的用户。

启用HTTP范围

使用诸如videojs之类的js库播放视频,也需要在标头中返回一个AcceptRange。Azure blob存储支持此功能。这样,浏览器便开始逐块下载视频。通常,32字节乘32字节。那么您需要听一下videojs的timeupdate变化,并向服务器更新有关观看视频的百分比。观看视频的百分比不能超过视频交付的百分比。如果您在交付视频内容时未收到任何百分比变化,则可以阻止该用户。因为可以肯定他们正在下载。

实施此操作很棘手,因为用户可以向前或向后跳过视频,因此在实施此操作时请注意这一点。

这就是BestDotnetTraining如何处理 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);
            }
        });
    }

});

无论如何,用户可以通过使用一些通过流下载文件的下载方法来解决此问题。几乎C#可以立即使用,对于nodejs,可以使用requestmodule。那么您需要启动秒表,收听收到的包裹并将收到的总字节与总大小进行比较。这样,您可以计算一个百分比以及获得该百分比所花费的时间。然后使用Thread.Sleep()或类似的方法延迟线程,如果您正常观看视频,则必须等待的时间。同样,在睡眠之前,用户可以呼叫服务器并更新接收到的百分比。因此服务器认为用户实际上正在观看视频。

例如,如果计算得出到目前为止已收到1%,那么您可以计算出应该等待休眠下载线程的数量。这样,您下载视频的速度不会超过实际长度。如果视频是24分钟 下载将需要24分钟。(加上我们在第一种方法中设置的阈值)

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

检查浏览器代理

当您提供网页并提供视频链接或接受进度更新请求时,您可以查看浏览器代理。如果不同,则禁止该用户。

请注意,某些旧的浏览器不会传递此信息。因此,当视频请求和网页请求中都没有浏览器代理时,您应该忽略此设置。但是如果一个请求有该请求,而另一个没有,则应禁止该用户。

要解决此问题,用户可以将浏览器代理标头手动设置为与他们用来捕获下载链接的无头浏览器相同。

检查引荐标头

如果引荐来源网址不是您提供视频的主机URL或页面URL之外的其他内容,则可以禁止该用户,因为他们将下载链接放置在另一个选项卡或另一个应用程序中。即使您可以针对进度更新请求执行此操作。

对此的要求是具有视频和显示该视频的页面的映射。您可以创建一些约定或模式来了解URL应该是什么,这取决于您的设计。

要解决此问题,用户可以在下载视频时手动将引荐来源标头设置为等于下载页面URL。

计算两次请求之间的时间

如果收到太多请求以至于它们之间的时间相同,则应阻止该用户。您应该使用它来捕获两次视频链接生成请求之间的时间。如果它们相同(加/减某个阈值)并且发生多次,则可以禁止该用户。因为如果有一个机器人会抓取您的网站或视频,那么通常他们在两次请求之间的睡眠时间相同。因此,例如,如果您收到每一个请求,则每1.3(分钟/分)。然后您发出警报。为此,您可以使用一些统计计算来了解请求之间的偏差。

要解决此问题,用户可以在请求之间放置一个随机的睡眠时间。

样例代码

我有一个正在做的仓库PluralSight-Downloader我在大约5年前创建了此仓库。因为我写的只是出于学习目的,并且仅供个人使用,所以该回购到目前为止尚未收到任何更新,我也不会进行更新或使其易于使用。这只是如何完成的一个例子。

简短答案:像youtube一样对链接进行加密,不知道如何向youtube / google询问他们如何做。(以防万一,您想直截了当。)

我想向任何人指出,这是有可能的,因为youtube可以做到,其他网站也可以,而且不是来自浏览器,因为我在Microsoft Edge和Internet Explorer等多种浏览器上进行了测试,所以有一种方法可以禁用它,并且看到人们仍然在说...我试图寻找答案,因为如果youtube可以,那么必须有一种方法,并且唯一的方法就是看看有人怎么做。我现在正在做的youtube脚本。我还检查了它是否也是一个自定义的上下文菜单,这不是因为上下文菜单溢出了检查元素,我的意思是就像它位于该元素上一样,我查看了它并且从未创建新的类,而且不可能实际上使用javascript访问inspect元素,所以不能。您可以判断何时双击鼠标右键,会弹出chrome上下文菜单。此外... youtube不会在其中添加该功能。我正在做研究,并且正在寻找youtube的来源,所以如果找到答案我会回来的...如果有人说不能,那么他们没有像我一样做研究。下载youtube视频的唯一方法是通过视频下载。

好的...我做了研究,但我的研究仍然是您可以禁用它,除非没有JavaScript。...您必须能够加密指向视频的链接才能禁用它,因为我认为如果找不到它,浏览器将不会显示它,当我打开youtube视频链接时,它显示为“斑点:https : //www.youtube.com/e5c4808e-297e-451f-80da-3e838caa1275“没有引号,因此它正在对其进行加密,因此无法保存...您需要了解php,但是就像您从使它变得更难得到的答案中一样,youtube使它成为最难对付的加密方法,您需要成为先进的php程序员,但是如果您不知道那件事,而不是选择您所选择的人作为使其难以下载的最佳答案...但是,如果您知道php胜过加密视频链接,那么它只能被读取您的...我不知道如何解释他们的操作方式,但是他们确实做到了,而且有一种方法。youtube加密视频的方式非常聪明,因此,如果您想知道如何操作,而不仅仅是问问youtube / google如何操作他们做到了...希望这对您有所帮助,尽管您已经选择了最佳答案。因此,短期内最好加密链接。

似乎通过websocket流式传输视频是一个可行的选择,因为在流式传输帧并将它们绘制在画布上的事情上。

使用JavaScript在WebSocket上进行视频流式传输

我认为这将提供另一种级别的保护,使客户端更难以获取视频,当然可以通过右键单击上下文菜单选项“将视频另存为...”解决您的问题(过度杀伤?!)。

这是我所做的:

function noRightClick() {
      alert("You cannot save this video for copyright reasons. Sorry about that.");
}
    <body oncontextmenu="noRightClick();">
    <video>
    <source src="http://calumchilds.com/videos/big_buck_bunny.mp4" type="video/mp4">
    </video>
    </body>

这也适用于图像,文本和几乎所有内容。但是,您仍然可以通过键盘快捷键访问“检查”和“查看源代码”工具。(正如顶部的回答所述,您不能完全阻止它。)但是您可以尝试设置障碍以阻止它们。

@ Clayton-Graul有我想要的东西,除了我需要使用AngularJS的网站的CoffeeScript版本。以防万一您也需要它,这是您放在有问题的AngularJS控制器中的内容:

    # This is how to we do JQuery ready() dom stuff
    $ ->
        # let's hide those annoying download video options.
        # of course anyone who knows how can still download
        # the video, but hey... more power to 'em.
        $('#my-video').bind 'contextmenu', -> 
            false

“圆k处正在出现奇怪的事情”(的确是)

本文地址:http://javascript.askforanswer.com/zuzhixiazaihtml5shipinyoujiandanjibaocun.html
文章标签: ,   ,  
版权声明:本文为原创文章,版权归 javascript 所有,欢迎分享本文,转载请保留出处!

文件下载

老薛主机终身7折优惠码boke112

上一篇:
下一篇:

评论已关闭!