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 /> 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 }