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

在Next.js项目中使用youtube-transcript获取字幕报错的解决咨询

在Next.js中使用youtube-transcript包获取字幕报错的解决方法

问题说明

单个JS/TS文件中使用youtube-transcript包获取YouTube视频字幕完全正常,但在Next.js项目中运行时出现报错:

Uncaught (in promise) Error: [YoutubeTranscript] 🚨 TypeError: URL is not a constructor
at new YoutubeTranscriptError (youtube-transcript.esm.js:74:1)
at Function.eval (youtube-transcript.esm.js:134:1)
at step (youtube-transcript.esm.js:64:1)
at Object.eval [as throw] (youtube-transcript.esm.js:45:46)
at rejected (youtube-transcript.esm.js:36:42)

单个文件运行的预期结果:

[
  {
    text: 'what is going on everyone my name is',
    duration: 2800,
    offset: 399
  },
  {
    text: "anson and in this video i'm going to go",
    duration: 2960,
    offset: 1680
  },
  // ... 更多字幕条目
]

原因分析

youtube-transcript包内部依赖Node.js环境的URL构造函数(或node:url模块),而Next.js客户端组件运行在浏览器环境中,包的代码未做浏览器兼容处理,导致出现URL is not a constructor错误。单个JS/TS文件运行在Node.js环境,因此无此问题。

解决方案

方案一:使用Next.js服务器组件运行代码

服务器组件运行在Node.js环境,与单个JS文件的运行环境一致,可直接调用包:

// app/TranscriptServerComponent.tsx
import { YoutubeTranscript } from "youtube-transcript";

export default async function TranscriptServerComponent() {
  const transcript = await YoutubeTranscript.fetchTranscript("QY8dhl1EQfI");
  
  return (
    <div>
      <h3>视频字幕</h3>
      <pre>{JSON.stringify(transcript, null, 2)}</pre>
    </div>
  );
}

方案二:创建API路由,客户端通过接口调用

如果需要在客户端组件中使用字幕数据,可创建Next.js API路由处理字幕获取逻辑,客户端通过fetch调用该接口:

1. 创建API路由

// app/api/transcript/route.ts (App Router)
// 或 pages/api/transcript.ts (Pages Router)
import { YoutubeTranscript } from "youtube-transcript";
import { NextResponse } from "next/server";

export async function GET(request: Request) {
  const { searchParams } = new URL(request.url);
  const videoId = searchParams.get("videoId");

  if (!videoId) {
    return NextResponse.json({ error: "缺少videoId参数" }, { status: 400 });
  }

  try {
    const transcript = await YoutubeTranscript.fetchTranscript(videoId);
    return NextResponse.json(transcript);
  } catch (error) {
    return NextResponse.json(
      { error: (error as Error).message },
      { status: 500 }
    );
  }
}

2. 客户端组件调用API

// app/TranscriptClientComponent.tsx
'use client';

import { useEffect, useState } from "react";

export default function TranscriptClientComponent() {
  const [transcript, setTranscript] = useState<any[]>([]);
  const [loading, setLoading] = useState(true);
  const [error, setError] = useState<string | null>(null);

  useEffect(() => {
    const getTranscript = async () => {
      try {
        const res = await fetch("/api/transcript?videoId=QY8dhl1EQfI");
        if (!res.ok) throw new Error("获取字幕失败");
        const data = await res.json();
        setTranscript(data);
      } catch (err) {
        setError((err as Error).message);
      } finally {
        setLoading(false);
      }
    };

    getTranscript();
  }, []);

  if (loading) return <div>加载中...</div>;
  if (error) return <div>错误:{error}</div>;

  return (
    <div>
      <h3>视频字幕</h3>
      <pre>{JSON.stringify(transcript, null, 2)}</pre>
    </div>
  );
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.18 16:53:10