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,
}