DEV Community

Aleksander Łukiańczuk
Aleksander Łukiańczuk

Posted on

Need Help: Youtube Caption Extractor not working in Vercel

I have an Anki-like app in Next.js, where users can create their flashcards from YT captions. I used youtube-caption-extractor for that. It works perfectly fine but only locally (local:3000) but not when I deployed my app to vercel. Thus it's less possible that this is youtube-caption-extractor problem or openAI, execution time and memory seems also ok: Execution Duration / Limit 283ms / 10s Memory Used / Limit126 MB / 1024 MB so these issues can also be excluded. I have similar option to generate flashcards from text (using same OpenAI keys etc.) and this works when deployed to vercel. Only this YT generetion has problems. Any ideas what these problems may be? Is this issue with vercel? Thank you very much for your time!

Error: [POST] /api/generate-flashcards-youtube status=500 Error generating flashcards: Error: No captions found for video: pvIwTeXaEP0... (but there are captions and flashcards are generated from this YT video locally)

Here anki-app\app\api\generate-flashcards-youtube for context:
`
import { NextResponse } from 'next/server';
import OpenAI from 'openai';
import { getVideoDetails } from 'youtube-caption-extractor';

const openai = new OpenAI({
apiKey: process.env.OPENAI_API_KEY,
});

export async function POST(req: Request) {
const { videoUrl, lang = 'en', useCustomInstructions, customInstructions } = await req.json();

try {
const videoId = extractVideoId(videoUrl);
const { subtitles } = await getVideoDetails({ videoID: videoId, lang });

if (!subtitles || subtitles.length === 0) {
  throw new Error(`No captions found for video: ${videoId}`);
}

const captionText = subtitles.map(caption => caption.text).join(' ');

const systemMessage = useCustomInstructions
  ? `You are the creator of flashcards. Create questions (with a question mark at the end) and in detail answers from the given text in a JSON array format:
     [
       {"question": "Question 1?", "answer": "Answer 1"},
       {"question": "Question 2?", "answer": "Answer 2"},
       ...
     ]
     ${customInstructions}`
  : `Create flashcards from the following YouTube video captions in a JSON array format:
     [
       {"question": "Question 1?", "answer": "Answer 1"},
       {"question": "Question 2?", "answer": "Answer 2"},
       ...
     ] Answers should be in detail.`;

const response = await openai.chat.completions.create({
  model: 'gpt-4o-mini',
  messages: [
    {
      "role": "system",
      "content": systemMessage
    },
    {
      "role": "user",
      "content": captionText
    }
  ],
});

const content = response.choices[0]?.message?.content?.trim();
if (!content) {
  throw new Error('No content generated from OpenAI');
}

let jsonString = content;
if (content.includes('[') && content.includes(']')) {
  const jsonStart = content.indexOf('[');
  const jsonEnd = content.lastIndexOf(']') + 1;
  jsonString = content.substring(jsonStart, jsonEnd);
}

try {
  const generatedFlashcards = JSON.parse(jsonString);
  return NextResponse.json(generatedFlashcards);
} catch (parseError) {
  console.error('Error parsing JSON:', parseError);
  throw new Error('Failed to parse generated content as JSON');
}
Enter fullscreen mode Exit fullscreen mode

} catch (error) {
console.error('Error generating flashcards:', error);
return NextResponse.json({ error: error instanceof Error ? error.message : 'Failed to generate flashcards' }, { status: 500 }); }
}

function extractVideoId(url: string): string {
const regex = /(?:https?:\/\/)?(?:www.)?(?:youtube.com|youtu.be)\/(?:watch\?v=)?(.+)/;
const match = url.match(regex);
return match ? match[1] : '';
}`

Top comments (0)