Theta is an intuitive platform designed for downloading YouTube videos seamlessly. With a user-friendly interface, Theta simplifies the process of saving your favorite videos for offline viewing, making it an essential tool for content lovers everywhere.
Navigate easily through a clean and straightforward layout, ensuring a hassle-free experience.
Download videos in High formats and resolutions to suit your preferences. Enjoy high quality on save content!
Contribute and collaborate! Theta is open to contributions from anyone looking to enhance its functionality. Join the community and help us grow!
Explore Theta in action here: theta-bucket.vercel.app
To run Theta locally, follow these steps:
Ensure you have the following installed on your machine:
Clone the repository:
git clone https://github.com/manoj-chavan-13/theta.git
cd theta
Install dependencies:
npm install
Run the project:
npm start
Open your web browser and go to http://localhost:3000
to start using the application.
While Theta operates smoothly on localhost, users may encounter issues when deploying on platforms like Vercel. Common errors include:
If you experience any issues, consider the following:
If issues persist, please report them on our GitHub Issues page.
We welcome and encourage contributions to Theta! To get involved, please follow these steps:
git checkout -b feature/your-feature-name
git commit -m "Brief description of your changes"
git push origin feature/your-feature-name
Theta utilizes several key packages to enhance its functionality. Below is a list of the packages used, their purposes, and basic usage instructions:
import ytdl from "@distube/ytdl-core";
import ffmpeg from "fluent-ffmpeg";
req.body
property.app.use(bodyParser.json());
import cors from "cors";
app.use(cors());
import express from "express";
const app = express();
import ffmpegPath from "ffmpeg-static";
ffmpeg().setFfmpegPath(ffmpegPath);
ffmpeg()
.input("video.mp4")
.output("output.mp4")
.run();
@distube/ytdl-core
, you can use it to handle video downloads.To install the dependencies, run:
npm install @distube/ytdl-core @ffmpeg/ffmpeg body-parser cors express ffmpeg-static fluent-ffmpeg mergerino mp4box ytdl-core
This will install all the necessary packages for Theta to function properly.
const downloadAudio = async (videoURL) => {
const audioFilePath = path.join(__dirname, "audio.mp3");
const audioStream = ytdl(videoURL, {
filter: (format) => format.hasAudio,
quality: "highest",
requestOptions: {
headers: {
"User-Agent": "Mozilla/5.0 ...", // Setting a user-agent to prevent blocking
},
},
});
return new Promise((resolve, reject) => {
audioStream
.pipe(fs.createWriteStream(audioFilePath))
.on("finish", () => {
console.log("Audio download complete!");
resolve(audioFilePath);
})
.on("error", (err) => {
console.error("Error downloading audio:", err);
reject(err);
});
});
};
videoURL
- The URL of the YouTube video.ytdl
to create a stream of the audio format.audio.mp3
.const downloadVideo = async (videoURL) => {
const videoFilePath = path.join(__dirname, "video.mp4");
const videoStream = ytdl(videoURL, {
filter: (format) => format.hasVideo,
quality: "highestvideo",
requestOptions: {
headers: {
"User-Agent": "Mozilla/5.0 ...", // Setting a user-agent to prevent blocking
},
},
});
return new Promise((resolve, reject) => {
videoStream
.pipe(fs.createWriteStream(videoFilePath))
.on("finish", () => {
console.log("Video download complete!");
resolve(videoFilePath);
})
.on("error", (err) => {
console.error("Error downloading video:", err);
reject(err);
});
});
};
videoURL
- The URL of the YouTube video.video.mp4
.const combineAudioVideo = async (audioFilePath, videoFilePath) => {
const outputFilePath = path.join(__dirname, "output.mp4");
return new Promise((resolve, reject) => {
ffmpeg()
.setFfmpegPath(ffmpegPath) // Setting the path for FFmpeg
.input(videoFilePath)
.input(audioFilePath)
.outputOptions("-c:v copy") // Copy video codec
.outputOptions("-c:a aac") // Use AAC audio codec
.output(outputFilePath)
.on("end", () => {
console.log("Merging finished! Output saved to:", outputFilePath);
resolve(outputFilePath);
})
.on("error", (err) => {
console.error("Error during merging:", err);
reject(err);
})
.run();
});
};
audioFilePath
- Path to the downloaded audio file.videoFilePath
- Path to the downloaded video file.const deleteFilesAfterDelay = (filePaths, delay) => {
setTimeout(() => {
filePaths.forEach((filePath) => {
fs.unlink(filePath, (err) => {
if (err) {
console.error(`Error deleting file ${filePath}:`, err);
} else {
console.log(`File deleted after ${delay / 1000} seconds: ${filePath}`);
}
});
});
}, delay);
};
filePaths
- An array of file paths to delete.delay
- Time in milliseconds to wait before deletion.setTimeout
to schedule the deletion of files.fs.unlink
to delete each file and logs the result.app.post("/download", async (req, res) => {
const { videoURL } = req.body;
try {
const audioFilePath = await downloadAudio(videoURL);
const videoFilePath = await downloadVideo(videoURL);
const outputFilePath = await combineAudioVideo(audioFilePath, videoFilePath);
res.json({
success: true,
outputFile: `/download/${path.basename(outputFilePath)}`,
});
// Schedule deletion of the temporary files after 10 minutes
deleteFilesAfterDelay(
[audioFilePath, videoFilePath, outputFilePath],
10 * 60 * 1000
);
} catch (error) {
res.json({ success: false, message: error.message });
}
});
videoURL
from the request body.downloadAudio
, downloadVideo
, and combineAudioVideo
functions sequentially.app.get("/download/:filename", (req, res) => {
const filePath = path.join(__dirname, req.params.filename);
res.download(filePath, (err) => {
if (err) {
console.error("Error downloading file:", err);
res.status(500).send("Could not download the file.");
}
});
});
:filename
- The name of the file to download.req.params.filename
.res.download
to send the file to the client.To run this application:
/download
endpoint with a JSON body containing the videoURL
(e.g., via Postman or a frontend application).Hereโs an example of how to send a POST request using cURL:
curl -X POST http://localhost:3000/download -H "Content-Type: application/json" -d '{"videoURL": "https://www.youtube.com/watch?v=YOUR_VIDEO_ID"}'
Replace YOUR_VIDEO_ID
with the actual ID of the YouTube video you want to download.
This project is licensed under the ISC License. See the LICENSE file for more details.
For questions, issues, or feedback, please feel free to raise an issue on the GitHub Repository or connect with me on LinkedIn: manoj-chavan-1311 .
Thank you for exploring Theta! We hope you find it useful for effortlessly downloading your favorite YouTube videos. Happy downloading!