Skip to content

Commit

Permalink
Upgrade poster image to webp if possible.
Browse files Browse the repository at this point in the history
ref  #70
  • Loading branch information
paulirish committed Mar 3, 2024
1 parent 376fc42 commit 3b456bc
Show file tree
Hide file tree
Showing 3 changed files with 43 additions and 15 deletions.
35 changes: 30 additions & 5 deletions src/lite-yt-embed.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,16 +19,13 @@ class LiteYTEmbed extends HTMLElement {
this.playLabel = (playBtnEl && playBtnEl.textContent.trim()) || this.getAttribute('playlabel') || 'Play';

/**
* Lo, the youtube placeholder image! (aka the thumbnail, poster image, etc)
* Lo, the youtube poster image! (aka the thumbnail, image placeholder, etc)
*
* See https://github.com/paulirish/lite-youtube-embed/blob/master/youtube-thumbnail-urls.md
*
* TODO: Do the sddefault->hqdefault fallback
* - When doing this, apply referrerpolicy (https://github.com/ampproject/amphtml/pull/3940)
* TODO: Consider using webp if supported, falling back to jpg
*/
if (!this.style.backgroundImage) {
this.style.backgroundImage = `url("https://i.ytimg.com/vi/${this.videoId}/hqdefault.jpg")`;
this.upgradePosterImage();
}

// Set up play button, and its visually hidden label
Expand Down Expand Up @@ -172,6 +169,34 @@ class LiteYTEmbed extends HTMLElement {
// Set focus for a11y
iframeEl.focus();
}

/**
* In the spirit of the `lowsrc` attribute and progressive JPEGs, we'll upgrade the reliable
* poster image to a higher resolution one, if it's available.
* Interestingly this sddefault webp is often smaller in filesize, but we will still attempt it second
* because getting _an_ image in front of the user if our first priority.
*
* See https://github.com/paulirish/lite-youtube-embed/blob/master/youtube-thumbnail-urls.md for more details
*/
upgradePosterImage() {
// Defer to reduce network contention.
setTimeout(() => {
const webpUrl = `https://i.ytimg.com/vi_webp/${this.videoId}/sddefault.webp`;
const img = new Image();
img.fetchPriority = 'low'; // low priority to reduce network contention
img.referrerpolicy = 'origin'; // Not 100% sure it's needed, but https://github.com/ampproject/amphtml/pull/3940
img.src = webpUrl;
img.onload = e => {
// A pretty ugly hack since onerror won't fire on YouTube image 404. This is (probably) due to
// Youtube's style of returning data even with a 404 status. That data is a 120x90 placeholder image.
// … per "annoying yt 404 behavior" in the .md
const noAvailablePoster = e.target.naturalHeight == 90 && e.target.naturalWidth == 120;
if (noAvailablePoster) return;

this.style.backgroundImage = `url("${webpUrl}")`;
}
}, 100);
}
}
// Register custom element
customElements.define('lite-youtube', LiteYTEmbed);
21 changes: 11 additions & 10 deletions test/poster-image-availability.html
Original file line number Diff line number Diff line change
Expand Up @@ -108,14 +108,15 @@
* copy(Array.from(new Set(Array.from(document.querySelectorAll('a.ytd-thumbnail')).map(e => e.href).filter(Boolean).map(h => { const u = new URL(h); return u.searchParams.get('v'); }))))
*/
const ids = [
"3zaq56QsX28",
"ajGX7odA87k",
"-hKK4_gvOS0",
"5BueilOHIws",
"saaTXQ7E3Lw",
"bJcTWr8-mFo",
"jWur1VrxNUg",
"b52cfb6lweU",
"svEuG_ekNT0",
]
"ogfYd705cRs",
"3zaq56QsX28",
"ajGX7odA87k",
"-hKK4_gvOS0",
"5BueilOHIws",
"saaTXQ7E3Lw",
"bJcTWr8-mFo",
"jWur1VrxNUg",
"b52cfb6lweU",
"svEuG_ekNT0",
]
</script>
2 changes: 2 additions & 0 deletions youtube-thumbnail-urls.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,8 @@ When YouTube serves a response for a 404 thumbnail, they serve a true 404 respon

`sddefault`, `hqdefault`, `default` are 4:3.

This difference ends up being mostly unimportant, in practice. The YT iframe is a 16:9 size by default. Using `background-position: center` ensures the (possible) black bars in the 4:3 images are hidden.

## WebP

`https://i.ytimg.com/vi_webp/${videoid}/${width}.webp`
Expand Down

0 comments on commit 3b456bc

Please sign in to comment.