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

如何通过CGI实现HTTP实时传输生成中的文件?(yt-dlp场景)

Apache/CGI + yt-dlp 流式传输(Chunked编码)解决方案

先明确:Apache CGI本身支持chunked传输,但坑主要在输出缓冲和脚本的流式处理逻辑上,以下是亲测有效的配置和代码:

1. 先搞定Apache的CGI配置

Apache默认会缓冲CGI脚本的输出,这直接卡死流式传输,必须先关缓冲:

  • 在httpd.conf或者站点目录的.htaccess里加这些配置:
    # 禁用gzip压缩(避免干扰二进制流的chunked结构)
    SetEnv no-gzip 1
    SetEnv dont-vary 1
    # 关闭CGI输出缓冲(如果用PHP的话单独加下面这句)
    php_flag output_buffering off
    
  • 确认mod_cgi或mod_cgid模块已经启用(Apache默认一般开着,没开的话用a2enmod cgi启用)。

2. 写对CGI脚本(拿Python举例)

核心是关掉脚本自身的输出缓冲,然后把yt-dlp的输出实时拆成chunked格式发出去,不能等整个视频下完再输出。

示例脚本youtube_download.cgi(记得给执行权限:chmod +x youtube_download.cgi):

#!/usr/bin/env python3
import subprocess
import sys

# 先发送响应头,必须用二进制输出避免编码问题
sys.stdout.buffer.write(b"Transfer-Encoding: chunked\r\n")
# 这里的Content-Type要对应视频格式,比如mp4就用video/mp4,webm用video/webm
sys.stdout.buffer.write(b"Content-Type: video/mp4\r\n")
sys.stdout.buffer.write(b"\r\n")  # 头部结束的空行
sys.stdout.buffer.flush()  # 立即把头部发出去,不能等

# 调用yt-dlp,直接输出到stdout
cmd = [
    "yt-dlp",
    "-f", "bestvideo+bestaudio/best",  # 选你要的格式,按需调整
    "-o", "-",  # 关键:输出到stdout
    # 这里换成用户请求的视频URL,实际场景要从CGI的QUERY_STRING里取
    "https://www.youtube.com/watch?v=example"
]

# 启动yt-dlp进程,实时读输出
with subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.DEVNULL) as proc:
    while True:
        # 每次读4KB的块,大小可以自己调
        chunk = proc.stdout.read(4096)
        if not chunk:  # 读到空说明yt-dlp输出完了
            break
        # 按照chunked编码规则输出:十六进制长度 + 换行 + 内容 + 换行
        sys.stdout.buffer.write(f"{len(chunk):x}\r\n".encode())
        sys.stdout.buffer.write(chunk)
        sys.stdout.buffer.write(b"\r\n")
        sys.stdout.buffer.flush()  # 实时发走,别缓冲

# 发送chunked结束标记
sys.stdout.buffer.write(b"0\r\n\r\n")
sys.stdout.buffer.flush()

3. 踩过的坑排查

  • 无限传输:大概率是脚本没检测到yt-dlp的进程结束,比如死循环了。确保读到proc.stdout.read()返回空就终止循环,同时检查yt-dlp会不会卡住(比如终端直接跑命令看能不能正常结束)。
  • 内容为空:
    • 先在终端跑一遍脚本里的yt-dlp命令,看有没有输出,要是终端都没输出,那就是yt-dlp的参数错了。
    • 一定要加flush(),不管是头部还是每个分块,不然Python会把输出攒着不发,Apache也会等缓冲区满了才传。
    • 别开gzip压缩,压缩会把chunked的结构搞乱,直接导致传输异常。
  • 权限问题:Apache的运行用户(比如www-data)得能执行yt-dlp,还要能访问ffmpeg(如果yt-dlp需要合并音视频的话),不然会悄悄失败。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.02 02:04:53