javascript - oncontextmenu - Evite que se descargue video HTML5(haga clic con el botón derecho guardado)?
document oncontextmenu function() return false (15)
Sí, puedes hacer esto en tres pasos:
- Coloque los archivos que desea proteger en un subdirectorio del directorio donde se está ejecutando su código.
www.foo.com/player.html
www.foo.com/videos/video.mp4 Guarde un archivo en ese subdirectorio llamado ".htaccess" y agregue las líneas a continuación.
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]
Ahora el enlace fuente es inútil , pero aún debemos asegurarnos de que ningún usuario que intente descargar el archivo no pueda ser servido directamente en el archivo.
Para una solución más completa , ahora sirva el video con un reproductor flash (o lienzo html) y nunca lo vincule al video directamente. Para eliminar el menú del botón derecho, agregue a su HTML:
<body oncontextmenu="return false;">
El resultado:
www.foo.com/player.html reproducirá correctamente el video , pero si visita www.foo.com/videos/video.mp4:
Código de error 403: PROHIBIDO
Esto funcionará para descarga directa, cURL, hotlinking, lo que sea.
Esta es una respuesta completa a las dos preguntas formuladas y no a la pregunta: "puedo evitar que un usuario descargue un video que ya descargó".
¿Cómo puedo desactivar "Guardar video como ..." desde el menú contextual de un navegador para evitar que los clientes descarguen un video?
¿Hay soluciones más completas que evitan que el cliente acceda directamente a una ruta de archivo?
@ Clayton-Graul tenía lo que estaba buscando, excepto que necesitaba la versión de CoffeeScript para un sitio que utilizaba AngularJS. En caso de que lo necesites también, esto es lo que pones en el controlador AngularJS en cuestión:
# 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
"cosas extrañas están en marcha en el círculo k" (es verdad)
Al menos puede evitar que las personas no conocedoras de la tecnología utilicen el menú contextual del botón derecho para descargar su video. Puede deshabilitar el menú contextual para cualquier elemento usando el atributo oncontextmenu.
oncontextmenu="return false;"
Esto funciona para el elemento del cuerpo (página completa) o solo un video usando dentro de la etiqueta del video.
<video oncontextmenu="return false;" controls>...</video>
En primer lugar , tenga en cuenta que es imposible evitar completamente que se descargue un video, todo lo que puede hacer es hacerlo más difícil . Es decir, ocultas la fuente del video.
Un navegador web descarga temporalmente el video en un búfer, por lo que si se evita la descarga, también se evitaría que el video se visualice también.
También debe saber que <1% de la población total del mundo podrá comprender el código fuente, por lo que es bastante seguro. Eso no significa que no debas ocultarlo en la fuente también, deberías .
No debe deshabilitar el clic derecho, y aún menos debe mostrar un mensaje que diga "You cannot save this video for copyright reasons. Sorry about that."
. Como se sugiere en esta respuesta .
Esto puede ser muy molesto y confuso para el usuario. Aparte de eso; si deshabilitan JavaScript en su navegador , podrán hacer clic derecho y guardar de todos modos.
Aquí hay un truco de CSS que puedes usar:
video {
pointer-events: none;
}
CSS no se puede desactivar en el navegador, protegiendo su video sin deshabilitar el clic derecho. Sin embargo, un problema es que los controls
tampoco se pueden habilitar, en otras palabras, se deben establecer en false
. Si va a instalar su propia función Reproducir / Pausa o usar una API que tiene botones separados a la etiqueta de video
entonces esta es una opción viable.
controls
también tiene un botón de descarga, por lo que su uso tampoco es una buena idea.
Aquí hay un ejemplo de JSFiddle .
Si va a deshabilitar el clic derecho usando JavaScript, también almacene también el código fuente en JavaScript. De esta forma, si el usuario deshabilita JavaScript (permitiendo el clic derecho), el video no se cargará (también oculta un poco mejor la fuente de video).
Desde la respuesta de TxRegex :
<video oncontextmenu="return false;" controls>
<source type="video/mp4" id="video">
</video>
Ahora agrega el video a través de JavaScript:
document.getElementById("video").src = "https://www.w3schools.com/html/mov_bbb.mp4";
Functional JSFiddle
Otra forma de evitar el clic derecho consiste en utilizar la etiqueta de embed
. Sin embargo, esto no proporciona los controles para ejecutar el video, por lo que deberían insertarse en JavaScript:
<embed src="https://www.w3schools.com/html/mov_bbb.mp4"></embed>
En realidad, no puedes . Pero puedes hacer que sea más difícil de descargar .
Los navegadores hacen que el acaparamiento sea demasiado fácil
Porque eso es lo que los navegadores fueron diseñados para hacer: servir contenido , lo que significa dar el contenido al usuario . Para mostrarle lo fácil que es, así es como generalmente tomo videos en prácticamente cualquier sitio de transmisión de video :
Prepare la pestaña de red de su depurador de navegador preferido y deje que se cargue el video. Luego búscalo en los recursos cargados. Los videos generalmente se transmiten en .flv o .mp4, y audio en .mp3. Cuando veas la url, abre una nueva pestaña / ventana y abre el enlace allí. El navegador luego descargará el archivo.
Haciéndolo más difícil
Aquí hay métodos para hacer la vida de un grabber más difícil. Como dije antes, estos no son métodos infalibles, pero al menos pueden evitar skiddies.
Técnica de video a lienzo
Recientemente me encontré con este artículo de HTML5Doctor mientras investigaba la detección de movimiento en JS. Esto implica la transmisión de su video a través de un <video>
, luego con algunos JS, literalmente copie el video a un <canvas>
. Aquí hay un ejemplo donde el video está en la delantera, mientras que el lienzo en la parte posterior se alimenta con datos de ese mismo video.
Esencialmente, lo que haces es:
- Predefina en el HTML o inserte dinámicamente un
<canvas>
al DOM. Este es el "jugador" que el usuario ve. - Cree dinámicamente una etiqueta de video a través de JS, añádala al DOM oculto y proporciónele una url para transmitir. Esta será la fuente de video para el lienzo.
- Luego, con JS, periódicamente toma datos del
<video>
que acaba de crear y lo dibuja en<canvas>
. Con este paso, el video se alimenta del lienzo.
Esa es la base de toda la rutina. Como tu jugador ahora es el lienzo y el verdadero video oculto, puedes intentar hacer clic con el botón derecho en todo lo que quieras y guardar. Como el lienzo actúa como una imagen en la página, solo puede guardar una captura de un cuadro que se mostró en el lienzo. En cuanto a los controles, JS tiene una API para controlar <video>
para que pueda crear botones y controles deslizantes personalizados.
Sin embargo, si saben que estás haciendo esto, encontrarán tu elemento de video oculto, y estás jodido. Esto nos lleva al siguiente método que complementa esta técnica solo de front-end, con ayuda del lado del servidor.
Urls de recursos temporales
Una cosa que puede hacer para evitar este método es evitar que el enlace sea reutilizable . Haga que el enlace sea desechable, temporal, de una sola vez. Una vez que el jugador carga con la url desechable, deséchelo. Que sea inutilizable.
De forma similar a la prevención CSRF , cuando un navegador solicita una página con su video, haga que genere un token aleatorio y almacénelo en algún almacenamiento en el lado del servidor para referencia futura. Al mismo tiempo, agréguela a la URL de su video , algo como esto:
//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
Ahora cuando tu reproductor carga el video, usará esta url que lleva el token. Haga que el servidor valide el token.
Si es bueno, transmita el video y destruya el token del servidor para evitar su reutilización. Esto esencialmente hace que la url sea "de uso único por única vez". Si se utiliza un token no válido, devuelve los encabezados apropiados como respuesta , como un 403 quizás.
Para agregar un poco más de seguridad, impone un vencimiento de la url al almacenar su marca de tiempo junto con el token. Luego compare la marca de tiempo de solicitud con la marca de tiempo almacenada si todavía está dentro de la "ventana de uso". Haga que esta "ventana de uso" sea lo suficientemente corta como para ser utilizada por el jugador en la página, pero no lo suficiente como para que un skiddie tome esa url y la pegue en otra pestaña / ventana / descargador.
Esta es una solución simple para aquellos que desean simplemente eliminar la opción de "guardar" del botón derecho de los videos html5
$(document).ready(function(){
$(''#videoElementID'').bind(''contextmenu'',function() { return false; });
});
Esto es lo que hice:
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>
La mejor manera que suelo usar es muy simple, deshabilito completamente el menú contextual en toda la página, html + javascript puro:
<body oncontextmenu="return false;">
¡Eso es! Lo hago porque siempre se puede ver la fuente haciendo clic derecho.
Ok, dices: "Puedo usar directamente la fuente de visualización del navegador" y es cierto, pero partimos del hecho de que NO PUEDES detener la descarga de videos html5
.
Modo simple + 1 a través del navegador: también puede colocar una imagen transparente sobre el video con css z-index y opacidad. Por lo tanto, los usuarios verán "guardar imagen como" en lugar de "guardar video" en el menú contextual.
PHP envía la etiqueta de video html5 junto con una sesión donde la clave es una cadena aleatoria y el valor es el nombre del archivo.
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>'';
Ahora se le pide a PHP que envíe el video. PHP recupera el nombre de archivo; borra la sesión y envía el video al instante. Además, deben estar presentes todos los encabezados "sin caché" y tipo 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:
Ahora, si el usuario copia la URL en una nueva pestaña o utiliza el menú contextual, no tendrá suerte.
Parece que la transmisión del video a través de websocket es una opción viable, como transmitir los fotogramas y dibujarlos en un lienzo.
Transmisión de video a través de websockets con JavaScript
Creo que eso proporcionaría otro nivel de protección que dificultaría que el cliente adquiriera el video y, por supuesto, resolvería su problema con "Guardar video como ...", haga clic con el botón secundario en la opción del menú contextual (¿overkill?!).
Respuesta simple,
NO PUEDES
Si están viendo tu video, ya lo tienen
Puedes retrasarlos pero no puedes detenerlos.
Terminamos usando AWS CloudFront con URL expirantes. El video se cargará, pero cuando el usuario haga clic derecho y elija Guardar como, la url del video que inicialmente recibió ha expirado. Realice una búsqueda de la identidad de acceso de origen de CloudFront.
La producción de la URL del video requiere un par de claves que se puede crear en la CLI de AWS. ¡FYI este no es mi código pero funciona genial!
$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>'';
Utilizando un servicio como Vimeo: inicie sesión en Vimeo > Goto Video > Settings > Privacy > Mark as Secured
, y también seleccione dominios incrustados. Una vez establecidos los dominios de inserción, no permitirá que nadie incruste el video ni lo muestre desde el navegador a menos que se conecte desde los dominios especificados. Por lo tanto, si tiene una página segura en su servidor que carga el reproductor Vimeo en iframe, esto hace que sea bastante difícil de recorrer.
SÍ PUEDES :
Como desarrollador del lado del cliente, recomiendo usar blob URL, blob URL es una URL del lado del cliente que refiere un objeto binario
<video id="id" width="320" height="240" type=''video/mp4'' controls > </video>
en html deja tu video en blanco, y en JS busca el archivo de video usando AJAX, asegúrate de que el tipo de respuesta sea 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();
}