Skip to content

Commit

Permalink
made a page for folks to find out what the best poster image availabl…
Browse files Browse the repository at this point in the history
…e is
  • Loading branch information
paulirish committed Mar 3, 2024
1 parent 3b456bc commit 3e08b67
Show file tree
Hide file tree
Showing 3 changed files with 160 additions and 1 deletion.
4 changes: 4 additions & 0 deletions .editorconfig
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,10 @@ charset = utf-8
end_of_line = lf
trim_trailing_whitespace = true

# prettier custom things
quote_type = single
max_line_length = 160

[src/]
indent_size = 4
indent_style = space
Expand Down
155 changes: 155 additions & 0 deletions testpage/poster-image-availability.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,155 @@
<!doctype html>
<title>poster image availability</title>
<style>
body {
max-width: 1000px;
margin: 0 auto;
}
form {
margin: 25px;
}
input {
font-size: 30px;
}

input[type='text'] {
width: 30ex;
}
img,
picture {
max-height: 120px;
max-width: 120px;
}

thead {
position: sticky;
top: 0;
background: #ffffffd4;
}

td {
background: #eee;
}
#results.done {
background: aliceblue;
padding: 20px;
border-radius: 20px;
margin: 20px 0;
}
</style>
<form>
<input type="text" name="videoid" id="videoidorurl" placeholder="Youtube video ID or URL" />
<input type="submit" value="OK" />
</form>

<div id="results"></div>
<script>
// bling dot js
window.$ = document.querySelector.bind(document);
window.$$ = document.querySelectorAll.bind(document);
Node.prototype.on = window.on = function (name, fn) {
this.addEventListener(name, fn);
};

$('form').on('submit', (e) => {
const value = $('input').value;
const videoid = value.length < 20 ? value : new URL(value).searchParams.get('v');
$('input').value = videoid;
});

const sizes = [
'maxresdefault', // 1280px
'sddefault', // 640px
'hqdefault', // 480px (lol, naming is hard)
'mqdefault', // 320px
'default', // 120px
];
const sizePxs = ['1280px', '640px', '480px', '320px', '120px'];

const createChild = (tagName, container) => container.appendChild(document.createElement(tagName));

const videoid = new URL(location.href).searchParams.get('videoid');
document.addEventListener('DOMContentLoaded', (_) => {
if (!videoid) return;

$('#results').innerHTML = '<h2>Loading…</h2>';

const table = createChild('table', document.body);
const thead = createChild('thead', table);
const tbody = createChild('tbody', table);

// headers
const tr = createChild('tr', thead);
createChild('th', tr).textContent = 'video id';
createChild('th', tr).textContent = '';
for (const size of sizes) {
createChild('th', tr).textContent = size;
}
const tr2 = createChild('tr', thead);
createChild('th', tr2);
createChild('th', tr2);
for (const px of sizePxs) {
createChild('th', tr2).textContent = px;
}

// rows
[videoid].forEach((videoid) => {
const tr = createChild('tr', tbody);
createChild('td', tr).textContent = videoid;

const bestEl = createChild('td', tr);
// im very lazy
bestEl.innerHTML = `
webp &rarr;
<br><br><br><br>
jpg &rarr;
`;
const updateBest = (sizeIndex, format, e) => {
// A pretty ugly hack since onerror won't fire on YouTube image 404. This might be due to the fact that
// YouTube returns data to the request even when the status is 404. YouTube returns a placeholder image that is 120x90.
// … per ../youtube-thumbnail-urls.md (annoying yt 404 behavior)
const noAvailableThumbnail = e.target.naturalHeight == 90 && e.target.naturalWidth == 120;
if (noAvailableThumbnail) return;

bestEl.loaded = bestEl.loaded ?? [];
const formatIndex = { webp: 100, jpg: 110 }[format];
const sum = formatIndex + sizeIndex;
bestEl.loaded.push({ sum, format, sizeIndex });
bestEl.loaded.sort((a, b) => a.sum - b.sum);
const bestObj = bestEl.loaded.at(0);
bestEl.bestObj = bestObj;
};

// all combos. verbose
sizes.forEach((size, i) => {
const td = createChild('td', tr);
const imgWebp = createChild('img', td);
imgWebp.src = `https://i.ytimg.com/vi_webp/${videoid}/${size}.webp`;
imgWebp.onload = (e) => updateBest(i, 'webp', e);
createChild('br', td);
const imgJpg = createChild('img', td);
imgJpg.src = `https://i.ytimg.com/vi/${videoid}/${size}.jpg`;
imgJpg.onload = (e) => updateBest(i, 'jpg', e);
});
});
});

// Log our winner. Relying on all-images-loaded semantics. Handy.
onload = (_) => {
if (!videoid) return;

const bestEl = document.querySelector('tbody td:nth-child(2)');
const bestObj = bestEl.bestObj;
const size = sizes[bestObj.sizeIndex];
const imgHref = bestObj.format === 'webp' ? `https://i.ytimg.com/vi_webp/${videoid}/${size}.webp` : `https://i.ytimg.com/vi/${videoid}/${size}.jpg`;
results.innerHTML = `
<h2>The highest quality poster image available is:
<code>
${sizes[bestObj.sizeIndex]}.${bestObj.format} (${sizePxs[bestObj.sizeIndex]})
</code>
</h2>
<h3>That URL is: <a href="${imgHref}"><code>${imgHref}</code></a></h3>
`;
results.classList.add('done');
};
</script>
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<!DOCTYPE html>
<title>poster image availability</title>
<title>poster image summary</title>

<style>
img,
Expand Down

0 comments on commit 3e08b67

Please sign in to comment.