js视频加密防下载解决方案
如今视频越来越多,好不容易录制的视频,人家一键就下载了,那么怎么保护自己制作的视频让人家没那么容易破解并下载呢
我的思路是这样的:
视频播放器需要获取是地址才能完成播放,如果采用分片播放的形式,将视频文件切片保存在服务端,客户端分片播放视频,加快了播放的速度
第一步将视频上传只视频服务器,通过ffmpeg对视频进行切片存储,hls
ffmpeg -i output.mp4 -c:v libx264 -c:a aac -strict -2 -f hls -hls_list_size 0 -hls_time 5 output1.m3u8
ffmpeg转化成HLS时附带的指令 ,以H264和AAC的形式对视频进行输出
-hls_time n: 设置每片的长度,默认值为2。单位为秒
-hls_list_size n:设置播放列表保存的最多条目,设置为0会保存有所片信息,默认值为5
-hls_wrap n:设置多少片之后开始覆盖,如果设置为0则不会覆盖,默认值为0.这个选项能够避免在磁盘上存储过多的片,而且能够限制写入磁盘的最多的片的数量
-hls_start_number n:设置播放列表中sequence number的值为number,默认值为0
第二步,对视频切片文件进行二进制文件加密
<?php /* * AES 算法 */ class Aes { private $hex_iv = '00000000000000000000000000000000'; private $key = '397e2eb61307109f6e68006ebcb62f98'; function __construct($key) { $this->key = $key; $this->key = hash('sha256', $this->key, true); } /* * 字符串加密 不写入文件 */ public function encrypt($input) { $data = openssl_encrypt($input, 'AES-256-CBC', $this->key, OPENSSL_RAW_DATA, $this->hexToStr($this->hex_iv)); $data = base64_encode($data); return $data; } /* * aes 给PHP文件加密 * 写入设置文件 */ public function filecrypt($filename) { $type=strtolower(substr(strrchr($filename,'.'),1)); if ('php' == $type && is_file($filename) && is_writable($filename)) { $contents = file_get_contents($filename); // echo $contents;exit; $contents = php_strip_whitespace($filename); // echo $contents;exit; // $headerPos = strpos($contents,'<?php'); // echo $headerPos;exit; // $contents = substr($contents, $headerPos + 5, $footerPos - $headerPos); // echo $contents;exit; $data = openssl_encrypt($contents, 'AES-256-CBC', $this->key, OPENSSL_RAW_DATA, $this->hexToStr($this->hex_iv)); // echo $data;exit; $data = base64_encode($data); // echo $data;exit; return file_put_contents($filename, $data); } return false; } /* * 字符串解密 */ public function decrypt($input) { $decrypted = openssl_decrypt(base64_decode($input), 'AES-256-CBC', $this->key, OPENSSL_RAW_DATA, $this->hexToStr($this->hex_iv)); return $decrypted; } /* For PKCS7 padding */ private function addpadding($string, $blocksize = 16) { $len = strlen($string); $pad = $blocksize - ($len % $blocksize); $string .= str_repeat(chr($pad), $pad); return $string; } private function strippadding($string) { $slast = ord(substr($string, -1)); $slastc = chr($slast); $pcheck = substr($string, -$slast); if (preg_match("/$slastc{" . $slast . "}/", $string)) { $string = substr($string, 0, strlen($string) - $slast); return $string; } else { return false; } } function hexToStr($hex) { $string=''; for ($i=0; $i < strlen($hex)-1; $i+=2) { $string .= chr(hexdec($hex[$i].$hex[$i+1])); } return $string; } } $key = '397e2eb61307109f6e68006ebcb62f98'; $aes = new Aes($key); $filename = __DIR__.'\bfw.php'; // 加密 $string = $aes->filecrypt($filename); echo "OK,加密完成!" ; ?>
第三步,播放的时候先获取整个切片的url列表,然后加载第一段切片视频并解密后进行浏览器播放,同时下载第二段视频,检测第一段视频播放结束后立即播放第二段视频,以此类推。
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>BFW NEW PAGE</title> <script id="bfwone" data="dep=jquery.17|crypto-js-3.1.9-1/crypto-js|crypto-js-3.1.9-1/pad-zeropadding&err=0" type="text/javascript" src="http://repo.bfw.wiki/bfwrepo/js/bfwone.js"></script> <script type="text/javascript"> function getKey() { //先获取加密的秘钥,通过rsa方式 return "key"; } bready(function() { var key = getKey(); //先获取加密的秘钥,通过rsa方式 var xhr = new XMLHttpRequest(); xhr.open('GET', 'video/silice_01.mp4', true); xhr.responseType = 'blob'; xhr.onload = function(e) { if (this.status == 200) { //然后加载第一段视频进行解密并播放 var videoblob = this.response; var decryptedvideo = CryptoJS.AES.decrypt(videoblob, key) .toString(CryptoJS.enc.Latin1); $("#player").attr('src', decryptedvideo); } }; xhr.send(); }); </script> </head> <body> <video id="player" src=""></video> </body> </html>
网友评论0