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

如何用Node.js将youtube-dl-exec处理后的输出流式传输到前端

解决youtube-dl-exec流式传输MP3到前端的问题

问题根源

你遇到的核心问题在于:

  1. youtubedl.exec()返回的是Promise,resolve结果是命令执行后的输出内容(字符串/Buffer),而非子进程对象,因此无法调用stdout.pipe
  2. 直接使用output: "-"时,若未正确配置流式输出触发ffmpeg后处理,youtube-dl会输出原始音频流(如webm)而非转换后的MP3
  3. 手动res.write大文件会导致内存溢出、文件结构损坏,无法保证流式传输的完整性

修正方案

使用youtubedl.spawn()方法直接获取子进程对象,流式传输处理后的MP3输出,并配置正确的响应头:

import youtubedl from 'youtube-dl-exec';
import type { Request, Response } from 'express';

export default async function convertAndDownload(req: Request, res: Response) {
  try {
    const { video, meta, filename } = req.body;
    const videoUrl = `https://youtube.com/watch?v=${video.id}`;

    // 配置正确的响应头,让浏览器识别MP3文件
    res.header('Content-Disposition', `attachment; filename="${filename}.mp3"`);
    res.header('Content-Type', 'audio/mpeg');

    // 使用spawn创建子进程,而非exec(exec会缓冲全部输出)
    const proc = youtubedl.spawn(videoUrl, {
      extractAudio: true,
      audioFormat: 'mp3',
      audioQuality: '10',
      output: '-', // 将处理后的MP3输出到stdout
      postprocessorArgs: [`ffmpeg: -metadata title="${meta.title}"`],
      addHeader: ['referer:youtube.com', 'user-agent:googlebot'],
      noBuffer: true, // 禁用输出缓冲,确保实时流式传输
    });

    // 将子进程的stdout直接pipe到响应对象,自动处理流式传输
    proc.stdout.pipe(res);

    // 处理子进程错误
    proc.stderr.on('data', (data) => {
      console.error(`youtube-dl 错误信息: ${data.toString()}`);
    });

    proc.on('error', (err) => {
      if (!res.headersSent) {
        res.status(500).json({
          success: false,
          msg: '处理请求失败',
        });
      }
    });

    // 子进程结束后收尾响应
    proc.on('close', (code) => {
      if (code !== 0 && !res.headersSent) {
        res.status(500).json({
          success: false,
          msg: `进程异常退出,代码: ${code}`,
        });
      }
    });
  } catch (err) {
    if (!res.headersSent) {
      res.status(500).json({
        success: false,
        msg: '请求处理过程中发生错误',
      });
    }
  }
}

关键注意事项

  • 确保服务器已安装ffmpeg:youtube-dl依赖ffmpeg完成音频格式转换,缺少时会直接输出原始音频流
  • 必须设置Content-Type: audio/mpeg:让浏览器正确识别文件类型,避免下载后无法播放
  • 使用spawn而非exec:spawn返回子进程对象,支持实时流式输出;exec会缓冲全部输出,不适合大文件传输

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.21 05:13:12