youtube-downloader

Simple Next.js website and interface to download YouTube videos to mp3 or mp4 files with URLs
git clone https://codeberg.org/night0721/youtube-downloader
Log | Files | Refs | README | LICENSE

index.tsx (4298B)


      1 import React, { useState } from "react";
      2 import Head from "next/head";
      3 import { FiDownloadCloud } from "react-icons/fi";
      4 import download from "downloadjs";
      5 
      6 export default function Home() {
      7   const [url, setUrl] = useState("");
      8   const [info, setInfo] = useState("");
      9 
     10   const getTitle = async (videoID: string) => {
     11     const youtubeAPI = `https://www.googleapis.com/youtube/v3/videos?part=snippet&id=${videoID}&fields=items(id%2Csnippet)&key=AIzaSyB8Fk-MWT_r8nVgG35gIZoP-DhJYpJ_tZ0`;
     12     const response = await fetch(youtubeAPI).then(res => res.json());
     13     return response.items[0].snippet.title;
     14   };
     15 
     16   const getVideoID = (url: string) => {
     17     if (url.match(/watch/)) {
     18       return url.split("/")[3].split("?")[1].split("=")[1];
     19     } else if (url.match(/youtu.be/)) {
     20       const videoID = url != "" && url.split("/")[3];
     21       return videoID;
     22     }
     23   };
     24 
     25   const handle = async (type: string) => {
     26     const videoID = getVideoID(url);
     27     setInfo("Processing the video...");
     28     if (videoID) {
     29       const title = await getTitle(videoID);
     30       try {
     31         fetch("https://service-api.night0721.repl.co/api/download", {
     32           method: "POST",
     33           headers: { "Content-Type": "application/json" },
     34           body: JSON.stringify({ url, type }),
     35         })
     36           .then(res => res.blob())
     37           .then(async blob => {
     38             const sizeInBytes = blob.size;
     39             if (sizeInBytes <= 0) {
     40               setInfo(
     41                 "Unable to download! Maybe File size is too high. Try to download video less than 5MB"
     42               );
     43             } else {
     44               download(
     45                 blob,
     46                 `${title}.${type}`,
     47                 type === "mp3" ? "audio/mpeg" : "video/mp4"
     48               );
     49               setInfo("Ready for download!");
     50             }
     51           });
     52       } catch (err) {
     53         console.error(err);
     54         setInfo(
     55           "Unable to download! Maybe File size is too high. Try to download video less than 5MB"
     56         );
     57       }
     58     } else {
     59       setInfo("Invalid URL");
     60     }
     61   };
     62 
     63   return (
     64     <div>
     65       <Head>
     66         <title>Youtube Downloader</title>
     67         <link
     68           rel="shortcut icon"
     69           href="https://www.youtube.com/s/desktop/066935b0/img/favicon.ico"
     70           type="image/x-icon"
     71         />
     72       </Head>
     73 
     74       <div className="py-12 w-full  h-screen">
     75         <div className="max-w-7xl mx-auto sm:px-6 lg:px-8 w-full relative top-1/4">
     76           <h3 className="text-4xl flex justify-center">
     77             {" "}
     78             <FiDownloadCloud /> &nbsp; Youtube Downloader{" "}
     79           </h3>
     80           <h4 className="text-xs py-1 flex justify-center">
     81             {" "}
     82             Sample video link : https://youtu.be/videoID{" "}
     83           </h4>
     84           <div className="bg-white overflow-hidden shadow-sm sm:rounded-lg w-full">
     85             <div className="p-6 bg-white border-b border-gray-200 flex justify-center w-full">
     86               <div className="flex w-4/5">
     87                 <input
     88                   type="text"
     89                   className="border-2 m-1.5 border-gray-300 p-2 w-full"
     90                   name="title"
     91                   id="title"
     92                   value={url}
     93                   onChange={e => {
     94                     setInfo("");
     95                     setUrl(e.target.value);
     96                   }}
     97                   placeholder="Paste the valid youtube link"
     98                   required
     99                 ></input>
    100               </div>
    101             </div>
    102             <div className="p-3 flex w-full justify-center">
    103               <button
    104                 className="p-3 m-1.5 flex w-56 justify-center bg-blue-900 text-white hover:bg-blue-600"
    105                 onClick={() => handle("mp3")}
    106               >
    107                 Download mp3
    108               </button>
    109               <button
    110                 className="p-3 m-1.5 flex w-48 justify-center bg-blue-900 text-white hover:bg-blue-600"
    111                 onClick={() => handle("mp4")}
    112               >
    113                 Download mp4
    114               </button>
    115             </div>
    116           </div>
    117           {info && <h3 className="flex justify-center p-3 m-1.5 "> {info} </h3>}
    118         </div>
    119       </div>
    120     </div>
    121   );
    122 }