先说下原理:因为视频是付费的,肯定需要作视频加密处理。
加密可实现的方式:修改视频字节流,只能替换字节流,例如头100-1024字节进行加密,源文件就无法打开了。
下面上代码吧,加解密是
openssl_encrypt
openssl_decrypt
<?php /** * * Created by PhpStorm. * User: js * Date: 2021/04/15 * Time: 17:03 * PhpStorm */ namespace CoreModel\Payfilms; class Movie{ const KEY = 'jiangsheng'; const METHOD = 'des-ecb'; static function movieModify($filename){ $strLong = mt_rand(1,9); $str = self::randStr($strLong); // 字符串占位 $key = self::randStr(6); // key $Pkey = base64_encode($key); $fp = fopen($filename, 'r+') or die('文件打开失败!'); $bin = fread($fp, $strLong); //随机 $passStr = self::_encrypt($bin,$key); // 密文头 转存 // 判断是否是小写字母组成 $i = 0; while (!feof($fp)) { //修改第二行数据 if ($i == 0) { fseek($fp, 0);// 移动文件指针至偏移量处 fwrite($fp, $str); break; } fgets($fp); $i++; } fclose($fp); return [ 'key'=>$key, 'Pkey'=>$Pkey, 'passStr'=>$passStr, 'str'=>$str, 'bin'=>$bin ]; } static function movieReduction($filename, $passStr, $Pkey){ $fp = fopen($filename, 'r+') or die('文件打开失败!'); $key = base64_decode($Pkey); $str = self::_decrypt($passStr,$key); $i = 0; while (!feof($fp)) { //修改第二行数据 if ($i == 0) { fseek($fp, 0);// 移动文件指针至偏移量处 fwrite($fp,$str); break; } fgets($fp); $i++; } fclose($fp); return true; } static function handOpen($filename){ $fp = fopen($filename, 'r') or die('文件打开失败!'); $content = fread($fp, filesize($filename)); return $content; } static function _encrypt($data, $key=self::KEY, $method=self::METHOD){ return openssl_encrypt($data, $method, $key); } static function _decrypt($data, $key=self::KEY, $method=self::METHOD){ return openssl_decrypt($data, $method, $key); } static function authcode($string,$key='',$operation=false,$expiry=0){ $ckey_length = 4; $key = md5($key ? $key : self::KEY); $keya = md5(substr($key, 0, 16)); $keyb = md5(substr($key, 16, 16)); $keyc = $ckey_length ? ($operation? substr($string, 0, $ckey_length):substr(md5(microtime()), -$ckey_length)) : ''; $cryptkey = $keya.md5($keya.$keyc); $key_length = strlen($cryptkey); $string = $operation? base64_decode(substr($string, $ckey_length)) : sprintf('%010d', $expiry ? $expiry + time() : 0).substr(md5($string.$keyb), 0, 16).$string; $string_length = strlen($string); $result = ''; $box = range(0, 255); $rndkey = array(); for($i = 0; $i <= 255; $i++) { $rndkey[$i] = ord($cryptkey[$i % $key_length]); } for($j = $i = 0; $i < 256; $i++) { $j = ($j + $box[$i] + $rndkey[$i]) % 256; $tmp = $box[$i]; $box[$i] = $box[$j]; $box[$j] = $tmp; } for($a = $j = $i = 0; $i < $string_length; $i++) { $a = ($a + 1) % 256; $j = ($j + $box[$a]) % 256; $tmp = $box[$a]; $box[$a] = $box[$j]; $box[$j] = $tmp; $result .= chr(ord($string[$i]) ^ ($box[($box[$a] + $box[$j]) % 256])); } if($operation) { if((substr($result, 0, 10) == 0 || substr($result, 0, 10) - time() > 0) && substr($result, 10, 16) == substr(md5(substr($result, 26).$keyb), 0, 16)) { return substr($result, 26); } else { return ''; } } else { return $keyc.str_replace('=', '', base64_encode($result)); } } static function randStr($randLength = 6, $addtime = 0, $includenumber = 0) { if ($includenumber) { $chars = 'abcdefghijklmnopqrstuvwxyzABCDEFGHJKLMNPQEST123456789'; } else { $chars = 'abcdefghijklmnopqrstuvwxyz'; } $len = strlen($chars); $randStr = ''; for ($i = 0; $i < $randLength; $i++) { $randStr .= $chars[mt_rand(0, $len - 1)]; } $tokenvalue = $randStr; if ($addtime) { $tokenvalue = $randStr . time(); } return $tokenvalue; } }
// 批量加密 function index(){ ini_set('max_execution_time', 0);//秒为单位,自己根据需要定义 set_time_limit(0); // $code = $this->arguments['code']; // $sta = $this->arguments['sta']; // $end = $this->arguments['end']; // var_dump($code,$sta,$end); // echo $res = Movies::_encrypt('123'); // echo $res = Movies::_decrypt($res); $moviePath = FCPATH.'movie'.DIRECTORY_SEPARATOR; // 视频目录 $data = [ ['ID'=>1,'VideoFile'=>'huzongdieying.zip'], ['ID'=>2,'VideoFile'=>'27000084-bstg.mp4'] ]; $obj = new FilmFiles(); foreach($data as $key=>$val){ $filePath = $moviePath.$val['VideoFile']; $res = Movies::movieModify($filePath); if($res){ $where = ['ID'=>$val['ID']]; $info = [ 'EncryptType'=>3, 'SecretKey'=>$res['Pkey'], 'SecretEncrypt'=>$res['passStr'] ]; $sta = $obj->updateLine($where,$info); var_dump($res,$sta); } } } // 批量解密 function indexOut(){ ini_set('max_execution_time', 0);//秒为单位,自己根据需要定义 set_time_limit(0); $moviePath = FCPATH.'movie'.DIRECTORY_SEPARATOR; $data = [ ['ID'=>1,'VideoFile'=>'a.mkv'], ['ID'=>2,'VideoFile'=>'b.mkv'] ]; $obj = new FilmFiles(); $where = ['ID'=>1,'ID'=>2]; $data = $obj->getList(); foreach($data as $val){ $filePath = $moviePath.$val->VideoFile; $res = Movies::movieReduction($filePath, $val->SecretEncrypt, $val->SecretKey); if($res){ $where = ['ID'=>$val->ID]; $info = [ 'EncryptType'=>0, 'SecretKey'=>'', 'SecretEncrypt'=>'' ]; $sta = $obj->updateLine($where,$info); var_dump($res,$sta); } } }