I'd always wanted to build my very own youtube mp3 downloader and as soon as I understood how the youtube API works and went through the ytdl-core documentation and a few examples, I went to work.
The interesting about this is that this program is part of a relatively more complex product I'm building and decided to make it open-source because I believe someone might find it useful.
I promise you that at the end of this article, you'll have your very own YouTube MP3 Downloader running locally.
Here's how you can build yours. I'll try to make this as detailed as possible. Let's goo!
This entire project was built with:
NodeJS+Express - for the backend
ReactJs for Frontend
TailwindCss for the styling
Set-Up
Open your terminal and type this in:
mkdir ytdownloader
cd ytdownloader
code .
or just open the folder in vscode
once you're in, we're going to first set up our NodeJS Server. Here's how we'll do that:
first, run *npm init -y*
this will create a new *package.json*
for us. It's quite important.
Then copy and paste this in your terminal:
*npm i express concurrently axios ytdl-core jquery*
The above code will install:
Express Server
Concurrently
Axios
ytdl-core
jquery
Once your installation has been completed, let's set up our server file.
Create a new file and call it server.js
. Open the file and we'll initialize our express server and get our app running on a port.
Copy and Paste this in your server.js
const express = require('express');
const app = express();
const port = 5000;
const path = require('path');
const ytdl = require('ytdl-core');
app.get('/test', (req, res) => {
console.log('it works!');
});
app.listen(port, () => console.log(`Server started on port ${port}`));
Save your file and then type in node server.js
to start your server. visit http://localhost:5000/test on your web browser and you should see "it works!" on your vscode terminal.
Now that we have our server all set up and ready, let's set up our react frontend.
We'll create a new folder called client where our react app will live. Do that, and then run this in the parent directory "ytdownloader":
*npx create-react-app client*
The above command creates our client folder for us and installs react in there. We then cd into our client folder and get to work.
The first most important thing to do is to add our nodeJS server URL to our react package.json file. Open your package.json file and paste this after 'scripts'.
"proxy" : "http://localhost:5000",
Next is to head over to our src folder and create a new folder we'll call *components*
. Inside this folder, we'll create a component called *Download.js*
. Open it up and copy and paste this inside:
import React, { Component } from 'react';
import axios from 'axios';
import $ from 'jquery';
class Download extends Component {
constructor(props) {
super(props);
this.state = {
link: '',
downloads: null
}
}
onChangeHandle = (e) => {
const { name, value } = e.target;
this.setState({
[name] : value
});
}
onSubmit = (e) => {
e.preventDefault();
axios
.post('/data', $(e.target).serialize())
.then(res => {console.log(res.data)
if (res.data.message === "filled!") {
window.open('http://localhost:5000/downloads', '_parent')
}
})
.catch(err => {
console.error(err)
})
}
render() {
return (
<div className="w-1/2 center m-auto" >
<form onSubmit={this.onSubmit.bind(this)} className="flex flex-col items-center">
<input type="text"
className="shadow appearance-none mt-5 mb-5 border rounded w-96 py-3 px-7 text-gray-700 leading-tight focus:outline-none focus:shadow-outline"
value={this.state.link}
name="link"
placeholder = "Paste Link Here"
onChange={this.onChangeHandle.bind(this)}
required
/>
<button
className="bg-blue-500 m-auto hover:bg-blue-700 text-white font-bold w-60 py-2 px-8 rounded focus:outline-none focus:shadow-outline" type="submit">
Download
</button>
</form>
</div>
);
}
}
export default Download;
Save and head over to your App.js
component. Replace everything in there with this:
import './App.css';
import './index.css';
import Download from './components/Download';
function App() {
return (
<div className="App">
<Download/>
</div>
);
}
export default App;
All done. Now lets's get to styling!
First, we have to install and set up tailwindcss for our react app. Follow the steps in this article and come back once you're done.
*NB: Styling with Tailwind is completely optional. And your application is ready at this point.*
Once you have tailwind installed and setup, copy and paste this in your index.css
file:
@tailwind base;
@tailwind components;
@tailwind utilities;
.App {
max-width: 1300px;
margin: 0 auto;
}
body {
margin: 0;
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen',
'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue',
sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}
code {
font-family: source-code-pro, Menlo, Monaco, Consolas, 'Courier New',
monospace;
}
.box {
width: 279px;
height: 231px;
}
And one last thing to do is to set up concurrently
it's a pretty neat package that runs your NodeJs and ReactJs server at the same time.
Open the package.json
in your parent directory i.e, ytdownloader
folder. Copy and paste this inside of scripts
:
"client-install": "cd client && npm install",
"start": "node server.js",
"server": "nodemon server.js",
"client": "npm start --prefix client",
"dev": "concurrently \"npm run server\" \"npm run client\""
should look like this:
...
"scripts": {
"client-install": "cd client && npm install",
"start": "node server.js",
"server": "nodemon server.js",
"client": "npm start --prefix client",
"dev": "concurrently \"npm run server\" \"npm run client\""
},
...
and you can simply run `npm run dev` to start your server!
And that's all folks! Now you've built your very own youtube downloader!
I happen to be spending a lot more time with the ytdl-core API and will most likely be writing about it as I explore and discover anything cool. Stay tuned!
GitHub repo link here: ytdownloader-react-node