You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何让HLS.js从服务端拉取数据 解决blob前缀视频资源路径无法访问问题

问题根因

你通过Blob URL加载m3u8清单时,hls.js会将Blob URL作为基准路径拼接所有相对路径的TS分片地址,因此出现了blob前缀的错误请求。以下是3种可行的实现方案:

方案1:服务端预处理m3u8分片路径(推荐,改动最小)

直接在PHP读取m3u8内容时,把所有分片的相对路径替换为指向video.php的绝对路径,hls.js解析后会直接请求你指定的接口,无需修改前端逻辑:

<?php
// 读取原始m3u8内容
$m3u8Content = file_get_contents('./your_manifest_path.m3u8');
// 替换所有.ts后缀的分片路径为video.php接口地址,匹配规则可根据你的实际路径调整
$domain = 'https://<your domain>';
$processedContent = preg_replace_callback('/([a-zA-Z0-9_\-]+\.ts)/', function($matches) use ($domain) {
    return "{$domain}/video.php?file={$matches[1]}";
}, $m3u8Content);
// 返回给前端
$res['manifest'] = $processedContent;
echo json_encode($res);
?>
  • 优点:无需修改前端hls.js逻辑,兼容性最好,也方便服务端统一做鉴权、流量控制。
方案2:前端通过hls.js配置拦截所有请求

无需修改服务端m3u8处理逻辑,通过hls.js内置的xhrSetup配置拦截所有请求,统一转发到video.php接口:

var manifest = res["manifest"];
var blob = new Blob([manifest]);
// 初始化时传入xhrSetup配置
var hls = new Hls({
  xhrSetup: function(xhr, url) {
    // 匹配所有带blob前缀的分片请求
    if (url.startsWith('blob:')) {
      // 提取真实的资源路径,可根据你的实际路径规则调整提取逻辑
      const realFilePath = url.replace('blob:https://<your domain>/', '');
      // 替换为video.php接口地址
      const targetUrl = `https://<your domain>/video.php?file=${encodeURIComponent(realFilePath)}`;
      // 重写请求地址
      xhr.open('GET', targetUrl, true);
      // 如果需要带cookie或者自定义header可以在这里加
      // xhr.withCredentials = true;
    }
  }
});
var url = URL.createObjectURL(blob);

hls.loadSource(url);
hls.attachMedia(video);
hls.on(Hls.Events.MANIFEST_PARSED, function() {
    video.load();
});
  • 优点:前端完全控制请求逻辑,不需要改动服务端已有接口。
方案3:省略Blob中转步骤,直接加载PHP接口地址

完全去掉前端先拉m3u8转Blob的逻辑,直接给hls.js传入返回m3u8的PHP接口地址,后续所有分片请求可配合xhrSetup统一转发到video.php:

var hls = new Hls({
  xhrSetup: function(xhr, url) {
    // 只处理TS分片请求,跳过m3u8本身的请求
    if (url.endsWith('.ts')) {
      const fileName = url.split('/').pop();
      const targetUrl = `https://<your domain>/video.php?file=${encodeURIComponent(fileName)}`;
      xhr.open('GET', targetUrl, true);
    }
  }
});
// 直接加载返回m3u8内容的PHP接口
hls.loadSource('https://<your domain>/get_m3u8.php?vid=xxx');
hls.attachMedia(video);
hls.on(Hls.Events.MANIFEST_PARSED, function() {
    video.play();
});

对应的get_m3u8.php示例:

<?php
// 做参数校验、鉴权逻辑
$vid = $_GET['vid'];
// 注意做路径安全校验,防止目录遍历
$m3u8Path = "./videos/{$vid}/index.m3u8";
if (!file_exists($m3u8Path) || !str_starts_with(realpath($m3u8Path), __DIR__ . '/videos/')) {
    http_response_code(403);
    exit;
}
header('Content-Type: application/vnd.apple.mpegurl');
header('Access-Control-Allow-Origin: *');
echo file_get_contents($m3u8Path);
?>
  • 优点:省去Blob中转的冗余逻辑,全链路请求都可在服务端做管控。

安全提示

所有接收文件路径参数的PHP接口,必须做路径合法性校验,限制只能读取指定目录下的资源,避免用户传入../等路径实现目录遍历,读取到敏感文件。


内容的提问来源于stack exchange,提问作者Wilson Suwei

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.01 21:39:03