Просто создайте компонент видеозаписи, который вы сможете потом воспроизвести, чтобы посмотреть, нравится ли вам это, если нет, вы просто перезапишете его, и, наконец, он сохранит его в базе данных. Я использую для этого реактивную веб-камеру с некоторыми функциями, которые я нашел в Интернете.
У меня есть функция handleDownload
, которая устанавливает источник тега видео с помощью только что записанного большого двоичного объекта. Первоначально он загружал видеофайл при нажатии кнопки, но я хочу, чтобы видео воспроизводилось, как только я останавливаю запись. В идеале я хочу использовать тот же компонент реактивной веб-камеры, но не уверен, что смогу это сделать, так что пока это подойдет.
Это работает, когда я устанавливаю функцию прослушивателя onClick для кнопки, однако это не работает, когда я вызываю функцию внутри handleStopCaptureClick
, поэтому я попытался реализовать useEffect
, который вызывает запуск handleDownload
после прекращения захвата. Это тоже не работает – мысли? Спасибо!
import React, {useEffect} from "react";
import Webcam from "react-webcam";
export const WebcamStreamCapture = () => {
const webcamRef = React.useRef(null);
const mediaRecorderRef = React.useRef(null);
const [capturing, setCapturing] = React.useState(false);
const [recordedChunks, setRecordedChunks] = React.useState([]);
const isInitialMount = React.useRef(true);
useEffect(() => {
if (isInitialMount.current) {
isInitialMount.current = false;
} else {
if (!capturing) {
console.log('running handleDownload')
handleDownload();
}
}
}, [capturing])
const handleStartCaptureClick = React.useCallback(() => {
setCapturing(true);
mediaRecorderRef.current = new MediaRecorder(webcamRef.current.stream, {
mimeType: "video/webm"
});
mediaRecorderRef.current.addEventListener(
"dataavailable",
handleDataAvailable
);
mediaRecorderRef.current.start();
}, [webcamRef, setCapturing, mediaRecorderRef]);
const handleDataAvailable = React.useCallback(
({ data }) => {
if (data.size > 0) {
setRecordedChunks((prev) => prev.concat(data));
}
},
[setRecordedChunks]
);
const handleStopCaptureClick = React.useCallback(() => {
mediaRecorderRef.current.stop();
setCapturing(false);
}, [mediaRecorderRef, webcamRef, setCapturing]);
const handleDownload = React.useCallback(() => {
if (recordedChunks.length) {
const blob = new Blob(recordedChunks, {
type: "video/webm"
});
const url = URL.createObjectURL(blob);
const video = document.getElementById("video-replay");
video.src = url
}
}, [recordedChunks]);
return (
<div className="d-flex flex-column align-items-center">
<Webcam audio={false} ref={webcamRef} height={400} width={500}/>
<video id="video-replay" height="400" width="500" controls></video>
{capturing ? (
<button className="btn btn-danger" onClick={handleStopCaptureClick}>Stop Capture</button>
) : (
<button className="btn btn-danger" onClick={handleStartCaptureClick}>Start Capture</button>
)}
{recordedChunks.length > 0 && (
<div>
<button onClick={handleDownload}>Download</button>
</div>
)}
</div>
);
};
Возможное решение Итак, я поймал себя на мысли, что если чанки не появляются/не работают и во время useEffect, это должно означать, что при захвате остановок в handleStopCaptureClick
он принимает состояние a пока обновлять, включая куски, я полагаю. Изменив зависимость с «capturing» на «recordedChunks» в useEffect, мне удалось заставить видео появляться сразу после остановки записи.