gpt4 book ai didi

reactjs - 使用 React Hook 时,来自 MediaRecorder 的中间数据丢失

转载 作者:行者123 更新时间:2023-12-04 15:46:34 26 4
gpt4 key购买 nike

我正在开发一个更高阶的组件,它将提供使用 MediaRecorder API 捕获媒体的能力。但是,当我尝试使用捕获的视频(以传递给 createObjectURL 的 Blob 形式)时,出现错误 ERR_REQUEST_RANGE_NOT_SATISFIABLE。当我控制台记录传递给包装组件的 Blob 时,它的长度为 0。我在本文末尾包含了我的代码。

为了诊断问题,我尝试了以下测试:

  • handleDataAvailable 中的控制台记录 newChunks 记录正确的值(即 [Blob])。
  • 我添加了 React.useEffect(() => console.log(chunks), [chunks]); 以查看 block 是否真的得到更新。这也会导致记录正确的值(即 [Blob])。
  • 我添加了 React.useEffect(() => console.log(captured), [captured]); 以查看 captured 是否正在更新。这会导致记录大小为 0 的 Blob。
  • handleStop 中,我控制日志 block 和通过组合这些 block 创建的 blob。这会分别产生一个空数组和一个大小为 0 的 blob。

这让我相信 handleDataAvailable 正确地将每个 block 添加到 chunks 数组,但不知何故,在 handleStop 运行时该数组被清空了。

有没有人知道是什么导致了这种情况的发生?

代码:

import React from 'react';

import { getUserMedia, getConstraints } from '../../utils/general';

const withMediaCapture = (WrappedComponent, recordingType, facingMode, deviceID) => {
const constraints = getConstraints(recordingType, facingMode, deviceID);

const type = recordingType === 'audio'
? 'audio/ogg; codecs=opus'
: 'video/webm; codecs=vp9';

return props => {
const [mediaStream, setMediaStream] = React.useState(undefined);
const [mediaRecorder, setMediaRecorder] = React.useState(undefined);
const [isRecording, setIsRecording] = React.useState(false);
const [captured, setCaptured] = React.useState(undefined);
const [chunks, setChunks] = React.useState([]);

// On mount, get the mediaStream:
const setupStream = () => {
getUserMedia(constraints)
.then(setMediaStream)
.catch(error => {/* TODO: Handle error */});
};
React.useEffect(setupStream, []);

// Once we have gotten the mediaStream, get the mediaRecorder:
const handleDataAvailable = ({ data }) => {
const newChunks = [...chunks, data];
setChunks(newChunks);
};
const handleStop = foo => {
const blob = new Blob(chunks, { type });
setCaptured(blob);
setChunks([]);
}
const getMediaRecorder = () => {
mediaStream && setMediaRecorder(Object.assign(
new MediaRecorder(mediaStream),
{
ondataavailable: handleDataAvailable,
onstop: handleStop,
},
));
}
React.useEffect(getMediaRecorder, [mediaStream]);

const toggleRecording = () => {
isRecording
? mediaRecorder.stop()
: mediaRecorder.start();
setIsRecording(!isRecording);
};

return <WrappedComponent {...{ preview: mediaStream, captured, toggleRecording, isRecording, ...props }} />;
};
};

const VideoCaptureDemo = ({ preview, captured, toggleRecording, isRecording }) => {
const previewRef = React.useRef(null);
const capturedRef = React.useRef(null);

const setupPreview = () => {
previewRef.current.srcObject = preview;
};
React.useEffect(setupPreview, [preview]);

const setupCaptured = () => {
const url = captured && window.URL.createObjectURL(captured);
capturedRef.current.src = url;
};
React.useEffect(setupCaptured, [captured]);

return (
<div>
<video ref={previewRef} autoPlay={true} muted={true} />
<video ref={capturedRef} controls />
<button onClick={toggleRecording}>
{isRecording ? 'Stop Recording' : 'Start Recording'}
</button>
</div>
);
};

export default withMediaCapture(VideoCaptureDemo, 'videoAndAudio');

最佳答案

handleStophandleDataAvailable 都关闭了初始的空 chunks 数组。如果 handleDataAvailable 被多次调用,较早的 block 将丢失,并且 handleStop 将始终从空 block 数组创建一个 Blob。由 setChunks 引起的重新呈现将导致创建新版本的 handle 方法,但 MediaRecorder 仍将使用创建 MediaRecorder 时的版本。

您可以使用 functional updates 修复 handleDataAvailable ,但为了修复 handleStop 我认为你最好切换到使用 useReducer(reducer 管理 chunkscaptured)这样您就可以分派(dispatch)一个 Action ,然后 reducer 可以访问当前 block 并适本地创建 Blob。

关于reactjs - 使用 React Hook 时,来自 MediaRecorder 的中间数据丢失,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55499621/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com