├── README.md
├── css
└── style.css
├── index.php
├── js
└── color_palette.js
├── res
└── favicon.png
└── scripts
├── GetVideoInfo.php
├── download_img.php
└── download_video.php
/README.md:
--------------------------------------------------------------------------------
1 | # youtube_video_downloader
2 |
3 |
--------------------------------------------------------------------------------
/css/style.css:
--------------------------------------------------------------------------------
1 | @import url("https://fonts.googleapis.com/css2?family=Poppins:wght@200;300;400;500;600;800;900&display=swap");
2 |
3 | * {
4 | margin: 0;
5 | padding: 0;
6 | box-sizing: border-box;
7 | font-family: "Poppins", sans-serif;
8 | }
9 |
10 | :root {
11 | --primary-color: #4193f0;
12 | --text-color-dark: #333;
13 | --text-color-light: #fff;
14 | --light-grey: #f5f5f5;
15 | }
16 |
17 | .downloader {
18 | height: 100vh;
19 | width: 100%;
20 | display: flex;
21 | align-items: center;
22 | justify-content: center;
23 | flex-direction: column;
24 | background-color: var(--primary-color);
25 | }
26 |
27 | .main {
28 | width: 426px;
29 | display: flex;
30 | flex-direction: column;
31 | padding: 15px;
32 | border-radius: 5px;
33 | /* background: var(--text-color-light);
34 | box-shadow: 0.1px 4px 8px 2px rgba(0, 0, 0, 0.05); */
35 | background: rgba(255, 255, 255, 0.25);
36 | box-shadow: 0 8px 32px 0 rgba(31, 38, 135, 0.37);
37 | backdrop-filter: blur(4px);
38 | -webkit-backdrop-filter: blur(4px);
39 | border-radius: 10px;
40 | border: 1px solid rgba(255, 255, 255, 0.18);
41 | }
42 |
43 | .main form {
44 | width: 100%;
45 | height: 45px;
46 | display: flex;
47 | justify-content: space-between;
48 | }
49 |
50 | .main form input:first-child {
51 | width: 80%;
52 | height: 100%;
53 | padding: 10px;
54 | border: none;
55 | outline: none;
56 | margin-right: 4px;
57 | border-radius: 5px;
58 | font-size: 1em;
59 | box-shadow: 0.1px 2px 8px 4px rgba(0, 0, 0, 0.05);
60 | }
61 |
62 | .main form input:last-child {
63 | width: 20%;
64 | height: 100%;
65 | padding: 10px;
66 | margin-left: 4px;
67 | border: none;
68 | outline: none;
69 | border-radius: 5px;
70 | background: var(--primary-color);
71 | color: var(--text-color-light);
72 | font-size: 1em;
73 | cursor: pointer;
74 | box-shadow: 0.1px 2px 8px 4px rgba(0, 0, 0, 0.05);
75 | }
76 |
77 | .video_detail_box {
78 | width: 100%;
79 | margin-top: 1em;
80 | }
81 |
82 | .video_detail_box .thumbnail_box {
83 | position: relative;
84 | }
85 |
86 | .thumbnail_box #img_download_btn {
87 | position: absolute;
88 | right: 10px;
89 | bottom: 10px;
90 | color: var(--text-color-light);
91 | height: 35px;
92 | width: 35px;
93 | border-radius: 50%;
94 | text-decoration: none;
95 | display: inline-flex;
96 | align-items: center;
97 | justify-content: center;
98 | background: var(--primary-color);
99 | }
100 |
101 | .thumbnail_box #original_video_link_btn {
102 | position: absolute;
103 | right: 55px;
104 | bottom: 10px;
105 | color: var(--text-color-light);
106 | height: 35px;
107 | width: 35px;
108 | border-radius: 50%;
109 | text-decoration: none;
110 | display: inline-flex;
111 | align-items: center;
112 | justify-content: center;
113 | background: #ec407a;
114 | }
115 |
116 | .thumbnail_box img {
117 | height: auto;
118 | width: 100%;
119 | border-radius: 5px;
120 | object-fit: cover;
121 | }
122 |
123 | .text_info {
124 | width: 100%;
125 | display: flex;
126 | flex-direction: column;
127 | margin-top: 10px;
128 | }
129 |
130 | .text_info table {
131 | border: 1px dashed #ccc;
132 | margin-top: 10px;
133 | }
134 |
135 | .text_info table th {
136 | padding: 10px;
137 | }
138 | .text_info table td {
139 | text-align: center;
140 | padding: 10px;
141 | }
142 |
143 | .additional_info {
144 | display: flex;
145 | align-items: center;
146 | margin-top: 10px;
147 | }
148 |
149 | .additional_info a {
150 | padding: 5px 10px 5px 10px;
151 | color: var(--text-color-light);
152 | font-size: 13px;
153 | border-radius: 5px;
154 | text-decoration: none;
155 | background: var(--primary-color);
156 | }
157 |
158 | .additional_info p {
159 | padding: 5px 10px 5px 10px;
160 | color: #000;
161 | font-size: 13px;
162 | border-radius: 5px;
163 | margin-left: 5px;
164 | box-shadow: 0.1px 2px 8px 4px rgba(0, 0, 0, 0.05);
165 | }
166 |
167 | #download_btn {
168 | color: var(--text-color-light);
169 | text-decoration: none;
170 | background: var(--primary-color);
171 | padding-left: 10px;
172 | padding-right: 10px;
173 | padding-top: 5px;
174 | padding-bottom: 5px;
175 | border-radius: 5px;
176 | font-size: 15px;
177 | display: inline-block;
178 | }
179 |
180 | .instruction_box {
181 | width: 100%;
182 | display: flex;
183 | align-items: center;
184 | justify-content: center;
185 | flex-direction: column;
186 | margin-top: 2em;
187 | }
188 |
189 | .instruction_box h3 {
190 | margin-top: 10px;
191 | }
192 | .instruction_box p {
193 | font-size: 14px;
194 | margin-top: 5px;
195 | }
196 |
197 | .instruction_box label {
198 | height: 50px;
199 | width: 50px;
200 | border-radius: 50%;
201 | background: var(--primary-color);
202 | display: flex;
203 | align-items: center;
204 | justify-content: center;
205 | }
206 |
207 | .instruction_box label i {
208 | color: var(--text-color-light);
209 | font-size: 1.2em;
210 | }
211 |
212 | /* COLOR PALETTE */
213 |
214 | .color-palette {
215 | position: absolute;
216 | display: flex;
217 | flex-direction: column;
218 | justify-content: center;
219 | margin: 12px;
220 | right: 0;
221 | background: rgba(255, 255, 255, 0.2);
222 | box-shadow: 0 8px 32px 0 rgba(31, 38, 135, 0.37);
223 | backdrop-filter: blur(1.5px);
224 | -webkit-backdrop-filter: blur(1.5px);
225 | border-radius: 10px;
226 | border: 1px solid rgba(255, 255, 255, 0.18);
227 | border-radius: 30px;
228 | padding: 8px;
229 | text-align: center;
230 | top: 50%;
231 | -ms-transform: translateY(-50%);
232 | transform: translateY(-50%);
233 | }
234 |
235 | .color-palette .theme-color {
236 | background-color: red;
237 | border-radius: 50%;
238 | width: 30px;
239 | height: 30px;
240 | cursor: pointer;
241 | }
242 |
243 | .color-palette .theme-color:not(:last-child) {
244 | margin-bottom: 10px;
245 | }
246 |
247 | /* drak mode palette */
248 |
249 | .dark-mode {
250 | position: absolute;
251 | top: 12px;
252 | right: 12px;
253 | background: rgba(255, 255, 255, 0.25);
254 | box-shadow: 0 8px 32px 0 rgba(31, 38, 135, 0.37);
255 | backdrop-filter: blur(4px);
256 | -webkit-backdrop-filter: blur(4px);
257 | border-radius: 50%;
258 | padding: 8px 13px;
259 | border: 1px solid rgba(255, 255, 255, 0.18);
260 | }
261 |
262 | .dark-mode span {
263 | font-size: 20px;
264 | cursor: pointer;
265 | }
266 |
267 | @media (max-width: 800px) {
268 | .main {
269 | width: 70%;
270 | }
271 | }
272 |
273 | @media (max-width: 500px) {
274 | .main {
275 | width: 80%;
276 | }
277 | }
278 |
279 | @media (max-width: 400px) {
280 | .text_info table tbody tr th {
281 | font-size: 14px;
282 | }
283 |
284 | #download_btn {
285 | font-size: 8px;
286 | }
287 | }
288 |
289 | /* Media Queries */
290 | @media only screen and (max-width: 436px) {
291 | .color-palette {
292 | max-width: 90%;
293 | min-width: 90%;
294 | }
295 |
296 | .color-palette .theme-color {
297 | width: 22px;
298 | height: 22px;
299 | }
300 | }
301 |
302 | @media only screen and (max-width: 636px) {
303 | .color-palette {
304 | flex-direction: row;
305 | justify-content: center;
306 | left: 50%;
307 | bottom: 0;
308 | padding: 0;
309 | margin: 0 auto;
310 | width: 400px;
311 | margin-bottom: 16px;
312 | text-align: center;
313 | /*to remove*/
314 | top: auto;
315 | transform: translateX(-50%);
316 | }
317 |
318 | .color-palette .theme-color {
319 | margin-top: 10px;
320 | }
321 |
322 | .color-palette .theme-color:not(:last-child) {
323 | margin-right: 10px;
324 | }
325 | }
326 |
--------------------------------------------------------------------------------
/index.php:
--------------------------------------------------------------------------------
1 | playabilityStatus->status;
17 |
18 | $formats = $video->streamingData->formats;
19 | $thumbnails = $video->videoDetails->thumbnail->thumbnails;
20 | $title = $video->videoDetails->title;
21 | $short_description = $video->videoDetails->shortDescription;
22 | $channel_id = $video->videoDetails->channelId;
23 | $channel_name = $video->videoDetails->author;
24 | $views = $video->videoDetails->viewCount;
25 | $video_duration_in_seconds = $video->videoDetails->lengthSeconds;
26 | $thumbnail = end($thumbnails)->url;
27 |
28 | // seconds to minutes&hours
29 | $hours = floor($video_duration_in_seconds / 3600);
30 | $minutes = floor(($video_duration_in_seconds / 60) % 60);
31 | $seconds = $video_duration_in_seconds % 60;
32 | }
33 | }
34 | }
35 |
36 | ?>
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 | Youtube Video Downloader
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
83 |
84 |
86 |
87 |
88 |
Entered url is invalid.
89 |
make sure url is valid.
90 |
91 |
92 |
93 |
94 |
Copy video url & paste here.
95 |
make sure url is valid.
96 |
97 |
98 |
99 |
100 |
101 |
102 |

103 |
104 |
105 |
106 |
107 | url == "") { ?>
110 |
111 |
112 |
Unsupported.
113 |
This video is currently unsupported.
114 |
115 |
116 |
117 |
118 |
119 |
120 |
121 |
126 |
127 |
128 |
129 | Quality |
130 | Format |
131 | Download |
132 |
133 |
134 | url == "") {
138 | $signature = "https://youtube.com?" . $format->signatureCipher;
139 | parse_str(parse_url($signature, PHP_URL_QUERY), $parse_signature);
140 | $url = $parse_signature['url'] . "&sig=" . $parse_signature['s'];
141 | } else {
142 | $url = $format->url;
143 | }
144 | ?>
145 |
146 |
147 | qualityLabel) echo $format->qualityLabel;
148 | else echo "Unknown"; ?>
149 | |
150 | mimeType) echo explode(";", explode("/", $format->mimeType)[1])[0];
151 | else echo "Unknown"; ?>
152 | |
153 | mimeType)[1])[0];
154 | else echo "mp4"; ?>" id="download_btn"> Download |
155 |
156 |
157 |
158 |
159 |
160 |
161 |
162 |
163 |
164 |
167 |
168 |
169 |
Unable to fetch video info.
170 |
make sure url is valid.
171 |
172 |
173 |
174 |
175 |
176 |
177 |
178 |
179 |
--------------------------------------------------------------------------------
/js/color_palette.js:
--------------------------------------------------------------------------------
1 | //get the theme from local storage
2 | getTheme();
3 |
4 | //color palette
5 | const colors = [
6 | "hsl(345, 80%, 50%)",
7 | "hsl(100, 80%, 50%)",
8 | "hsl(200, 80%, 50%)",
9 | "hsl(227, 66%, 55%)",
10 | "hsl(26, 80%, 50%)",
11 | "hsl(44, 90%, 51%)",
12 | "hsl(280, 100%, 65%)",
13 | "hsl(480, 100%, 25%)",
14 | "hsl(180, 100%, 25%)",
15 | ];
16 |
17 | const colorBtns = document.querySelectorAll(".theme-color");
18 | const darkModeBtn = document.querySelector(".dark-mode-btn");
19 |
20 | //change theme to dark
21 | var isDark = false;
22 | darkModeBtn.addEventListener("click", () => {
23 | if(!isDark) {
24 | changeTheme("#000");
25 | isDark = true;
26 | }else{
27 | changeTheme(colors[3]);
28 | isDark = false;
29 | }
30 | });
31 |
32 | //loop through colors array and set each color to a button
33 | for (let i = 0; i < colorBtns.length; i++) {
34 | colorBtns[i].style.backgroundColor = colors[i];
35 | }
36 |
37 | colorBtns.forEach((btn) => {
38 | btn.addEventListener("click", () => {
39 | changeTheme(btn.style.backgroundColor);
40 | });
41 | });
42 |
43 | function changeTheme(color) {
44 | document.documentElement.style.setProperty("--primary-color", color);
45 | saveTheme(color);
46 | }
47 |
48 | //get the theme from local storage
49 | function getTheme() {
50 | const theme = localStorage.getItem("theme");
51 | if (theme) {
52 | changeTheme(theme);
53 | }
54 | }
55 |
56 | //save the theme to local storage
57 | function saveTheme(color) {
58 | localStorage.setItem("theme", color);
59 | }
60 |
--------------------------------------------------------------------------------
/res/favicon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/abdellatif-laghjaj/youtube_video_downloader/aec23010efcbd10a6375d9d9c6b5f0a99f26e843/res/favicon.png
--------------------------------------------------------------------------------
/scripts/GetVideoInfo.php:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/scripts/download_img.php:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/scripts/download_video.php:
--------------------------------------------------------------------------------
1 |