目标是在 html 视频元素中预览计算机网络摄像头的流,同时记录音频和显示另一个视频的 Chrome 选项卡,并使用 MediaRecorder API、navigator.mediaDevices.getDisplayMedia 和 navigator.mediaDevice.getUserMedia 进行预览.
该实现使用 Chrome 和 Ubuntu/Windows 设置运行良好,但在 macOS 上运行时变得滞后。下面提供了 Javascript 代码。关于为什么实施在 macOS 上特别糟糕的任何想法?
我尝试将编解码器从 vp9 更改为 vp8,将帧速率降低到 24,并且分辨率已经降低。如果我降低质量会变差。
我尝试在 macOS 上降低流和录制的质量而没有任何性能提升。
export default function VideoRecord(props) {
const [isLoading, setIsLoading] = useState(true);
useEffect(() => {
async function onLoad() {
try {
//some code
} catch (e) {
alert(e);
}
setIsLoading(false);
}
onLoad();
}, [props.match.params.id]);
var mediaRecorder;
var recordedChunks = [];
var videoStream;
var cameraStream;
var combinedStream;
var BLOB;
var cameraElem;
var videoElem;
$(function() {
cameraElem = document.querySelector('#camera');
videoElem = document.querySelector('#video');
})
var videoMediaOptions = {
video: {
width: 720,
height: 480,
aspectRatio: 1920/1080,
cursor: "never",
frameRate: 30
},
audio: false
};
var cameraMediaOptions = {
video: {
width: 300,
height: 300
},
audio: true
}
async function startCapture() {
try {
videoStream = await navigator.mediaDevices.getDisplayMedia(videoMediaOptions);
cameraStream = await navigator.mediaDevices.getUserMedia(cameraMediaOptions);
cameraElem.srcObject = cameraStream;
startRec();
} catch(err) {
console.error("Error: " + err);
}
}
function handleDataAvailable(event) {
if (event.data.size > 0) {
recordedChunks.push(event.data);
createBlob();
}
}
function startRec () {
var options = { mimeType: "video/webm; codecs=vp9" };
combinedStream = new MediaStream([...cameraStream.getAudioTracks(), ...videoStream.getTracks()]);
mediaRecorder = new MediaRecorder(combinedStream, options);
mediaRecorder.ondataavailable = handleDataAvailable;
mediaRecorder.start();
}
function createBlob() {
BLOB = new Blob(recordedChunks, {
type: "video/webm"
});
var url = URL.createObjectURL(BLOB);
videoElem.srcObject = null;
videoElem.src = url;
videoElem.muted = false;
}
function stopCapture() {
let cameraTracks = cameraStream.getTracks();
cameraTracks.forEach(cameraTracks => cameraTracks.stop());
let tracks = videoStream.getTracks();
tracks.forEach(track => track.stop());
mediaRecorder.stop();
}
function renderPage(){
return (
<div className="videoWrapper">
<video preload="auto" id="video"></video>
<video id="camera" autoPlay muted></video>
<Button id="startBtn" onClick={startCapture}>Start</Button>
<Button id="stopBtn" onClick={stopCapture}>Stop</Button>
</div>
)
}
return (
<div id="videoRecordID" className="VideoRecord">
{!isLoading && <div>Loading...</div>}
{!isLoading && renderPage()}
</div>
);
}