How can I push new value to array of object by dynamic key in useState?

Viewed 55

I have a website for recording the video 15 seconds. And I want to capture canvas to blob every 40 millisecond. (25FPS) So, then I should to get 375 blobs.

// requestAnimationFrame
const loop = async () => {
  sequenceRef.current = setTimeout(() => {
    setSequence((prev) => [
       ...prev,
       new Promise((resolve) => webcam.toBlob(resolve, "image/webp")),
    ]);
    animationFrame.current = requestAnimationFrame(loop);
  }, 40);
};
loop();

// with setInterval
sequenceRef.current = setInterval(() => {
  setSequence((prev) => [
    ...prev,
    new Promise((resolve) => webcam.toBlob(resolve, "image/webp")),
  ]);
}, 1000 / FPS);

BUT I try to use requestAnimationFrame or setInterval for 40 millisecond and sometimes it normally and sometimes it can capture less than 375. These two solutions is not solve my problem. (I think it cause by device performance.)

So that, I try to other ways. I decide to create like a time-mapping in object. and each object key has string value in array

Every second push the new blob into array some second has loss some blob but it fine.

I want to use useState to collect data in this format like this

timeSequence = {
  "1": ["blob-1s-1", "blob-1s-2", "blob-1s-3"],
  "2": ["blob-2s-1", "blob-2s-2"],
  "2": ["blob-3s-1", "blob-3s-2", "blob-3s-3"],
  ...
}

I use useState for push a new value to array of object but it not work :( each key has just one value. I do not know why.

here is my code (do not care about push promise in array)

const [sequenceObj, setSequenceObj] = useState<any>({
  "0": [],
  "1": [],
  "2": [],
  "3": [],
  "4": [],
  "5": [],
  "6": [],
  "7": [],
  "8": [],
  "9": [],
  "10": [],
  "11": [],
  "12": [],
  "13": [],
  "14": [],
  "15": [],
});

useEffect(() => {
  const loop = async () => {
    setTimeout(() => {
      setSequenceObj((prev: any) => ({
        ...prev,
        [`${currentTime}`]: [
          ...sequenceObj[`${currentTime}`],
          new Promise((resolve) => webcam.toBlob(resolve, "image/webp")),
        ];,
      }));
      animationFrame.current = requestAnimationFrame(loop);
    }, 1000 / FPS);
  };

  loop();
}, [currentTime])
0 Answers
Related