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

通过Vercel无服务器函数管道传输m3u8链接失败,如何实现源地址混淆?

解决Vercel无服务器函数代理m3u8视频的问题

你的代码能代理图片是因为图片是单文件资源,但m3u8是播放列表文件,里面包含了实际视频分片的原始URL,客户端会直接请求这些分片地址而不走你的Vercel代理,再加上响应头配置缺失,才导致视频一直缓冲。以下是可行的实现方案:

核心解决思路

  1. 正确设置响应头,确保客户端能识别m3u8格式
  2. 重写m3u8内容中的所有分片URL,让分片请求也通过Vercel函数代理
  3. 新增分片代理逻辑,处理视频分片的转发

具体实现代码

1. 代理m3u8播放列表的函数

import type { NextApiRequest, NextApiResponse } from 'next';
import https from 'https';

export default async (req: NextApiRequest, res: NextApiResponse) => {
  // 设置CORS和内容类型头
  res.setHeader('Access-Control-Allow-Origin', '*');
  res.setHeader('Content-Type', 'application/vnd.apple.mpegurl');

  // 获取原始m3u8内容
  const m3u8Response = await new Promise<string>((resolve, reject) => {
    https.get('https://devstreaming-cdn.apple.com/videos/streaming/examples/img_bipbop_adv_example_fmp4/master.m3u8', (response) => {
      let data = '';
      response.on('data', (chunk) => data += chunk);
      response.on('end', () => resolve(data));
      response.on('error', reject);
    });
  });

  // 重写m3u8中的分片URL,替换为你的Vercel代理地址
  const baseUrl = 'https://devstreaming-cdn.apple.com/videos/streaming/examples/img_bipbop_adv_example_fmp4/';
  const proxyUrl = `${req.headers.origin}/api/proxy-segment?url=`;
  const rewrittenM3u8 = m3u8Response.replace(new RegExp(baseUrl, 'g'), proxyUrl);

  // 返回重写后的m3u8内容
  res.send(rewrittenM3u8);
};

2. 代理视频分片的函数(新建pages/api/proxy-segment.ts)

import type { NextApiRequest, NextApiResponse } from 'next';
import https from 'https';

export default async (req: NextApiRequest, res: NextApiResponse) => {
  const { url } = req.query;
  if (!url || typeof url !== 'string') {
    return res.status(400).send('Missing or invalid URL parameter');
  }

  // 设置CORS头
  res.setHeader('Access-Control-Allow-Origin', '*');

  // 管道传输分片内容
  https.get(decodeURIComponent(url), (response) => {
    // 转发原始响应的Content-Type头
    res.setHeader('Content-Type', response.headers['content-type'] || 'application/octet-stream');
    response.pipe(res);
  }).on('error', (err) => {
    res.status(500).send(`Failed to fetch segment: ${err.message}`);
  });
};

关键注意事项

  • URL编码:分片URL需要编码后作为参数传递,避免特殊字符导致请求错误
  • 响应头转发:分片代理时要转发原始的Content-Type,确保客户端能正确解析视频分片
  • Vercel函数限制:注意Vercel无服务器函数的超时时间(默认10秒),如果分片较大或网络较慢,可能需要调整配置
  • 缓存策略:可以给分片代理添加缓存头,减少重复请求,提升性能

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.13 07:20:35