对于朋友的硕士论文,我已经开始创建一个小型录像机应用程序,以便她的参与者可以录制自己(也是因为我想使用这个 API :))。
我正处于这个支线任务的早期阶段。我已经搭建了 next.js 应用程序,到目前为止已经能够从网络摄像头录制媒体流并在录制运行时将其回放给用户。完成此操作后,我想继续存储视频等。 现在我的问题是:用户完成录音后,我想给他们机会查看录音。但是,如果用户点击“播放”按钮,视频播放器将保持黑色并且不会像我预期的那样显示视频。
这是点击“播放”按钮后视频播放器的样子:
我怀疑视频播放器无法处理 blob-url。我必须附加扩展名吗?如果是这样,我该如何在这里实现这一点?
一些帮助将不胜感激!
亲切的问候, 最大
'use client'
import React, { useState, useRef } from 'react'
import RecorderControls from './RecorderControls/RecorderControls'
const Recorder = () => {
const videoRef = useRef(null);
const mediaRecorderRef = useRef(null);
const constraints = { audio: true, video: true }
const [videoBlob, setVideoBlob] = useState(null);
const [isRecording, setIsRecording] = useState (false);
const startRecord = async () => {
// Check if the browser supports the getUserMedia API
const userMediaDevices = navigator.mediaDevices;
if (!userMediaDevices) {
console.log("getUserMedia is not supported!");
return
}
// Get the video stream from the webcam, display it in the video element, and start playing it back to the user
const stream = await navigator.mediaDevices.getUserMedia(constraints);
videoRef.current.srcObject = stream;
videoRef.current.play();
mediaRecorderRef.current = new MediaRecorder(stream, {
mimeType: 'video/mp4',
});
// When the recording starts, create an array to store the video chunks while recording
const chunks = [];
mediaRecorderRef.current.ondataavailable = (e) => {
if (e.data.size > 0) {
chunks.push(e.data);
}
};
// When the recording stops, create a video blob and set it in the state
mediaRecorderRef.current.onstop = () => {
const blob = new Blob(chunks, { type: 'video/mp4' });
setVideoBlob(blob);
}
// Start recording
mediaRecorderRef.current.start();
setIsRecording(true);
console.log("Recording started");
};
const stopRecord = () => {
mediaRecorderRef.current.stop();
videoRef.current.srcObject.getTracks().forEach((track) => track.stop());
setIsRecording(false);
console.log("Recording stopped")
};
const playVideo = () => {
console.log(videoBlob);
if (videoBlob) {
const videoURL = URL.createObjectURL(videoBlob);
videoRef.current.src = videoURL;
videoRef.current.load();
videoRef.current.play();
}
};
return (
<>
<div className='mb-6 font-semibold text-xl'>Recorder Apparat</div>
<div className="bg-gray-700 w-96 h-96 rounded-lg">
<video ref={videoRef} width="640" height="480" />
</div>
<div className="mt-5"></div>
<div className='flex gap-3'>
<button onClick={startRecord} className='btn btn-primary btn-outline'>
record
</button>
<button onClick={stopRecord} className='btn btn-primary btn-outline'>
stop
</button>
<button onClick={playVideo} className='btn btn-primary btn-outline'>
playback
</button>
</div>
<RecorderControls />
</>
)
}
export default Recorder
显然,当你停止录制时,你必须将 srcObject 清空,以防止干扰常规 src
我已将以下行添加到 stopRecord 方法中:
const stopRecord = () => {
mediaRecorderRef.current.stop();
videoRef.current.srcObject.getTracks().forEach((track) => track.stop());
videoRef.current.srcObject = null; // <<<<<<<<<<<<
setIsRecording(false);
console.log("Recording stopped")
};