Video.js直播场景下,如何为所有m3u8/TS文件追加Nginx鉴权参数?
碰到过一模一样的坑!这是因为Video.js默认会直接解析主playlist里的相对URL,完全不会自动带上主URL的鉴权查询参数。给你几个实测有效的解决办法:
方法1:从源头修改主m3u8内容(最省心)
如果你能控制生成主live.m3u8的环节(比如转码服务器或后端),直接把子播放列表和ts片段的URL改成带鉴权参数的绝对地址。比如把原来主文件里的live_109.m3u8改成:https://example.com/video/live_109.m3u8?md5=xznbbmbbbbbxncb&expire=123456788
这样Video.js请求子资源时会直接用带参数的地址,一步到位解决所有问题。
方法2:用Video.js钩子拦截请求(前端快速修复)
如果没法改主m3u8,就用Video.js的beforeRequest钩子在请求发送前自动追加鉴权参数。直接上代码:
videojs('your-player-id').ready(function() { const player = this; // 从主播放地址里提取鉴权参数 const mainUrlParams = new URL(player.currentSrc()).search; // 拦截所有媒体资源请求 player.hook('beforeRequest', function(options) { // 只处理m3u8和ts文件 if (options.url.match(/\.(m3u8|ts)$/i)) { // 判断URL已有参数的拼接符 const separator = options.url.includes('?') ? '&' : '?'; // 追加鉴权参数(slice(1)去掉开头的?) options.url += separator + mainUrlParams.slice(1); } return options; }); });
这个方案前端就能搞定,不需要动后端。注意要确保播放器初始化时player.currentSrc()能正确拿到带参数的主播放地址,如果主URL是动态生成的,要保证参数能被正确捕获。
方法3:Nginx端重写URL(备选方案)
如果前端也不好修改,可以在Nginx层面做兜底处理——当请求子m3u8或ts时,检查请求的Referer是否来自带有效鉴权的主m3u8,自动把参数追加过去。不过这个方法依赖Referer字段(可能被篡改),安全性不如前两种,仅做备选:
location ~* \.(m3u8|ts)$ { # 保留原有Secure Link验证逻辑 secure_link $arg_md5,$arg_expire; secure_link_md5 "your_secret_key$uri$arg_expire"; if ($secure_link = "") { # 从Referer中提取鉴权参数 set $referer $http_referer; if ($referer ~* "\?md5=([^&]+)&expire=([^&]+)") { set $new_md5 $1; set $new_expire $2; # 验证参数有效性 set $is_valid 0; if ($secure_link_md5 = $new_md5) { if ($new_expire > $time_local) { set $is_valid 1; } } # 验证通过则重写URL带上参数 if ($is_valid = 1) { rewrite ^ $uri?md5=$new_md5&expire=$new_expire; } } # 验证不通过返回403 if ($is_valid != 1) { return 403; } } # 其他直播流配置... }
最后提醒下:测试前记得清浏览器缓存,有时候旧的playlist缓存会导致参数没生效;另外要确保鉴权参数的过期时间足够覆盖直播时长,不然中途过期还是会触发403。
内容的提问来源于stack exchange,提问作者Ajitabh Pandey
相关产品推荐
相关产品推荐

