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

如何在Next.js中调用YouTube API获取视频字幕?

在Next.js中通过YouTube API获取视频字幕

我已经有一个Next.js客户端组件,能通过useSearchParams获取视频链接{link},并且知道如何用Python的youtube_transcript_api获取YouTube视频字幕,现在需要在Next.js中借助YouTube API实现相同功能。

现有客户端组件代码

"use client";

import { useSearchParams } from "next/navigation";

function VideoCreado() {
    const searchParams = useSearchParams(); // 修正拼写错误:searchParmas → searchParams
    const link = searchParams.get("link");
    return (
        <div className="bg-gray-900 text-gray-100 min-h-screen flex flex-col items-center justify-center">
            <h1 className="text-3xl font-bold mb-4">视频已生成!</h1>
            <p className="text-lg">字幕:</p>
            <p>{link}</p>
        </div>
    );
}

export default VideoCreado;

Python实现示例(注释汉化)

from youtube_transcript_api import YouTubeTranscriptApi

def get_transcription(video_url):
    # 从URL中提取视频ID
    video_id = video_url.split("v=")[1]
    ampersand_position = video_id.find("&")
    if ampersand_position != -1:
        video_id = video_id[:ampersand_position]

    # 获取字幕
    transcript = YouTubeTranscriptApi.get_transcript(video_id)
    
    # 将字幕合并为单个字符串
    transcription = ' '.join([entry['text'] for entry in transcript])
    return transcription

# 示例用法
video_url = "https://www.youtube.com/watch?v=8yZ-x-WuFw0&ab_channel=NamePointer"
transcription = get_transcription(video_url)
print(transcription)

Next.js实现步骤

1. 前端提取视频ID

和Python逻辑一致,在客户端组件中添加提取视频ID的工具函数:

const extractVideoId = (url) => {
  if (!url) return null;
  // 匹配标准YouTube链接的视频ID(11位字符)
  const videoIdMatch = url.match(/(?:v=|\/)([0-9A-Za-z_-]{11}).*/);
  return videoIdMatch ? videoIdMatch[1] : null;
};

2. 创建API路由代理请求

直接在客户端调用YouTube API会暴露密钥,因此用Next.js API路由做代理。在app/api/transcript/route.js创建文件:

export async function GET(request) {
  const { searchParams } = new URL(request.url);
  const videoId = searchParams.get("videoId");
  const apiKey = process.env.YOUTUBE_API_KEY; // 从环境变量读取API密钥

  if (!videoId || !apiKey) {
    return new Response(JSON.stringify({ error: "缺少视频ID或API密钥" }), {
      status: 400,
      headers: { "Content-Type": "application/json" },
    });
  }

  // 调用YouTube Data API获取字幕列表
  const transcriptListUrl = `https://www.googleapis.com/youtube/v3/captions?part=snippet&videoId=${videoId}&key=${apiKey}`;
  const transcriptListResponse = await fetch(transcriptListUrl);
  const transcriptListData = await transcriptListResponse.json();

  if (!transcriptListData.items || transcriptListData.items.length === 0) {
    return new Response(JSON.stringify({ error: "该视频无可用公开字幕" }), {
      status: 404,
      headers: { "Content-Type": "application/json" },
    });
  }

  // 获取第一个可用字幕的JSON格式内容
  const captionId = transcriptListData.items[0].id;
  const transcriptUrl = `https://www.googleapis.com/youtube/v3/captions/${captionId}?key=${apiKey}&tfmt=json`;
  const transcriptResponse = await fetch(transcriptUrl);
  const transcriptData = await transcriptResponse.json();

  // 格式化字幕为纯文本
  const transcriptText = transcriptData.events
    .map((event) => event.segs?.map((seg) => seg.utf8).join(""))
    .filter(Boolean)
    .join(" ");

  return new Response(JSON.stringify({ transcript: transcriptText }), {
    headers: { "Content-Type": "application/json" },
  });
}

3. 客户端组件集成API调用

修改原组件,添加状态管理和字幕获取逻辑:

"use client";

import { useSearchParams } from "next/navigation";
import { useState, useEffect } from "react";

function VideoCreado() {
    const searchParams = useSearchParams();
    const link = searchParams.get("link");
    const [transcript, setTranscript] = useState("");
    const [loading, setLoading] = useState(false);
    const [error, setError] = useState("");

    // 提取视频ID的工具函数
    const extractVideoId = (url) => {
      if (!url) return null;
      const videoIdMatch = url.match(/(?:v=|\/)([0-9A-Za-z_-]{11}).*/);
      return videoIdMatch ? videoIdMatch[1] : null;
    };

    useEffect(() => {
        if (link) {
            const videoId = extractVideoId(link);
            if (!videoId) {
                setError("无效的YouTube视频链接");
                return;
            }

            setLoading(true);
            setError("");

            // 调用API路由获取字幕
            fetch(`/api/transcript?videoId=${videoId}`)
                .then(res => res.json())
                .then(data => {
                    if (data.error) {
                        setError(data.error);
                    } else {
                        setTranscript(data.transcript);
                    }
                })
                .catch(() => {
                    setError("获取字幕失败,请稍后重试");
                })
                .finally(() => {
                    setLoading(false);
                });
        }
    }, [link]);

    return (
        <div className="bg-gray-900 text-gray-100 min-h-screen flex flex-col items-center justify-center p-4">
            <h1 className="text-3xl font-bold mb-4">视频已生成!</h1>
            <p className="text-lg mb-2">视频链接:</p>
            <p className="mb-4 break-all">{link}</p>
            <p className="text-lg mb-2">字幕:</p>
            {loading && <p>正在加载字幕...</p>}
            {error && <p className="text-red-400">{error}</p>}
            {transcript && (
                <div className="bg-gray-800 p-4 rounded max-w-2xl whitespace-pre-wrap">
                    {transcript}
                </div>
            )}
        </div>
    );
}

export default VideoCreado;

关键注意事项

  • 需在Google Cloud控制台创建项目,启用YouTube Data API v3,生成API密钥后添加到.env.local:YOUTUBE_API_KEY=你的密钥
  • YouTube API有调用配额限制,需留意配额使用情况
  • 部分视频可能没有公开字幕,需处理无字幕的异常场景

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.21 02:35:55