user2419677
user2419677

Reputation:

How to write a JavaScript download function in my YouTube MP4 & MP3 Downloader

// put your own value below!
const apiKey = "AIzaSyCGKrLxvpot6hrekFHQTPaCGeOFj92T3ao";
const searchURL = "https://www.googleapis.com/youtube/v3/search";

function formatQueryParams(params) {
  const queryItems = Object.keys(params).map(
    key => `${encodeURIComponent(key)}=${encodeURIComponent(params[key])}`
  );
  return queryItems.join("&");
}

function displayResults(responseJson) {
  // if there are previous results, remove them
  console.log(responseJson);
  $("#results-list").empty();
  // iterate through the items array
  for (let i = 0; i < responseJson.items.length; i++) {
    // for each video object in the items
    //array, add a list item to the results
    //list with the video title, description,
    //and thumbnail
    $("#results-list").append(
      `<li><h3>${responseJson.items[i].snippet.title}</h3>
      <p>${responseJson.items[i].snippet.description}</p>
      <img src='${responseJson.items[i].snippet.thumbnails.default.url}'>
      </li>`
    );
  }
  //display the results section
  $("#results").removeClass("hidden");
}

async function downloadVideo(videoId) {
  console.log(videoId);
  const response = await fetch(`https://getvideo.p.rapidapi.com/?url=https%3A%2F%2Fwww.youtube.com%2Fwatch%3Fv%3D${videoId}`, {
    headers: {
      "X-RapidAPI-Host": "getvideo.p.rapidapi.com",
      "X-RapidAPI-Key": "d390d7b0e9msh42dc09f4e07e285p1486c4jsne0a4edb9e61e"
    }
  });
  const data = await response.json();
  return {
    audio: data.streams.filter(stream => {
      return stream.format === "audio only";
    })[0].url,
    video: data.streams.filter(stream => {
      return stream.format !== "audio only";
    })[0].url
  };
}

function getYouTubeVideos(query, maxResults = 50) {
  const params = {
    key: apiKey,
    q: query,
    part: "snippet",
    maxResults,
    type: "video"
  };
  const queryString = formatQueryParams(params);
  const url = searchURL + "?" + queryString;

  console.log(url);

  fetch(url)
    .then(response => {
      if (response.ok) {
        return response.json();
      }
      throw new Error(response.statusText);
    })
    .then(responseJson => downloadVideo(responseJson.items[0].id.videoId))
    .then(download => console.log(download))
    // .then(responseJson => displayResults(responseJson))
    .catch(err => {
      $("#js-error-message").text(`Something went wrong: ${err.message}`);
    });
}

function watchForm() {
  $("form").submit(event => {
    event.preventDefault();
    const searchTerm = $("#js-search-term").val();
    const maxResults = $("#js-max-results").val();
    getYouTubeVideos(searchTerm, maxResults);
  });
}

$(watchForm);
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <meta http-equiv="X-UA-Compatible" content="ie=edge" />
    <title>YouTube video finder</title>
    <link rel="stylesheet" href="style\style.css" />
    <link
      rel="stylesheet"
      href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css"
    />
    <script
      src="https://code.jquery.com/jquery-3.3.1.js"
      integrity="sha256-2Kok7MbOyxpgUVvAk/HJ2jigOSYS2auK4Pfzbm7uH60="
      crossorigin="anonymous"
    ></script>
  </head>

  <body>
    <div class="container">
      <div class="left">
        <h1 class="finder-heading">Download a YouTube video</h1>
        <form id="js-form">
          <label for="search-term"></label>
          <input
            class="search-input"
            type="text"
            name="search-term"
            id="js-search-term"
            required
            placeholder="Search YouTube Videos..."
          />

          <label for="max-results"></label>
          <input
            class="max-number"
            type="number"
            name="max-results"
            id="js-max-results"
            value="10"
          />

          <input class="go-button" type="submit" value="Search" />
        </form>
      </div>

      <!-- <div class="right">
        <h1 class="downloader-heading">Download a YouTube video</h1>
        <input class="URL-input" placeholder="Paste YouTube link here..." />
        <button class="download-button">
          <i class="fa fa-download"></i> Download
        </button>
      </div> -->

      <p id="js-error-message" class="error-message"></p>
      <section id="results" class="hidden">
        <h2>Search results</h2>
        <ul id="results-list"></ul>
      </section>
    </div>
    <script src="apps\app.js"></script>
  </body>
</html>

I am making a web app that is using a 2 API mashup of both youtube API and GET Video and Audio URL API. The problem that I am having is that I don't know how to code the javascript needed in the download portion in this project...

For the moment I have the javascript coded to a point where if you run it and inspect in google chrome you will see in the console how it captures both the audio file and video file of whatever video link you choose to insert into the input.

I expect for this to capture the video produce a thumbnail in the HTML with a given option of downloading MP4 or MP3

Upvotes: 0

Views: 4486

Answers (2)

help
help

Reputation: 31

i use my API Key and its work

const apiKey = "Your Key";
const searchURL = "https://www.googleapis.com/youtube/v3/search";

function formatQueryParams(params) {
  const queryItems = Object.keys(params).map(
    key => `${encodeURIComponent(key)}=${encodeURIComponent(params[key])}`
  );
  return queryItems.join("&");
}

function displayResults(responseJson) {
  console.log(responseJson);
  $("#results-list").empty();
 
  for (let i = 0; i < responseJson.items.length; i++) {
  
    $("#results-list").append(
      `<li><h3>${responseJson.items[i].snippet.title}</h3>
      <p>${responseJson.items[i].snippet.description}</p>
      <img src='${responseJson.items[i].snippet.thumbnails.default.url}'>
      </li>`
    );
  }
  
  $("#results").removeClass("hidden");
}

async function downloadVideo(videoId) {
  console.log(videoId);
  const response = await fetch(`https://getvideo.p.rapidapi.com/?url=https%3A%2F%2Fwww.youtube.com%2Fwatch%3Fv%3D${videoId}`, {
    headers: {
      "X-RapidAPI-Host": "getvideo.p.rapidapi.com",
      "X-RapidAPI-Key": "d390d7b0e9msh42dc09f4e07e285p1486c4jsne0a4edb9e61e"
    }
  });
  const data = await response.json();
  return {
    audio: data.streams.filter(stream => {
      return stream.format === "audio only";
    })[0].url,
    video: data.streams.filter(stream => {
      return stream.format !== "audio only";
    })[0].url
  };
}

function getYouTubeVideos(query, maxResults = 50) {
  const params = {
    key: apiKey,
    q: query,
    part: "snippet",
    maxResults,
    type: "video"
  };
  const queryString = formatQueryParams(params);
  const url = searchURL + "?" + queryString;

  console.log(url);

   fetch(url)
      .then(r => r.json())
      .then(data => {
        displayResults(data);
        return downloadVideo(data.items[0].id.videoId);
      })
      .then(download => console.log(download))
      .catch(err => {
        $("#js-error-message").text(`Something went wrong: ${err.message}`);
      });
}


function watchForm() {
  $("form").submit(event => {
    event.preventDefault();
    const searchTerm = $("#js-search-term").val();
    const maxResults = $("#js-max-results").val();
    getYouTubeVideos(searchTerm, maxResults);
  });
}

$(watchForm);
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <meta http-equiv="X-UA-Compatible" content="ie=edge" />
    <title>YouTube video finder</title>
    <link rel="stylesheet" href="style\style.css" />
    <link
      rel="stylesheet"
      href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css"
    />
    <script
      src="https://code.jquery.com/jquery-3.3.1.js"
      integrity="sha256-2Kok7MbOyxpgUVvAk/HJ2jigOSYS2auK4Pfzbm7uH60="
      crossorigin="anonymous"
    ></script>
  </head>

  <body>
    <div class="container">
      <div class="left">
        <h1 class="finder-heading">Download a YouTube video</h1>
        <form id="js-form">
          <label for="search-term"></label>
          <input
            class="search-input"
            type="text"
            name="search-term"
            id="js-search-term"
            required
            placeholder="Search YouTube Videos..."
          />

          <label for="max-results"></label>
          <input
            class="max-number"
            type="number"
            name="max-results"
            id="js-max-results"
            value="10"
          />

          <input class="go-button" type="submit" value="Search" />
        </form>
      </div>

      <!-- <div class="right">
        <h1 class="downloader-heading">Download a YouTube video</h1>
        <input class="URL-input" placeholder="Paste YouTube link here..." />
        <button class="download-button">
          <i class="fa fa-download"></i> Download
        </button>
      </div> -->

      <p id="js-error-message" class="error-message"></p>
      <section id="results" class="hidden">
        <h2>Search results</h2>
        <ul id="results-list"></ul>
      </section>
    </div>
    <script src="apps\app.js"></script>
  </body>
</html>

Upvotes: 0

Kobe
Kobe

Reputation: 6446

The issue is the order of your .then()'s. You are returning data with each call, and in one you return a console.log(), which will be undefined. You can fix it like this:

function getYouTubeVideos(query, maxResults = 50) {
  const params = {
    key: apiKey,
    q: query,
    part: "snippet",
    maxResults,
    type: "video"
  };
  const queryString = formatQueryParams(params);
  const url = searchURL + "?" + queryString;

  console.log(url);

  fetch(url)
          .then(r => r.json())
          .then(data => {
            displayResults(data);
            return downloadVideo(data.items[0].id.videoId);
          })
          .then(download => console.log(download))
          .catch(err => {
            $("#js-error-message").text(`Something went wrong: ${err.message}`);
          });
}

Upvotes: 1

Related Questions