Published
Edited
Feb 1, 2021
Importers
4 stars
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
extracter.fetchFrame(t)
Insert cell
Insert cell
d = fetch(src, { mode: 'no-cors', credentials: 'omit' }).then(r => r.status)
Insert cell
Insert cell
extracter._cache
Insert cell
Insert cell
{
const interval = 1;
const numFrames = Math.min(
Math.floor(extracter._video.duration / interval) + 1,
20
);

const iw = extracter._video.videoWidth;
const ih = extracter._video.videoHeight;
const ow = iw / 4;
const oh = (ow * ih) / iw;
const cols = Math.floor(width / ow);
const rows = Math.ceil(numFrames / cols);
const canvas = DOM.canvas(ow * cols, oh * rows);
const context = canvas.getContext('2d');

const fetchAndDraw = async i => {
const t = i * interval;
const frame = await extracter.fetchFrame(t);
const x = (i % cols) * ow;
const y = Math.floor(i / cols) * oh;
context.drawImage(frame, 0, 0, iw, ih, x, y, ow, oh);
context.fillText(`t=${t}`, x + 10, y + 20);
};

const times = new Array(numFrames).fill(0).map((_, i) => i);
await Promise.all(times.map(fetchAndDraw));

return canvas;
}
Insert cell
Insert cell
existingVideo = html`<video src="${await FileAttachment(
"Glacier Express - 45569.mp4"
).url()}" controls width=${width}/>`
Insert cell
extracterFromVideo = await fetchExtracterFromVideo(existingVideo)
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
// CODE EXAMPLE that might be adapted to warm the cache
//
// async function warmCache(invalidation, debug = false) {
// // Warming the cache, for 3s
// const infoNode = html`<span></span>`;
// if (debug) {
// component.querySelector('output').parentNode.appendChild(infoNode);
// invalidation.then(() => infoNode.remove());
// }
// const cacheDuration = 3;
// for await (const frameIdx of d3.range(
// 0,
// cacheDuration * metadata.framerate
// )) {
// if (debug) {
// infoNode.innerHTML = ` [buffered: ${(
// frameIdx / metadata.framerate
// ).toFixed(2)}s]`;
// }
// const cancel = invalidation.then(d => false);
// // Note that it does nothing: the video frame is added to the cache, and we don't do anything with it
// const ok = background.imageAt(frameIdx).then(d => true);
// const follow = Promise.race([cancel, ok]);
// if ((await follow) === false) {
// break;
// } else {
// // Try to keep unnoticed, by not using all the CPU
// await Promises.delay(15);
// }
// }
// if (debug) {
// infoNode.remove();
// }
// }
Insert cell

Purpose-built for displays of data

Observable is your go-to platform for exploring data and creating expressive data visualizations. Use reactive JavaScript notebooks for prototyping and a collaborative canvas for visual data exploration and dashboard creation.
Learn more