Next.js Discord

Discord Forum

YTDL auth issues.

Unanswered
Northeast Congo Lion posted this in #help-forum
Open in Discord
Northeast Congo LionOP
trying to use YTDL and everything works fine locally. im able to download the video and process it but when deploying to vercel i get
Error processing YouTube video: u [Error]: Sign in to confirm you’re not a bot
    at t.playError (/var/task/.next/server/app/api/youtube-transcribe/route.js:5:3149)
    at t.getBasicInfo (/var/task/.next/server/app/api/youtube-transcribe/route.js:1:53797)
    at process.processTicksAndRejections (node:internal/process/task_queues:95:5) ` 


after that i followed what it said about cookies here https://www.npmjs.com/package/@distube/ytdl-core and am getting
Access denied to YouTube video: Error: Status code: 403
    at ClientRequest.<anonymous> (/var/task/.next/server/app/api/youtube-transcribe/route.js:5:23884)
    at Object.onceWrapper (node:events:634:26)
    at ClientRequest.emit (node:events:531:35)
    at HTTPParser.parserOnIncomingClient (node:_http_client:698:27)
    at HTTPParser.parserOnHeadersComplete (node:_http_common:119:17)
    at TLSSocket.socketOnData (node:_http_client:540:22)
    at TLSSocket.emit (node:events:519:28)
    at addChunk (node:internal/streams/readable:559:12)
    at readableAddChunkPushByteMode (node:internal/streams/readable:510:3)
    at Readable.push (node:internal/streams/readable:390:5) {
  statusCode: 403
}


I really just need to figure out a way to fix the "sign in to confirm" issue. as I need to download youtube via api.

1 Reply

Northeast Congo LionOP
some info to my api

const cookies = JSON.parse(fs.readFileSync(path.join(process.cwd(), 'cookies.json'), 'utf-8'))

// Create an agent with cookies
const agent = ytdl.createAgent(cookies)

export async function POST(request) {
  const { url } = await request.json()

  // Normalize YouTube Shorts URL to standard YouTube URL
  const normalizedUrl = normalizeYouTubeUrl(url)

  if (!ytdl.validateURL(normalizedUrl)) {
    return NextResponse.json({ success: false, error: 'Invalid YouTube URL' }, { status: 400 })
  }

  try {
    // Check if video info can be fetched
    const videoInfo = await getVideoInfo(normalizedUrl)
    if (!videoInfo) {
      throw new Error('Unable to fetch video information')
    }

    const audioBuffer = await downloadAudioWithYtdl(normalizedUrl)
......


async function downloadAudioWithYtdl(url) {
  return new Promise((resolve, reject) => {
    const tempFilePath = path.join('/tmp', `${nanoid(5)}.mp3`)
    const writeStream = fs.createWriteStream(tempFilePath)

    // Add more options to ytdl
    const stream = ytdl(url, {
      filter: 'audioonly',
      agent,
      requestOptions: {
        headers: {
          'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36',
        },
      },
    })

    stream.pipe(writeStream)

    writeStream.on('finish', () => {
      fs.readFile(tempFilePath, (err, data) => {
        if (err) {
          reject(err)
        } else {
          fs.unlink(tempFilePath, (unlinkErr) => {
            if (unlinkErr) {
              console.error('Error deleting temp file:', unlinkErr)
            }
          })
          resolve(data)
        }
      })
    })

    stream.on('error', (err) => {
      reject(err)
    })
  })
}