d9fc1b2Demonstrate lazy reading of remote HDF5/NWB files (direct h5wasm + LINDI)magland 1// This was a nice attempt but in the end
2// it took way too long to decode a chunk
4export const decodeMp4 = async (
5 chunk: ArrayBuffer,
6 numFrames: number,
7 width: number,
8 height: number,
9) => {
10 const blob = new Blob([chunk], { type: "video/mp4" });
11 const url = URL.createObjectURL(blob);
13 const numBatches = 10;
14 const framesPerBatch = Math.ceil(numFrames / numBatches);
15 const batches = [];
16 for (let i = 0; i < numBatches; i++) {
17 const start = i * framesPerBatch;
18 const end = Math.min(start + framesPerBatch, numFrames);
19 batches.push({
20 start,
21 end,
22 url,
23 width,
24 height,
25 });
26 }
28 // do batches in parallel
29 const promises = batches.map((batch) => doBatch(batch));
30 const results = await Promise.all(promises);
31 const frames = results.flat();
33 // Cleanup
34 URL.revokeObjectURL(url);
36 return frames;
37};
39const doBatch = async (batch: {
40 start: number;
41 end: number;
42 url: string;
43 width: number;
44 height: number;
45}) => {
46 const { start, end, url, width, height } = batch;
47 // Prepare video element
48 const video = document.createElement("video");
49 video.width = width;
50 video.height = height;
51 video.src = url;
52 video.muted = true;
53 const canvas = document.createElement("canvas");
54 canvas.width = width;
55 canvas.height = height;
56 const ctx = canvas.getContext("2d");
57 if (!ctx) throw Error("Unable to create canvas context");
59 video.onerror = (e) => {
60 console.log("Video error", e, video.error);
61 };
63 // Wait for video to load
64 await new Promise((resolve) => {
65 video.addEventListener("loadedmetadata", resolve, { once: true });
66 });
68 // Utility to seek video and extract frame
69 const extractFrame = (time: number) =>
70 new Promise((resolve) => {
71 video.currentTime = time;
72 video.addEventListener(
73 "seeked",
74 () => {
75 ctx.drawImage(video, 0, 0, canvas.width, canvas.height);
76 const imageData = ctx.getImageData(0, 0, canvas.width, canvas.height);
77 resolve(imageData.data);
78 },
79 { once: true },
80 );
81 });
83 // Step 4 & 5: Extract frames (simplified)
84 const frames = [];
85 for (let i = start; i < end; i++) {
86 const time = i; // fps = 1
87 // print every 10 frames
88 if (frames.length % 10 === 0) {
89 console.log("Frames", frames.length);
90 }
91 const frameData = await extractFrame(time);
92 frames.push(frameData); // This pushes 3D data; needs adjustment for 4D structure
93 }
95 console.log("Frames", frames);
97 return frames; // This is your 4D array
98};