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

TypeScript中ytdl-core音视频流合并时child_process stdio类型错误

解决TypeScript中child_process自定义stdio管道的类型不兼容问题

在你的代码中,TypeScript报错是因为child_process.ChildProcess的stdio数组元素类型被定义为Readable | Writable | null | undefined,而ytdl返回的可读流调用pipe()方法时,要求参数必须是明确的WritableStream类型。以下是几种可行的解决方法:

方法1:类型断言(快速解决)

直接通过类型断言告诉TypeScript,你明确知道stdio[3]和stdio[4]是可写流:

audio.pipe(ffmpegProcess.stdio[3] as cp.Writable);
video.pipe(ffmpegProcess.stdio[4] as cp.Writable);
// 输出流同样可以断言
(ffmpegProcess.stdio[5] as cp.Readable).pipe(res);

方法2:类型守卫(更安全)

如果想避免类型断言带来的潜在风险,可以先检查流的存在性和类型,确保安全后再使用:

// 处理音频流管道
const audioDest = ffmpegProcess.stdio[3];
if (audioDest && typeof audioDest.write === 'function') {
  audio.pipe(audioDest);
}

// 处理视频流管道
const videoDest = ffmpegProcess.stdio[4];
if (videoDest && typeof videoDest.write === 'function') {
  video.pipe(videoDest);
}

// 处理输出流管道
const outputSrc = ffmpegProcess.stdio[5];
if (outputSrc && typeof outputSrc.pipe === 'function') {
  outputSrc.pipe(res);
}

完整修正代码

import express, { Request, Response } from "express";
import ytdl from "ytdl-core";
import cp from "child_process";
import ffmpeg from "ffmpeg-static";

const app = express();

app.get("/downloadmerged", (req: Request, res: Response) => {
  res.setHeader("Content-Type", "video/mp4");
  res.setHeader(
    `Content-Disposition`,
    `attachment; filename="Merged.mp4"`
  );
  
  const ref = "https://www.youtube.com/watch?v=aR-KAldshAE";
  const audio = ytdl(ref, { filter: "audioonly", quality: "highestaudio" });
  const video = ytdl(ref, { filter: "videoonly", quality: "highestvideo" });
  
  // 断言ffmpeg路径为字符串,避免类型错误
  const ffmpegPath = ffmpeg as string;
  const ffmpegProcess = cp.spawn(
    ffmpegPath,
    [
      "-loglevel", "0",
      "-hide_banner",
      "-itsoffset", "3.0",
      "-i", "pipe:3",
      "-i", "pipe:4",
      "-vf", "scale=320:240",
      "-c:v", "libx265",
      "-x265-params", "log-level=0",
      "-c:a", "flac",
      "-f", "matroska",
      "pipe:5",
    ],
    {
      windowsHide: true,
      stdio: [
        "inherit", "inherit", "inherit",
        "pipe", "pipe", "pipe",
      ],
    }
  );

  ffmpegProcess.on("close", () => {
    process.stdout.write("\n\n\n");
    console.log("done");
  });

  // 使用类型断言解决类型不兼容问题
  audio.pipe(ffmpegProcess.stdio[3] as cp.Writable);
  video.pipe(ffmpegProcess.stdio[4] as cp.Writable);
  (ffmpegProcess.stdio[5] as cp.Readable).pipe(res);
});

app.listen(3000, () => {
  console.log("Server running on port 3000");
});

另外,确保你已经安装了必要的类型依赖:

npm install @types/node @types/express @types/ytdl-core --save-dev

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.22 07:18:20