Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update non-challenge video thumbnails + automation script #1646

Closed
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Binary file added content/videos/code/0-trailer/trailer/index.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added content/videos/code/1-intro/1-intro/index.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added content/videos/code/1-intro/4-color/index.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added content/videos/code/1-intro/5-errors/index.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added content/videos/code/1-intro/6-comments/index.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added content/videos/code/2-variables/5-map/index.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added content/videos/code/4-loops/2-nested/index.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added content/videos/code/6-objects/1-intro/index.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added content/videos/code/7-arrays/1-arrays/index.jpg
Binary file added content/videos/data/welcome/setup/index.jpg
Binary file added content/videos/data/welcome/trailer/index.jpg
Binary file added content/videos/discord/2023-workflow/index.jpg
Binary file added content/videos/discord/coding-a-bot/index.jpg
Binary file added content/videos/js/array-filter/index.jpg
Binary file added content/videos/js/array-map-and-fill/index.jpg
Binary file added content/videos/js/array-reduce/index.jpg
Binary file added content/videos/js/array-sort/index.jpg
Binary file added content/videos/js/arrow-functions/index.jpg
Binary file added content/videos/js/async-await-part-1/index.jpg
Binary file added content/videos/js/async-await-part-2/index.jpg
Binary file added content/videos/js/const/index.jpg
Binary file added content/videos/js/for-of-loop/index.jpg
Binary file added content/videos/js/inheritance/index.jpg
Binary file added content/videos/js/let-vs-var/index.jpg
Binary file added content/videos/js/polymorphism/index.jpg
Binary file added content/videos/js/promise-all/index.jpg
Binary file added content/videos/js/promises-part-1/index.jpg
Binary file added content/videos/js/promises-part-2/index.jpg
Binary file added content/videos/js/try-catch/index.jpg
Binary file added content/videos/livestreams/genuary/index.jpg
Binary file added content/videos/livestreams/shiffbot/index.jpg
Binary file added content/videos/mastodon/streaming-api/index.jpg
Binary file added content/videos/mastodon/what-is-node-js/index.jpg
Binary file added content/videos/mastodon/what-is-npm/index.jpg
Binary file added content/videos/more-p5/2d-arrays/index.jpg
Binary file added content/videos/more-p5/custom-shapes/index.jpg
Binary file added content/videos/more-p5/local-storage/index.jpg
Binary file added content/videos/more-p5/pixel-array/index.jpg
Diff not rendered.
Diff not rendered.
Diff not rendered.
Diff not rendered.
Diff not rendered.
Diff not rendered.
Diff not rendered.
Diff not rendered.
Diff not rendered.
Binary file removed content/videos/noc/perlin/noise-vs-random/index.png
Diff not rendered.
Binary file removed content/videos/noc/perlin/perlin-noise-2d/index.png
Diff not rendered.
Diff not rendered.
Diff not rendered.
Diff not rendered.
Binary file added content/videos/noise/open-simplex-noise/index.jpg
Binary file added content/videos/pixels/checkbox-mirror/index.jpg
Binary file added content/videos/pixels/createCapture/index.jpg
Binary file added content/videos/pixels/slit-scan/index.jpg
Binary file added content/videos/pixels/video-photobooth/index.jpg
Binary file added content/videos/processing/index.jpg
Binary file added content/videos/sound/6-sound-synthesis/index.jpg
Binary file added content/videos/sound/7-adsr-envelope/index.jpg
Binary file added content/videos/transformations/scale/index.jpg
Binary file added content/videos/webgl/1-introduction/index.jpg
Binary file added content/videos/webgl/2-3d-geometries/index.jpg
Binary file added content/videos/webgl/4-texture/index.jpg
Binary file added content/videos/webgl/6-createGraphics/index.jpg
Binary file added content/videos/workflow/1-intro/index.jpg
Binary file added content/videos/workflow/3-shell/index.jpg
Binary file added content/videos/workflow/4-git/index.jpg
Binary file added content/videos/workflow/5-node/index.jpg
76 changes: 76 additions & 0 deletions node-scripts/download-non-challenge-thumbnails.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
import { paths } from '../content-testing/content.js';
import path from 'node:path';
import fs from 'node:fs';

// Thumbnails for non-challenge videos can just use the YouTube thumbnail.
// They are never displayed on the site directly, only when sharing links on social media.

function sleep(ms) {
return new Promise((resolve) => setTimeout(resolve, ms));
}

async function getImage(url) {
const response = await fetch(url);

if (!response.ok) return;

const arrayBuffer = await response.arrayBuffer();
return Buffer.from(arrayBuffer);
}

console.log(`Downloading ${paths.videos.length} thumbnails`);

for (const jsonPath of paths.videos) {
const baseDir = path.join(path.dirname(jsonPath));

// remove existing thumnails (co-located with index.json files if they exist)
['index.jpg', 'index.png'].forEach((filename) => {
fs.rmSync(path.join(baseDir, filename), { force: true });
});

const video = JSON.parse(fs.readFileSync(jsonPath));
const isMultiPart = !!video.parts;
let videoId = isMultiPart ? video.parts[0].videoId : video.videoId;

// download thumbnail from YouTube CDN
const thumbnailResolutions = [
'maxresdefault', // 1280x720 - may not be available for 720p videos
'sddefault', // 640x480
'hqdefault', // 480x360
'mqdefault', // 320x180
'default' // 120x90
];

let buffer;
let resolution;
for (const thumbnailResolution of thumbnailResolutions) {
resolution = thumbnailResolution;

// const thumbnailPath = `https://img.youtube.com/vi_webp/${videoId}/${resolution}.webp`;
const thumbnailPath = `https://img.youtube.com/vi/${videoId}/${resolution}.jpg`;
buffer = await getImage(thumbnailPath);
if (buffer) break;

console.warn(
videoId,
`🟠`,
resolution,
`| missing, trying lower resolution...`
);
}

if (!buffer) {
console.error(
`🔴 Failed to locate a thumbnail for ${videoId} - process aborted.`
);
process.exit(1);
}

console.log(videoId, '🟢', resolution, '\n');

// write file to disk
fs.writeFileSync(path.join(baseDir, 'index.jpg'), buffer);

// sleep for a bit to avoid spamming / getting blocked
await sleep(100 + Math.random() * 300);
}
Loading