You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

基于node-youtube-dl构建Node.js服务:下载YouTube视频并转发为Form-Data

Node.js实现YouTube视频下载并以Form-Data转发到其他服务

我帮你把这个流程补全并优化,直接给你可运行的完整方案,分两种场景(无本地文件缓存和带本地缓存)来写:

首先准备依赖

推荐用更活跃的youtube-dl-exec替代旧的node-youtube-dl,同时需要axiosform-data来处理表单请求:

npm install youtube-dl-exec axios form-data express

方案一:直接流转发(无本地文件,高效)

这种方式不需要把视频存到磁盘,直接把YouTube的视频流通过管道传给目标服务,节省磁盘空间和IO时间:

const youtubeDl = require('youtube-dl-exec');
const axios = require('axios');
const FormData = require('form-data');
const express = require('express');
const app = express();

async function downloadAndForwardVideo(req, res) {
  const videoUrl = req.query.url;
  if (!videoUrl) {
    return res.status(400).send('请提供视频URL参数(?url=xxx)');
  }

  try {
    // 1. 获取视频流(直接输出到stdout,避免写入本地)
    const videoStream = await youtubeDl(videoUrl, {
      format: 'best[height<=480]', // 筛选480p以内的最佳画质
      output: '-' // 输出到标准输出,获取流
    }, {
      stdio: ['ignore', 'pipe', 'ignore'] // 配置stdio,让stdout作为可读流返回
    });

    // 2. 获取视频基本信息(用于文件名)
    const videoInfo = await youtubeDl.getInfo(videoUrl);
    const videoFileName = `${videoInfo.title}.mp4`;

    // 3. 构建Form-Data表单
    const formData = new FormData();
    formData.append('video', videoStream, {
      filename: videoFileName,
      contentType: 'video/mp4'
    });

    // 4. 发送到目标服务
    const targetServiceUrl = 'https://你的目标服务地址/upload'; // 替换成实际地址
    const forwardResponse = await axios.post(targetServiceUrl, formData, {
      headers: {
        ...formData.getHeaders(), // 自动生成Form-Data所需的头部
        // 如果目标服务需要授权,在这里加:'Authorization': 'Bearer 你的token'
      }
    });

    // 5. 返回结果给客户端
    res.status(200).json({
      success: true,
      videoTitle: videoInfo.title,
      targetServiceResult: forwardResponse.data
    });
  } catch (err) {
    console.error('处理视频出错:', err);
    res.status(500).send(`视频处理失败:${err.message}`);
  }
}

// 注册接口,启动服务
app.get('/forward-youtube-video', downloadAndForwardVideo);
app.listen(3000, () => {
  console.log('服务启动在3000端口:http://localhost:3000/forward-youtube-video?url=YouTube视频链接');
});

方案二:先下载到本地再转发(适合需要缓存的场景)

如果需要临时保存视频文件(比如做备份),可以用这个版本:

const youtubeDl = require('youtube-dl-exec');
const axios = require('axios');
const FormData = require('form-data');
const express = require('express');
const fs = require('fs');
const path = require('path');
const app = express();

// 创建临时目录
const tempDir = path.join(__dirname, 'temp');
if (!fs.existsSync(tempDir)) fs.mkdirSync(tempDir);

async function downloadAndForwardWithCache(req, res) {
  const videoUrl = req.query.url;
  if (!videoUrl) {
    return res.status(400).send('请提供视频URL参数(?url=xxx)');
  }

  try {
    // 1. 获取视频信息,生成文件名
    const videoInfo = await youtubeDl.getInfo(videoUrl);
    const videoFileName = `${videoInfo.title}.mp4`;
    const localFilePath = path.join(tempDir, videoFileName);

    // 2. 下载视频到本地文件
    await youtubeDl(videoUrl, {
      format: 'best[height<=480]',
      output: localFilePath
    });

    // 3. 构建Form-Data,读取本地文件流
    const formData = new FormData();
    formData.append('video', fs.createReadStream(localFilePath), {
      filename: videoFileName,
      contentType: 'video/mp4'
    });

    // 4. 发送到目标服务
    const targetServiceUrl = 'https://你的目标服务地址/upload';
    const forwardResponse = await axios.post(targetServiceUrl, formData, {
      headers: formData.getHeaders()
    });

    // 5. 可选:删除临时文件(如果不需要缓存的话)
    fs.unlinkSync(localFilePath);

    // 6. 返回结果
    res.status(200).json({
      success: true,
      videoTitle: videoInfo.title,
      targetServiceResult: forwardResponse.data
    });
  } catch (err) {
    console.error('处理视频出错:', err);
    res.status(500).send(`视频处理失败:${err.message}`);
  }
}

app.get('/forward-youtube-video-with-cache', downloadAndForwardWithCache);
app.listen(3000, () => {
  console.log('服务启动在3000端口:http://localhost:3000/forward-youtube-video-with-cache?url=YouTube视频链接');
});

注意事项

  • 工具选择:建议安装yt-dlp替代官方youtube-dl(因为youtube-dl已经停止维护),youtube-dl-exec会自动检测系统中的yt-dlp,你可以手动安装或者通过youtube-dl-execdownload选项自动下载。
  • 目标服务兼容性:确保目标服务支持接收multipart/form-data格式的文件,并且表单字段名(这里是video)和目标服务的要求一致。
  • 大视频处理:流转发方案内存占用更低,但要确保服务器有足够的带宽;本地缓存方案需要注意磁盘空间,记得定期清理临时文件。

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

火山引擎 最新活动