跳到主要内容

getDisplayMedia

2024年02月04日
柏拉文
越努力,越幸运

一、认识


mediaDevices.getDisplayMedia() 方法提示用户去选择和授权捕获展示的内容或部分内容(如一个窗口)在一个MediaStream 里。

二、语法


const promise = navigator.mediaDevices.getDisplayMedia(constraints);
  • constraints: 一个可选的 MediaStreamConstraints (en-US) 对象,它指定了返回的 MediaStream 的要求。因为 getDisplayMedia() 需要视频轨道,所以即使 constraints 对象没有明确请求视频轨道,返回的流也会有一个。

  • promise: 一个被解析为 MediaStreamPromise,其中包含一个视频轨道。视频轨道的内容来自用户选择的屏幕区域以及一个可选的音频轨道。

三、错误


3.1 AbortError

AbortError 中止错误 发生了与以下任何其他异常不匹配的错误或故障。

3.2 InvalidStateError

InvalidStateError 拒绝错误 调用 getDisplayMedia()context 中的 document 不是完全激活的; 例如,也许它不是最前面的标签。

3.3 NotAllowedError

NotAllowedError 拒绝错误 用户拒绝授予访问屏幕区域的权限,或者不允许当前浏览实例访问屏幕共享。

3.4 NotFoundError

NotFoundError 找不到错误 没有可用于捕获的屏幕视频源。

3.5 NotReadableError

NotReadableError 无法读取错误 用户选择了屏幕,窗口,标签或其他屏幕数据源,但发生了硬件或操作系统级别错误或锁定,从而预先占用了共享所选源。

3.6 OverconstrainedError

OverconstrainedError 转换错误 创建流后,由于无法生成兼容的流导致应用指定的 constraints 失效。

3.7 TypeError

TypeError 类型错误 指定的 constraints 包括调用 getDisplayMedia() 时不允许的 constraints。这些不受支持的 constraintsadvanced 的,任何约束又有一个名为 minexact 的成员。

四、场景


4.1 获取流

const stream = navigator.mediaDevices.getDisplayMedia();

4.2 添加流

const stream = navigator.mediaDevices.getDisplayMedia({
video: true
});

const audioStream = navigator.mediaDevices.getUserMedia({
audio: true
});

audioStream.getAudioTracks().forEach((audioTrack) => stream.addTrack(audioTrack))

4.3 屏幕录制

描述: 仅仅将获取的视频流和音频流, 链接到 video 元素

<div class="operation">
<button id="start-capture">录制</button>
<button id="stop-capture">停止</button>
</div>
<div class="video-container">
<video autoplay></video>
</div>

<script>
const video = document.querySelector('video');
const stopButton = document.getElementById('stop-capture');
const startButton = document.getElementById('start-capture');

const startCapture = async displayMediaOptions => {
let captureStream = null;
displayMediaOptions = displayMediaOptions || {
video: {
displaySurface: 'window'
},
audio: {
echoCancellation: true,
noiseSuppression: true,
sampleRate: 44100,
suppressLocalAudioPlayback: true
},
surfaceSwitching: 'include',
selfBrowserSurface: 'exclude',
systemAudio: 'exclude'
};

try {
captureStream = await navigator.mediaDevices.getDisplayMedia(
displayMediaOptions
);
video.srcObject = captureStream;
} catch (error) {
console.log('startCapture Error: ', error);
}

return captureStream;
};

const stopCapture = async () => {
let tracks = video.srcObject.getTracks();
tracks.forEach(track => track.stop());
video.srcObject = null;
};

startButton.addEventListener('click', startCapture);
stopButton.addEventListener('click', stopCapture);
</script>

描述: 将获取的视频流和音频流, 链接到 video 元素, 并且通过MediaRecorder获取视频流和音频流

<div class="operation">
<button id="start-capture">录制</button>
<button id="stop-capture">停止</button>
</div>
<div class="video-container">
<video autoplay></video>
</div>

<script>
let mediaRecorder = null;
const recordedBlobs = [];
const video = document.querySelector('video');
const stopButton = document.getElementById('stop-capture');
const startButton = document.getElementById('start-capture');

const startCapture = async () => {
const timeSlice = 5000;
mediaRecorder.start(timeSlice);
};

const stopCapture = async () => {
const stream = video.srcObject;
const tracks = stream.getTracks();

tracks.forEach(track => {
track.stop();
});

video.srcObject = null;
mediaRecorder.stop();
};

const prepareCapture = async () => {
const displayMediaOptions = {
video: {
displaySurface: 'window'
},
audio: {
echoCancellation: true,
noiseSuppression: true,
sampleRate: 44100,
suppressLocalAudioPlayback: true
},
surfaceSwitching: 'include',
selfBrowserSurface: 'exclude',
systemAudio: 'exclude'
};

try {
const stream = await navigator.mediaDevices.getDisplayMedia(
displayMediaOptions
);
video.srcObject = stream;
video.play();

mediaRecorder = new MediaRecorder(stream, {
mimeType: 'video/webm'
});

mediaRecorder.ondataavailable = event => {
if (event.data && event.data.size > 0) {
recordedBlobs.push(event.data);
console.log("recordedBlobs",recordedBlobs)
}
};
} catch (error) {
console.log('startCapture Error: ', error);
}
};

prepareCapture();
startButton.addEventListener('click', startCapture);
stopButton.addEventListener('click', stopCapture);
</script>