Showing the most recent video in a YouTube playlist

I'm looking for a way to embed the most recent video from a YouTube playlist in a Hype document. Bonus: I'd love to display the description that corresponds to that video. Any ideas?

This is the playlist: https://www.youtube.com/playlist?list=PLimesz8836OfGhG5x8EfUnN0kEEuPKzoo

Thanks!

If I use the share icon on the playlist page and then choose embed, I get iframe code that doesn't contain a particular video. It seems to show the first.

But I think from the creator interface you might be able to apply a sort to the playlist?

Maybe then it always chooses the first in the list, which could be from a "Date added (newest)?"

<iframe width="560" height="315" src="https://www.youtube.com/embed/videoseries?si=QBYvc0uIL4EHCIL0&amp;list=PLimesz8836OfGhG5x8EfUnN0kEEuPKzoo" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" allowfullscreen></iframe>

Adding that as the Inner HTML of a Rectangle Element seems to show just one video with its title.

1 Like

Thank you! That worked great!

1 Like

Glad @Jonathan solution works for you.
You also mentioned about getting the description.

You can do this by using the Google Cloud APIs for YouTube.
You will need to sign up to Google Cloud free account and then creat a new project.
There are plenty of tutorials about on how to do that. Here's just one of them.

You will want the project to be for web when it comes to that choice.

Once you project is created.
You then will need to enable a service for the project. in this case YouTube Data v3 Api

This is all done in the Cloud Console area.


Once the service is selected, you can manage it.
Near the bottom of it's management page, use the Methods drop down

Screenshot 2023-09-21 at 08.49.37

to deselect all the options and then only select list under the : youtube.data.v3.V3DataPlaylistService



You will need to create an API Key for the project.

Again plenty of tutorials on all of this.

In the Projects dashboard you can create credentials. Choose an API Key



When the key is created it will popup. Copy the key and then click the edit Key button.
(You can alway get the key again later )



It's important to restrict access to the key and where it can be used and with what.
Google can charge you unexpectedly if it is hijacked and used beyond the free tariffs. Read their pricing and docs about this.

To put restrictions on where it can be used and what it can be used with. Note this is what I have done in a brief look at how to dod this. There may be more or less you should do to protect the API key and its usage. Read their docs about this and how to protect it to be fully protected. ( yes that's a disclaimer on my part)



Restrict to specified website/s by selecting websites. and using the add button.

Restrict the API services , in this case to use only the same YouTube service you enabled for the project.
use the dropdown to select it

Then hit the save button.

Also to test in hypes preview, I opened the Hype project in preview and copied the url to add as allowed.
i.e http://127.0.0.1:49456/*

That may change on each quit and launch of Hype so would need to be updated.



The above in reality should only take a few minutes to set up. It took longer to write this post than to do it.



Now in hype we can use the Api to get the last playlist item, title, description etc.

We call this function on scene load.

//== Function to populate the video information
async function populate() {
  //== Replace "YOUR API KEY HERE" with your actual API key
  const API_KEY = "YOUR_API_KEY_HERE";
  
  //== Construct the URL for the YouTube API request
  const requestURL = "https://www.googleapis.com/youtube/v3/playlistItems?part=snippet&maxResults=1&playlistId=PLimesz8836OfGhG5x8EfUnN0kEEuPKzoo&key=" + API_KEY;
  
  //== Create a Request object with the request URL
  const request = new Request(requestURL);

  //== Send an HTTP GET request to fetch the video data
  const response = await fetch(request);
  
  //== Parse the response as JSON
  const videos = await response.json();

  //== Call the populateHeader function with the video data
  populateHeader(videos);
}

//== Function to populate the HTML elements with video information
function populateHeader(obj) {
  //== Get HTML elements by their IDs
  const title = hypeDocument.getElementById('yTitle');
  const iframe_ = hypeDocument.getElementById("yIframe");
  const description = hypeDocument.getElementById('yDescription');

  //== Construct the YouTube video embed URL
  const videoSrc = "https://www.youtube.com/embed/" + obj.items[0].snippet.resourceId.videoId;

  //== Extract a portion of the video description
  var vidDescription = obj.items[0].snippet.description;
  var sourceDescription = vidDescription.split(' ', 20).join(' ');
  var sourceDescriptionMore = vidDescription.split(sourceDescription).join(' ');

  //== Set the title and description HTML
  title.innerHTML = obj.items[0].snippet.title;
  description.innerHTML = `
    <details class="details_">
      <summary class="summ">Read more...</summary>
      <p class="def">${sourceDescriptionMore}</p>
    </details>
  `;

  //== Add data-description attribute to the summary element
  document.querySelector('.summ').dataset.description = sourceDescription + "  ";

  //== Set the iframe HTML to embed the YouTube video
  iframe_.innerHTML = `
    <iframe width="560" height="315" src="${videoSrc}" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" allowfullscreen></iframe>
  `;

  //== Add a toggle event listener to the details element
  var details__ = document.querySelector('.details_');
  details__.addEventListener("toggle", (event) => {
    var summ_ = details__.querySelector('.summ');
    if (details__.open) {
      summ_.innerText = 'Read less...';
    } else {
      summ_.innerText = 'Read more...';
    }
  });
}

//== Call the populate function to fetch and display video data
populate();

And some additional css. is placed in the HEAD.

	<style>

 details summary::before {
  content: attr(data-description);
  font-weight: bold;
   padding: 1rem 2em 1rem 0;
}
 .def{
  
 	color:#945200!important;
   padding: 1rem 2em 1rem 0;
}

</style>

--

The result

--

youtubeapi.hype.zip (19.1 KB)

2 Likes