php视频边下边播,PHP + NGINX 控制视频文件播放,并防止文件下载

最简单的方法是使用NGINX的 internal 功能

server {

listen 80;

server_name www.xxx.com;

location / {

index index.php index.html index.htm;

root  /xxx;

if (!-e $request_filename) {

rewrite ^/index.php(.*)$ /index.php?s=$1 last;

rewrite ^(.*)$ /index.php?s=$1 last;

break;

}

}

# 这里使用internal做下载防护,只允许内部程序(PHP等)访问,这样外部直接访问这个地址就会提示404错误

location ~ \.mp4$ {

internal;

# 这里的路径配置是可选的,可以配置到网站外部,和其他location里的配置路径是一个意思,可以更好的防止文件被通过网址下载

root /bbb;

}

location ~ \.php$ {

root  /xxx;

try_files $uri =404;

fastcgi_pass  unix:/var/run/php-fpm/php-fpm.sock;

fastcgi_index index.php;

fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;

include fastcgi_params;

}

}

然后在PHP中通过header(‘Location: /xxx/aa.mp4‘)访问,但这个只适合于小文件,因为这种方式不支持Content-Range和HTTP 206,导致不支持断点续传和视频文件的边下边播

最好的方式是通过header(‘X-Accel-Redirect: /xxx/aa.mp4‘)访问,X-Accel-Redirect支持Content-Range和HTTP 206,Apache里面是X-Sendfile

如果不能配置nginx的internal选项,或者nginx不支持X-Accel-Redirect,却要使用断点续传、边下边播和下载防护,那么就要通过PHP代码来控制

思路上是使用token鉴权,首先下载文件前由前端请求一个token,这个token由用户ID+时间戳+视频ID组成,然后存储到session并加密后发送给前端

$token = $_SESSION[‘uid‘] . ‘|‘ . time() . ‘|‘ . $id;

// 保存未加密token到seesion

$_SESSION[‘video_token‘] = $token;

// 加密token以便发送到客户端

$token = Mcrypt::encode($token, ‘lbnnbs‘);

前端收到token,向下载控制器网址发送token请求文件下载,控制器对token解码,判断Session是否一致、用户ID是否正确、是否超时、视频ID是否正确

然后将视频ID转换为文件地址,通过PHP读取文件发送给前端下载。并通过发送Content-Range和HTTP 206来支持断点续传、边下边播等操作

$id = decodeIdFromToken($token);

$file = getFilePath($id);

SendVideo($file);

fcecaa27ea5212ceb9bf034c36bfbf34.gif

private function SendVideo($file) {

header("Content-type: video/mp4");

header("Accept-Ranges: bytes");

$size = filesize($file);

if (isset($_SERVER[‘HTTP_RANGE‘])) {

header("HTTP/1.1 206 Partial Content");

list($name, $range) = explode("=", $_SERVER[‘HTTP_RANGE‘]);

list($begin, $end) = explode("-", $range);

if ($end == 0)

$end = $size - 1;

}else {

$begin = 0;

$end = $size - 1;

}

header("Content-Length: " . ($end - $begin + 1));

header("Content-Disposition: filename=" . basename($file));

header("Content-Range: bytes " . $begin . "-" . $end . "/" . $size);

$fp = fopen($file, ‘rb‘);

fseek($fp, $begin);

while (!feof($fp)) {

$p = min(1024, $end - $begin + 1);

$begin += $p;

echo fread($fp, $p);

}

fclose($fp);

}

private function decodeIdFromToken($token) {

if (empty($_SESSION[‘uid‘])) {

return false;

}

$token = Mcrypt::decode($token, ‘lbnnbs‘);

if ($token != $_SESSION[‘video_token‘]) {

//token解密失败,判定失效

return false;

}

$token_arr = explode(‘|‘, $token);

if (intval($token_arr[0]) != $_SESSION[‘uid‘]) {

// token不是当前用户,判定失效

return false;

}

if (intval($token_arr[1]) < time() - 10) {

// token生成于10秒前,判定失效

return false;

}

unset($_SESSION[‘video_token‘]);

return $token_arr[2]; // 返回id

}

fcecaa27ea5212ceb9bf034c36bfbf34.gif

另外需要注意的是,很多时候mp4文件会无法支持边下边播,这是因为在转码或者压缩视频文件到mp4的时候把文件的元数据移除了或者放到了文件的末尾,导致前端播放器不能第一时间获取到视频文件的播放时长等信息,只能全部下载完毕后或者直到读取到了元数据后才能播放。这个时候可以使用qt-faststart.exe工具进行处理,把元数据放回文件头部即可。

原文:https://www.cnblogs.com/liliuguang/p/10576000.html

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值