|
| 1 | +# YouTube Video Downloader Electron Desktop App |
| 2 | + |
| 3 | + |
| 4 | + |
| 5 | +## Built using: |
| 6 | +- Vite + React + Joy UI Components (Frontend) |
| 7 | +- NodeJS + Express (Backend REST Api) |
| 8 | +- Electron (Desktop app) |
| 9 | + |
| 10 | +The app was first made as a traditional web app using React and Express communicated through REST Api calls. |
| 11 | + |
| 12 | +The desktop app is currently just for Windows (I haven't actually tested it on other platforms but electron-packager should have OS-specific options). |
| 13 | + |
| 14 | +Functionally, the app utilises two main dependencies: |
| 15 | +- [distubejs/ytdl-core](https://github.com/distubejs/ytdl-core) (YouTube downloader node module) |
| 16 | +- [ffmpeg](https://www.ffmpeg.org/) (video + audio processing software) which is interfaced using the fluent-ffmpeg node module |
| 17 | + |
| 18 | +YouTube "videos" are actually formed by their respective video and audio counterparts so these parts are individually downloaded by ytdl-core and are combined using ffmpeg. |
| 19 | +As a result **ffmpeg.exe** needs to be dowwnloaded externally from the ffmpeg website and added in a folder named "ffmpeg" in the backend directory (and electron directory if building the desktop app from source). |
| 20 | + |
| 21 | +For sake of categorisation, the electron directory is basically a copy and paste of the backend along with a static build of the frontend and the main.js electron entry point file. |
| 22 | +I just thought it'd be nice to have every seperate component of the app in different folders :) |
| 23 | + |
| 24 | +## Usage: |
| 25 | +It's pretty straightforward, just input the url and press the get resolutions button. |
| 26 | + |
| 27 | +From there, you can see the available resolutions for the video (the app supports all resolutions up to and including 4k/2160p!). |
| 28 | + |
| 29 | +Press download and the video gets downloaded depending on if using the web app or desktop app: |
| 30 | + |
| 31 | +#### Desktop app: |
| 32 | +Downloaded into the `resources/app/` folder (look for the `.mp4` file with the video title). |
| 33 | + |
| 34 | +#### Web app: |
| 35 | +Downloaded into the backend folder. |
| 36 | + |
| 37 | +**NOTE:** It might take a little while for longer videos at resolutions greater than 1080p, this is because merging audio + video just takes a long time :( |
| 38 | + |
| 39 | + |
| 40 | + |
| 41 | + |
| 42 | +## Build/Run: |
| 43 | + |
| 44 | +### Desktop app (packaged zip file) |
| 45 | +1. Download the zipped app file in the releases. |
| 46 | +2. Extract it and go into the app folder. |
| 47 | +3. Run `RYTDL.exe` |
| 48 | +(The zipped app includes ffmpeg so no need to download it) |
| 49 | + |
| 50 | +### Traditional Web App: |
| 51 | +1. Install node modules for frontend and backend: |
| 52 | +```bash |
| 53 | +cd frontend |
| 54 | +npm install |
| 55 | + |
| 56 | +cd ../backend |
| 57 | +npm install |
| 58 | +``` |
| 59 | +2. Install [ffmpeg](https://www.ffmpeg.org/) and place ffmpeg.exe into a ffmpeg folder in the backend. |
| 60 | +3. Run the backend and frontend in seperate terminals |
| 61 | +```bash |
| 62 | +# backend |
| 63 | +node index.js |
| 64 | + |
| 65 | +# frontend (in a seperate terminal) |
| 66 | +npm run dev |
| 67 | +``` |
| 68 | +4. Go to `localhost:5173` in a browser and you should see the interface. |
| 69 | + |
| 70 | +--- |
| 71 | + |
| 72 | +### Desktop app (Electron) |
| 73 | +1. Install node modules for the electron app: |
| 74 | +```bash |
| 75 | +cd electron |
| 76 | +npm install |
| 77 | +``` |
| 78 | +2. Install [ffmpeg](https://www.ffmpeg.org/) and place ffmpeg.exe into a ffmpeg folder in the electron folder. |
| 79 | +3. Run the Electron app using `npx electron .` OR package it into an executable app with `npx electron-packager .` |
| 80 | +4. The interface should pop up in a desktop window if just running it using `npx electron .`, otherwise, a folder containing the `.exe` for the app will be created if packaged. |
| 81 | + |
| 82 | +## Implementation Notes/Details: |
| 83 | +- The static build of the frontend is included in the electron folder (but not in the frontend folder). If you want to build the frontend yourself using `npm run build` you'll have to modify the `index.html` for it to work with Electron. |
| 84 | +On line 8 and 9 where it says `src="/assets/index-Ccy0lpz4.js"` and `href="/assets/index-Cp3wgTPn.css"`, you must remove the prefixed `/` on the `/assets` so after removing it should look like this: |
| 85 | +```html |
| 86 | +<!doctype html> |
| 87 | +<html lang="en"> |
| 88 | + <head> |
| 89 | + <meta charset="UTF-8" /> |
| 90 | + <link rel="icon" type="image/svg+xml" href="/vite.svg" /> |
| 91 | + <meta name="viewport" content="width=device-width, initial-scale=1.0" /> |
| 92 | + <title>Youtube Downloader</title> |
| 93 | + <script type="module" crossorigin src="assets/index-Ccy0lpz4.js"></script> |
| 94 | + <link rel="stylesheet" crossorigin href="assets/index-Cp3wgTPn.css"> |
| 95 | + </head> |
| 96 | + <body> |
| 97 | + <div id="root"></div> |
| 98 | + </body> |
| 99 | +</html> |
| 100 | +``` |
| 101 | +After that, you can copy and paste the `dist` folder into the Electron folder for it to display the interface. I'm pretty sure there is a way to prevent this without manually modifying it but after trying a couple methods I found online, I gave up. |
| 102 | + |
| 103 | +- _Why does the downloaded video get downloaded to `resources/app/` in the desktop app and not somewhere more convenient?_ |
| 104 | +It should be possible for user custom download path if the user inputs the full path to the folder in the interface which is then given to the backend but I wanted to do it through a dialog window by using |
| 105 | +[window.showDirectoryPicker()](https://developer.mozilla.org/en-US/docs/Web/API/Window/showDirectoryPicker) |
| 106 | +but I believe its impossible because of security issues. I probably will implement the manual download path though. |
| 107 | + |
| 108 | +- _Having the API and frontend both in the Electron app seems weird..._ |
| 109 | +Yes, it's pretty scuffed. If you take a look in the `main.js` file in the Electron app you'll see that the backend is actually run as a seperate node process that is forked from the main Electron node process. |
| 110 | +Optimally, the Electron app would have just been the frontend that made calls to the API that is externally hosted somewhere else but I really didn't want to host it somewhere. |
| 111 | +I could have also had the backend and frontend run in Electron's main and renderer processes but I would have had to redesign the whole backend to use IPC communication instead of HTTP requests. |
| 112 | + |
| 113 | + |
| 114 | + |
| 115 | + |
0 commit comments