How can I disable "Save Video As..." from a browser's right-click menu to prevent clients from downloading a video?
如何从浏览器的右键菜单中禁用“Save Video As…”以防止客户端下载视频?
Are there more complete solutions that prevent the client from accessing a file path directly?
是否有更完整的解决方案阻止客户端直接访问文件路径?
16 个解决方案
#1
171
In reality, you can't. But you can make it harder to download.
在现实中,你不可以。但是你可以让下载变得更加困难。
Browsers make grabbing too easy
Because that's what browsers were designed to do: Serve content - which means give the content to the user. To show you how easy it is, here's how I usually grab videos on virtually any video streaming site:
因为浏览器就是这么设计的:服务内容——这意味着把内容给用户。为了向你展示这有多简单,以下是我通常在任何视频流媒体网站上抓取视频的方法:
Prepare the network tab of your preferred browser debugger and let the video load. Then look for it in the loaded resources. Videos are usually streamed in .flv or .mp4, and audio in .mp3. When you spot the url, open a new tab/window and open the link there. The browser will then download the file.
准备首选浏览器调试器的network选项卡,让视频加载。然后在加载的资源中查找它。视频通常在.flv或.mp4中播放,在.mp3中播放。找到url后,打开一个新的选项卡/窗口并在那里打开链接。然后浏览器将下载该文件。
Making it harder
Here are methods on making a grabber's life harder. Like I said earlier, these are not fool-proof methods, but can at least ward off skiddies.
这里有一些方法可以让grabber的生活更加艰难。就像我之前说过的,这些方法不是简单的方法,但至少可以预防skiddies。
Video to Canvas technique
Recently I came across this article from HTML5Doctor while researching motion detection in JS. This involves streaming your video via a <video>
, then with some JS, literally copy the video to a <canvas>
. Here's an example where the video is up front, while the canvas at the back get's fed with data from that same video.
最近,我在研究JS中的运动检测时偶然发现了HTML5Doctor的这篇文章。这包括通过
Essentially, what you do is:
本质上,你要做的是:
- Predefine on the HTML or dynamically insert a
<canvas>
to the DOM. This is the "player" that the user sees. - 在HTML中预先定义或动态地将一个
- Dynamically create a video tag via JS, append it to the DOM hidden and give it a url to stream. This will be the video source for the canvas.
- 通过JS动态创建视频标记,将其附加到隐藏的DOM中,并为其提供流的url。这将是画布的视频源。
- Then with JS, you periodically grab data from the
<video>
you just created and draw it to the<canvas>
. With this step, the video gets fed to the canvas. - 然后使用JS,定期从刚才创建的
That's the very basic of the entire routine. Since your player is now the canvas and the true video hidden, you can try right-clicking all you want and save. Since the canvas acts like an image on the page, you can only save a shot of a frame that was displayed on the canvas. As for controls, JS has an API for controlling <video>
so you can create custom buttons and sliders.
这是整个程序最基本的部分。由于您的播放器现在是画布和真正的视频隐藏,您可以尝试右键单击您想要的并保存。由于画布的作用类似于页面上的图像,您只能保存显示在画布上的框架的一个快照。至于控件,JS有一个用于控制
However, if they know you are doing this, they will find your hidden video element, and you are screwed. This leads us to the next method that complements this front-end only technique, with aid from the server side.
但是,如果他们知道你在做这个,他们会找到你隐藏的视频元素,你就完蛋了。这将引导我们到下一个方法,该方法在服务器端帮助下补充这种前端技术。
Temporary resource urls
One thing you can do to prevent this method is to prevent the link from being reusable. Make the link disposable, temporary, one-time use only. Once the player loads using the disposable url, dispose of it. Make it unusable.
要防止这种方法,您可以做的一件事是防止链接被重用。使链接一次性,临时,一次性使用。一旦玩家使用一次性url加载,就可以处理它。让它无法使用。
Similar to CSRF prevention, when a browser requests a page with your video, have it generate a random token and store it in some storage on the server side for later reference. At the same time, append it to the url of your video, something like this:
与CSRF预防类似,当浏览器用您的视频请求一个页面时,让它生成一个随机的令牌并将其存储在服务器端的某个存储中,以供以后参考。同时,将它附加到视频的url中,如下所示:
//we load some video with id 1234324 from your site using this url
//and the token generated on page load is appended as sid
http://yoursite.com/media.php?video_id=1234324&sid=a0s9d8a98a0d98asd09809wq0e9
Now when your player loads the video, it will use this url that carries the token. Have the server validate the token.
现在,当你的播放器加载视频时,它会使用这个带有令牌的url。让服务器验证令牌。
If it's good, stream the video and destroy the token from the server to avoid reuse. This essentially makes the url "one time use only". If an invalid token is used, return the appropriate headers as the response, like a 403 perhaps.
如果它是好的,可以流视频并从服务器上销毁令牌,以避免重用。这实质上使url“一次性使用”。如果使用了无效的令牌,则返回相应的header作为响应,比如403。
To add a bit more security, impose an expiry of the url by storing it's timestamp along with the token. Then compare the request timestamp with the stored timestamp if it's still within the "use window". Make this "use window" short enough to be used by the player on the page, but not long enough for a skiddie to grab that url and paste it into another tab/window/downloader.
要增加一点安全性,可以将url的时间戳和令牌一起存储,从而使url过期。然后,如果请求时间戳仍然在“使用”窗口内,则将它与存储的时间戳进行比较。让这个“使用窗口”足够短以供页面上的播放器使用,但不够长以使skiddie能够抓取该url并将其粘贴到另一个tab/window/downloader中。
#2
97
This is a simple solution for those wishing to simply remove the right-click "save" option from the html5 videos
对于那些希望从html5视频中删除右键单击“保存”选项的人来说,这是一个简单的解决方案
$(document).ready(function(){
$('#videoElementID').bind('contextmenu',function() { return false; });
});
#3
30
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.
你可以让他们慢下来,但不能阻止他们。
#4
20
The best way that I usually use is very simple, I fully disable context menu in the whole page, pure html+javascript:
我通常使用的最佳方式是非常简单的,我完全禁用整个页面中的上下文菜单,纯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.
就是这样!我这样做是因为你总是可以通过右键看到源文件。好吧,你说:“我可以直接使用浏览器查看源”,这是真的,但是我们从你不能停止下载html5视频的事实开始。
#5
16
Yes, you can do this in three steps:
- 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.mp4www.foo.com/player.html www.foo.com/videos/video.mp4
-
Save a file in that subdirectory named ".htaccess" and add the lines below.
在名为“”的子目录中保存一个文件。并添加下面的行。
www.foo.com/videos/.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]
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.
现在源链接是无用的,但是我们仍然需要确保任何试图下载文件的用户不能直接服务于文件。
-
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:
要获得更完整的解决方案,请使用flash player(或html canvas)提供视频,并且不要直接链接到视频。要删除右击菜单,请添加到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:
www.foo.com/player.html将正确地播放视频,但是如果你访问www.foo.com/videos/video.mp4:):
Error Code 403: FORBIDDEN
错误代码403:被禁止的
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."
这是对这两个问题的完整回答,而不是对这个问题的回答:“我能阻止用户下载他们已经下载的视频吗?”
#6
10
PHP sends the html5 video tag together with a session where the key is a random string and the value is the filename.
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>';
Now PHP is asked to send the video. PHP recovers the filename; deletes the session and sends the video instantly. Additionally all the 'no cache' and mime-type headers must be present.
现在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:
Now if the user copy the url in a new tab or use the context menu he will have no luck.
现在,如果用户将url复制到一个新的选项卡中,或者使用上下文菜单,他就不会有什么好运气了。
#7
8
YES YOU CAN :
是的,您可以:
As a client side developer I recommend to use blob URL, blob URL is a client side URL which refer a binary object
作为客户端开发人员,我建议使用blob URL, blob URL是指引用二进制对象的客户端URL
<video id="id" width="320" height="240" type='video/mp4' controls > </video>
in html leave your video src
blank, and in JS fetch the video file using AJAX , make sure the response type is blob
在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();
}
#8
5
You can at least stop the the non-tech savvy people from using the right-click context menu to download your video. You can disable the context menu for any element using the oncontextmenu attribute.
你至少可以阻止那些不懂技术的人使用右键单击上下文菜单来下载你的视频。可以使用oncontextmenu属性禁用任何元素的上下文菜单。
oncontextmenu="return false;"
This works for the body element (whole page) or just a single video using it inside the video tag.
这适用于body元素(整个页面),也适用于在视频标签中使用它的单个视频。
<video oncontextmenu="return false;" controls>...</video>
#9
3
+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.
+1简单的跨浏览器方式:你也可以用css z-index和不透明度把透明图片放在视频上。因此,用户将在上下文菜单中看到“save picture as”而不是“save video”。
#10
1
Using a service such as Vimeo: Sign in Vimeo > Goto Video > Settings > Privacy > Mark as Secured
, and also select embed domains. Once the embed domains are set, it will not allow anyone to embed the video or display it from the browser unless connecting from the domains specified. So, if you have a page that is secured on your server which loads the Vimeo player in iframe, this makes it pretty difficult to get around.
使用Vimeo这样的服务:在Vimeo > Goto视频>设置>隐私>标记为安全,并选择嵌入域。一旦嵌入域被设置,它将不允许任何人嵌入视频或从浏览器显示它,除非从指定的域连接。所以,如果你的服务器上有一个安全的页面,它在iframe中加载Vimeo播放器,这使得你很难绕过它。
#11
1
We ended up using AWS CloudFront with expiring URLs. The video will load, but by the time the user right clicks and chooses Save As the video url they initially received has expired. Do a search for CloudFront Origin Access Identity.
我们最终使用了AWS CloudFront和过期url。视频将被加载,但是当用户点击并选择Save时,他们最初收到的视频url已经过期。搜索CloudFront访问标识。
Producing the video url requires a key pair which can be created in the AWS CLI. FYI this is not my code but it works great!
生成视频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>';
#12
1
First of all realise it is impossible to completely prevent a video being downloaded, all you can do is make it more difficult. I.e. you hide the source of the video.
首先要意识到不可能完全阻止视频被下载,你所能做的就是让它变得更加困难。也就是隐藏视频的来源。
A web browser temporarily downloads the video in a buffer, so if could prevent download you would also be preventing the video being viewed as well.
网络浏览器会临时在缓存中下载视频,所以如果可以阻止下载,你也会阻止视频被浏览。
You should also know that <1% of the total population of the world will be able to understand the source code making it rather safe anyway. That does not mean you should not hide it in the source as well - you should.
您还应该知道,<1%的世界人口将能够理解源代码,使其变得相当安全。这并不意味着你也不应该将它隐藏在源代码中——你应该这样做。
You should not disable right click, and even less you should display a message saying "You cannot save this video for copyright reasons. Sorry about that."
. As suggested in this answer.
你不应该禁用右击,更不用说你应该显示一条消息:“由于版权原因,你不能保存这个视频。”抱歉。”。正如这个答案中所暗示的。
This can be very annoying and confusing for the user. Apart from that; if they disable JavaScript on their browser they will be able to right click and save anyway.
这对用户来说是非常烦人和令人困惑的。除此之外;如果他们在浏览器上禁用JavaScript,他们将能够右键单击并保存。
Here is a CSS trick you could use:
这里有一个CSS技巧你可以使用:
video {
pointer-events: none;
}
CSS cannot be turned off in browser, protecting your video without actually disabling right click. However one problem is that controls
cannot be enabled either, in other words they must be set to false
. If you are going to inplament your own Play/Pause function or use an API that has buttons separate to the video
tag then this is a feasible option.
在浏览器中无法关闭CSS,在不禁用右键的情况下保护您的视频。然而,一个问题是控件也不能被启用,换句话说,它们必须被设置为false。如果您打算使用自己的Play/Pause函数,或者使用与视频标记单独的按钮的API,那么这是一个可行的选择。
controls
also has a download button so using it is not such a good idea either.
控件也有一个下载按钮,所以使用它也不是一个好主意。
Here is a JSFiddle example.
这里有一个JSFiddle示例。
If you are going to disable right click using JavaScript then also store the source of the video in JavaScript as well. That way if the user disables JavaScript (allowing right click) the video will not load (it also hides the video source a little better).
如果要禁用使用JavaScript的右击,那么也要用JavaScript存储视频的源代码。这样,如果用户禁用JavaScript(允许右击),视频就不会被加载(它也会更好地隐藏视频源)。
From TxRegex answer:
从TxRegex回答:
<video oncontextmenu="return false;" controls>
<source type="video/mp4" id="video">
</video>
Now add the video via JavaScript:
现在通过JavaScript添加视频:
document.getElementById("video").src = "https://www.w3schools.com/html/mov_bbb.mp4";
Functional JSFiddle
功能性JSFiddle
Another way to prevent right click involves using the embed
tag. This is does not however provide the controls to run the video so they would need to be inplamented in JavaScript:
另一种防止右击的方法是使用embed标签。但是,这并没有提供运行视频的控件,因此需要在JavaScript中嵌入:
<embed src="https://www.w3schools.com/html/mov_bbb.mp4"></embed>
#13
1
The
的
<body oncontextmenu="return false;">
no longer works. Chrome and Opera as of June 2018 has a submenu on the timeline to allow straight download, so user doesn't need to right click to download that video. Interestingly Firefox and Edge don't have this ...
不再有效。到2018年6月为止,Chrome和Opera在时间轴上有一个子菜单允许直接下载,所以用户不需要右键点击下载视频。有趣的是火狐和Edge没有这个…
#14
0
It seems like streaming the video through websocket is a viable option, as in stream the frames and draw them on a canvas sort of thing.
看起来通过websocket流视频是一个可行的选择,就像在流框中一样,把它们画在画布上。
Video streaming over websockets using JavaScript
使用JavaScript在websockets上的视频流
I think that would provide another level of protection making it more difficult for the client to acquire the video and of course solve your problem with "Save video as..." right-click context menu option ( overkill ?! ).
我认为这将提供另一个层次的保护,使客户更难获得视频,当然解决你的问题“以…保存视频”右键单击上下文菜单选项(超杀?!)
#15
0
Here's what I did:
这是我所做的:
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>
#16
-1
@Clayton-Graul had what I was looking for, except I needed the CoffeeScript version for a site using AngularJS. Just in case you need that too, here's what you put in the AngularJS controller in question:
@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
"strange things are afoot at the circle k" (it's true)
“奇怪的事情在k圈里发生”(这是真的)
#1
171
In reality, you can't. But you can make it harder to download.
在现实中,你不可以。但是你可以让下载变得更加困难。
Browsers make grabbing too easy
Because that's what browsers were designed to do: Serve content - which means give the content to the user. To show you how easy it is, here's how I usually grab videos on virtually any video streaming site:
因为浏览器就是这么设计的:服务内容——这意味着把内容给用户。为了向你展示这有多简单,以下是我通常在任何视频流媒体网站上抓取视频的方法:
Prepare the network tab of your preferred browser debugger and let the video load. Then look for it in the loaded resources. Videos are usually streamed in .flv or .mp4, and audio in .mp3. When you spot the url, open a new tab/window and open the link there. The browser will then download the file.
准备首选浏览器调试器的network选项卡,让视频加载。然后在加载的资源中查找它。视频通常在.flv或.mp4中播放,在.mp3中播放。找到url后,打开一个新的选项卡/窗口并在那里打开链接。然后浏览器将下载该文件。
Making it harder
Here are methods on making a grabber's life harder. Like I said earlier, these are not fool-proof methods, but can at least ward off skiddies.
这里有一些方法可以让grabber的生活更加艰难。就像我之前说过的,这些方法不是简单的方法,但至少可以预防skiddies。
Video to Canvas technique
Recently I came across this article from HTML5Doctor while researching motion detection in JS. This involves streaming your video via a <video>
, then with some JS, literally copy the video to a <canvas>
. Here's an example where the video is up front, while the canvas at the back get's fed with data from that same video.
最近,我在研究JS中的运动检测时偶然发现了HTML5Doctor的这篇文章。这包括通过
Essentially, what you do is:
本质上,你要做的是:
- Predefine on the HTML or dynamically insert a
<canvas>
to the DOM. This is the "player" that the user sees. - 在HTML中预先定义或动态地将一个
- Dynamically create a video tag via JS, append it to the DOM hidden and give it a url to stream. This will be the video source for the canvas.
- 通过JS动态创建视频标记,将其附加到隐藏的DOM中,并为其提供流的url。这将是画布的视频源。
- Then with JS, you periodically grab data from the
<video>
you just created and draw it to the<canvas>
. With this step, the video gets fed to the canvas. - 然后使用JS,定期从刚才创建的
That's the very basic of the entire routine. Since your player is now the canvas and the true video hidden, you can try right-clicking all you want and save. Since the canvas acts like an image on the page, you can only save a shot of a frame that was displayed on the canvas. As for controls, JS has an API for controlling <video>
so you can create custom buttons and sliders.
这是整个程序最基本的部分。由于您的播放器现在是画布和真正的视频隐藏,您可以尝试右键单击您想要的并保存。由于画布的作用类似于页面上的图像,您只能保存显示在画布上的框架的一个快照。至于控件,JS有一个用于控制
However, if they know you are doing this, they will find your hidden video element, and you are screwed. This leads us to the next method that complements this front-end only technique, with aid from the server side.
但是,如果他们知道你在做这个,他们会找到你隐藏的视频元素,你就完蛋了。这将引导我们到下一个方法,该方法在服务器端帮助下补充这种前端技术。
Temporary resource urls
One thing you can do to prevent this method is to prevent the link from being reusable. Make the link disposable, temporary, one-time use only. Once the player loads using the disposable url, dispose of it. Make it unusable.
要防止这种方法,您可以做的一件事是防止链接被重用。使链接一次性,临时,一次性使用。一旦玩家使用一次性url加载,就可以处理它。让它无法使用。
Similar to CSRF prevention, when a browser requests a page with your video, have it generate a random token and store it in some storage on the server side for later reference. At the same time, append it to the url of your video, something like this:
与CSRF预防类似,当浏览器用您的视频请求一个页面时,让它生成一个随机的令牌并将其存储在服务器端的某个存储中,以供以后参考。同时,将它附加到视频的url中,如下所示:
//we load some video with id 1234324 from your site using this url
//and the token generated on page load is appended as sid
http://yoursite.com/media.php?video_id=1234324&sid=a0s9d8a98a0d98asd09809wq0e9
Now when your player loads the video, it will use this url that carries the token. Have the server validate the token.
现在,当你的播放器加载视频时,它会使用这个带有令牌的url。让服务器验证令牌。
If it's good, stream the video and destroy the token from the server to avoid reuse. This essentially makes the url "one time use only". If an invalid token is used, return the appropriate headers as the response, like a 403 perhaps.
如果它是好的,可以流视频并从服务器上销毁令牌,以避免重用。这实质上使url“一次性使用”。如果使用了无效的令牌,则返回相应的header作为响应,比如403。
To add a bit more security, impose an expiry of the url by storing it's timestamp along with the token. Then compare the request timestamp with the stored timestamp if it's still within the "use window". Make this "use window" short enough to be used by the player on the page, but not long enough for a skiddie to grab that url and paste it into another tab/window/downloader.
要增加一点安全性,可以将url的时间戳和令牌一起存储,从而使url过期。然后,如果请求时间戳仍然在“使用”窗口内,则将它与存储的时间戳进行比较。让这个“使用窗口”足够短以供页面上的播放器使用,但不够长以使skiddie能够抓取该url并将其粘贴到另一个tab/window/downloader中。
#2
97
This is a simple solution for those wishing to simply remove the right-click "save" option from the html5 videos
对于那些希望从html5视频中删除右键单击“保存”选项的人来说,这是一个简单的解决方案
$(document).ready(function(){
$('#videoElementID').bind('contextmenu',function() { return false; });
});
#3
30
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.
你可以让他们慢下来,但不能阻止他们。
#4
20
The best way that I usually use is very simple, I fully disable context menu in the whole page, pure html+javascript:
我通常使用的最佳方式是非常简单的,我完全禁用整个页面中的上下文菜单,纯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.
就是这样!我这样做是因为你总是可以通过右键看到源文件。好吧,你说:“我可以直接使用浏览器查看源”,这是真的,但是我们从你不能停止下载html5视频的事实开始。
#5
16
Yes, you can do this in three steps:
- 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.mp4www.foo.com/player.html www.foo.com/videos/video.mp4
-
Save a file in that subdirectory named ".htaccess" and add the lines below.
在名为“”的子目录中保存一个文件。并添加下面的行。
www.foo.com/videos/.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]
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.
现在源链接是无用的,但是我们仍然需要确保任何试图下载文件的用户不能直接服务于文件。
-
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:
要获得更完整的解决方案,请使用flash player(或html canvas)提供视频,并且不要直接链接到视频。要删除右击菜单,请添加到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:
www.foo.com/player.html将正确地播放视频,但是如果你访问www.foo.com/videos/video.mp4:):
Error Code 403: FORBIDDEN
错误代码403:被禁止的
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."
这是对这两个问题的完整回答,而不是对这个问题的回答:“我能阻止用户下载他们已经下载的视频吗?”
#6
10
PHP sends the html5 video tag together with a session where the key is a random string and the value is the filename.
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>';
Now PHP is asked to send the video. PHP recovers the filename; deletes the session and sends the video instantly. Additionally all the 'no cache' and mime-type headers must be present.
现在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:
Now if the user copy the url in a new tab or use the context menu he will have no luck.
现在,如果用户将url复制到一个新的选项卡中,或者使用上下文菜单,他就不会有什么好运气了。
#7
8
YES YOU CAN :
是的,您可以:
As a client side developer I recommend to use blob URL, blob URL is a client side URL which refer a binary object
作为客户端开发人员,我建议使用blob URL, blob URL是指引用二进制对象的客户端URL
<video id="id" width="320" height="240" type='video/mp4' controls > </video>
in html leave your video src
blank, and in JS fetch the video file using AJAX , make sure the response type is blob
在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();
}
#8
5
You can at least stop the the non-tech savvy people from using the right-click context menu to download your video. You can disable the context menu for any element using the oncontextmenu attribute.
你至少可以阻止那些不懂技术的人使用右键单击上下文菜单来下载你的视频。可以使用oncontextmenu属性禁用任何元素的上下文菜单。
oncontextmenu="return false;"
This works for the body element (whole page) or just a single video using it inside the video tag.
这适用于body元素(整个页面),也适用于在视频标签中使用它的单个视频。
<video oncontextmenu="return false;" controls>...</video>
#9
3
+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.
+1简单的跨浏览器方式:你也可以用css z-index和不透明度把透明图片放在视频上。因此,用户将在上下文菜单中看到“save picture as”而不是“save video”。
#10
1
Using a service such as Vimeo: Sign in Vimeo > Goto Video > Settings > Privacy > Mark as Secured
, and also select embed domains. Once the embed domains are set, it will not allow anyone to embed the video or display it from the browser unless connecting from the domains specified. So, if you have a page that is secured on your server which loads the Vimeo player in iframe, this makes it pretty difficult to get around.
使用Vimeo这样的服务:在Vimeo > Goto视频>设置>隐私>标记为安全,并选择嵌入域。一旦嵌入域被设置,它将不允许任何人嵌入视频或从浏览器显示它,除非从指定的域连接。所以,如果你的服务器上有一个安全的页面,它在iframe中加载Vimeo播放器,这使得你很难绕过它。
#11
1
We ended up using AWS CloudFront with expiring URLs. The video will load, but by the time the user right clicks and chooses Save As the video url they initially received has expired. Do a search for CloudFront Origin Access Identity.
我们最终使用了AWS CloudFront和过期url。视频将被加载,但是当用户点击并选择Save时,他们最初收到的视频url已经过期。搜索CloudFront访问标识。
Producing the video url requires a key pair which can be created in the AWS CLI. FYI this is not my code but it works great!
生成视频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>';
#12
1
First of all realise it is impossible to completely prevent a video being downloaded, all you can do is make it more difficult. I.e. you hide the source of the video.
首先要意识到不可能完全阻止视频被下载,你所能做的就是让它变得更加困难。也就是隐藏视频的来源。
A web browser temporarily downloads the video in a buffer, so if could prevent download you would also be preventing the video being viewed as well.
网络浏览器会临时在缓存中下载视频,所以如果可以阻止下载,你也会阻止视频被浏览。
You should also know that <1% of the total population of the world will be able to understand the source code making it rather safe anyway. That does not mean you should not hide it in the source as well - you should.
您还应该知道,<1%的世界人口将能够理解源代码,使其变得相当安全。这并不意味着你也不应该将它隐藏在源代码中——你应该这样做。
You should not disable right click, and even less you should display a message saying "You cannot save this video for copyright reasons. Sorry about that."
. As suggested in this answer.
你不应该禁用右击,更不用说你应该显示一条消息:“由于版权原因,你不能保存这个视频。”抱歉。”。正如这个答案中所暗示的。
This can be very annoying and confusing for the user. Apart from that; if they disable JavaScript on their browser they will be able to right click and save anyway.
这对用户来说是非常烦人和令人困惑的。除此之外;如果他们在浏览器上禁用JavaScript,他们将能够右键单击并保存。
Here is a CSS trick you could use:
这里有一个CSS技巧你可以使用:
video {
pointer-events: none;
}
CSS cannot be turned off in browser, protecting your video without actually disabling right click. However one problem is that controls
cannot be enabled either, in other words they must be set to false
. If you are going to inplament your own Play/Pause function or use an API that has buttons separate to the video
tag then this is a feasible option.
在浏览器中无法关闭CSS,在不禁用右键的情况下保护您的视频。然而,一个问题是控件也不能被启用,换句话说,它们必须被设置为false。如果您打算使用自己的Play/Pause函数,或者使用与视频标记单独的按钮的API,那么这是一个可行的选择。
controls
also has a download button so using it is not such a good idea either.
控件也有一个下载按钮,所以使用它也不是一个好主意。
Here is a JSFiddle example.
这里有一个JSFiddle示例。
If you are going to disable right click using JavaScript then also store the source of the video in JavaScript as well. That way if the user disables JavaScript (allowing right click) the video will not load (it also hides the video source a little better).
如果要禁用使用JavaScript的右击,那么也要用JavaScript存储视频的源代码。这样,如果用户禁用JavaScript(允许右击),视频就不会被加载(它也会更好地隐藏视频源)。
From TxRegex answer:
从TxRegex回答:
<video oncontextmenu="return false;" controls>
<source type="video/mp4" id="video">
</video>
Now add the video via JavaScript:
现在通过JavaScript添加视频:
document.getElementById("video").src = "https://www.w3schools.com/html/mov_bbb.mp4";
Functional JSFiddle
功能性JSFiddle
Another way to prevent right click involves using the embed
tag. This is does not however provide the controls to run the video so they would need to be inplamented in JavaScript:
另一种防止右击的方法是使用embed标签。但是,这并没有提供运行视频的控件,因此需要在JavaScript中嵌入:
<embed src="https://www.w3schools.com/html/mov_bbb.mp4"></embed>
#13
1
The
的
<body oncontextmenu="return false;">
no longer works. Chrome and Opera as of June 2018 has a submenu on the timeline to allow straight download, so user doesn't need to right click to download that video. Interestingly Firefox and Edge don't have this ...
不再有效。到2018年6月为止,Chrome和Opera在时间轴上有一个子菜单允许直接下载,所以用户不需要右键点击下载视频。有趣的是火狐和Edge没有这个…
#14
0
It seems like streaming the video through websocket is a viable option, as in stream the frames and draw them on a canvas sort of thing.
看起来通过websocket流视频是一个可行的选择,就像在流框中一样,把它们画在画布上。
Video streaming over websockets using JavaScript
使用JavaScript在websockets上的视频流
I think that would provide another level of protection making it more difficult for the client to acquire the video and of course solve your problem with "Save video as..." right-click context menu option ( overkill ?! ).
我认为这将提供另一个层次的保护,使客户更难获得视频,当然解决你的问题“以…保存视频”右键单击上下文菜单选项(超杀?!)
#15
0
Here's what I did:
这是我所做的:
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>
#16
-1
@Clayton-Graul had what I was looking for, except I needed the CoffeeScript version for a site using AngularJS. Just in case you need that too, here's what you put in the AngularJS controller in question:
@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
"strange things are afoot at the circle k" (it's true)
“奇怪的事情在k圈里发生”(这是真的)