Unable to download video only file using ytdl-core chooseFormat options in Node.js

102 views Asked by At

I am trying to download the youtube video using Node.js and ytdl-core package. I followed the documentation of ytdl-core.

ytdl('http://www.youtube.com/watch?v=aqz-KE-bpKQ')
  .pipe(fs.createWriteStream('video.mp4'));

This works fine but if you want to download the video in high quality you must download download and audio files separately and merge them using ffmpeg. I am unable to download video only using custom function with "choosing a video format".

I have an endpoint with /download that execute download() function in controller. This function executes two following functions, getVideoInfo() and downloadVideo().

getVideoInfo() should create getInfo.json and videoFormat.json files in /public directory. downloadVideo() should download the video file in /public directory.

It creates the files successfully but it downloads the video file with 0 bytes.

const fs = require("fs")
const path = require("path")
const ytdl = require("ytdl-core")
const cmd = require("node-cmd")
const axios = require("axios")

async function download(req, res) {
  const url = "https://www.youtube.com/watch?v=Qdi_yp9FA-I"
  const videoPath = "public/video_only.mp4"

  try {
    const videoFormat = await getVideoInfo(url)
    await downloadVideo(url, videoFormat, videoPath)

    console.log('Video is downloaded.')
  } catch (error) {
    console.error("Error in download function:", error);
    res.status(500).send("Internal Server Error");
  }
}

async function getVideoInfo(url) {
  const info = await ytdl.getInfo(url)
  console.log("Title: " + info.videoDetails.title)

  // Save info to a JSON file
  fs.writeFileSync("public/getInfo.json", JSON.stringify(info, null, 2))

  const videoFormat = ytdl.chooseFormat(info.formats, { quality: "137" })

  // Save videoFormat to a JSON file
  fs.writeFileSync("public/videoFormat.json", JSON.stringify(videoFormat, null, 2))

  return videoFormat
}

async function downloadVideo(url, videoFormat, videoPath) {
  try {
      if (!videoFormat) {
        reject(new Error("No suitable format found."))
        return
      }

      ytdl(url, { format: videoFormat }).pipe(fs.createWriteStream(videoPath))
  } catch (error) {
    throw new Error("Error downloading video: " + error.message)
  }
}

module.exports = {
  download,
}
0

There are 0 answers