转载:https://developer.mozilla.org/en-US/docs/Web/API/MediaDevices
enumerateDevices()
获取有关系统上可用的媒体输入和输出设备的一系列信息。
getSupportedConstraints()
返回符合MediaTrackSupportedConstraints指示MediaStreamTrack接口支持哪些可约束属性的对象。见能力和限制在媒体捕获和流API(流媒体),以了解更多关于限制和如何使用它们。
getDisplayMedia()
提示用户选择一个显示或显示的一部分(例如窗口)以作为MediaStream共享或记录目的进行捕获。返回一个解析为 a 的承诺MediaStream。
try {
let mediaStream = await navigator.mediaDevices.getDisplayMedia({video:true});
videoElement.srcObject = mediaStream;
} catch (e) {
console.log('Unable to acquire screen capture: ' + e);
}
getUserMedia()
在用户通过提示许可的情况下,打开系统上的摄像头和/或麦克风,并提供MediaStream包含视频轨道和/或音频轨道的输入。
'use strict';
// Put variables in global scope to make them available to the browser console.
var video = document.querySelector('video');
var constraints = window.constraints = {
audio: false,
video: true
};
var errorElement = document.querySelector('#errorMsg');
navigator.mediaDevices.getUserMedia(constraints)
.then(function(stream) {
var videoTracks = stream.getVideoTracks();
console.log('Got stream with constraints:', constraints);
console.log('Using video device: ' + videoTracks[0].label);
stream.onremovetrack = function() {
console.log('Stream ended');
};
window.stream = stream; // make variable available to browser console
video.srcObject = stream;
})
.catch(function(error) {
if (error.name === 'ConstraintNotSatisfiedError') {
errorMsg('The resolution ' + constraints.video.width.exact + 'x' +
constraints.video.height.exact + ' px is not supported by your device.');
} else if (error.name === 'PermissionDeniedError') {
errorMsg('Permissions have not been granted to use your camera and ' +
'microphone, you need to allow the page access to your devices in ' +
'order for the demo to work.');
}
errorMsg('getUserMedia error: ' + error.name, error);
});
function errorMsg(msg, error) {
errorElement.innerHTML += '<p>' + msg + '</p>';
if (typeof error !== 'undefined') {
console.error(error);
}
}
if (navigator.mediaDevices) {
console.log('getUserMedia supported.');
var constraints = { audio: true };
var chunks = [];
navigator.mediaDevices.getUserMedia(constraints)
.then(function(stream) {
var mediaRecorder = new MediaRecorder(stream);
visualize(stream);
record.onclick = function() {
mediaRecorder.start();
console.log(mediaRecorder.state);
console.log("recorder started");
record.style.background = "red";
record.style.color = "black";
}
stop.onclick = function() {
mediaRecorder.stop();
console.log(mediaRecorder.state);
console.log("recorder stopped");
record.style.background = "";
record.style.color = "";
}
mediaRecorder.onstop = function(e) {
console.log("data available after MediaRecorder.stop() called.");
var clipName = prompt('Enter a name for your sound clip');
var clipContainer = document.createElement('article');
var clipLabel = document.createElement('p');
var audio = document.createElement('audio');
var deleteButton = document.createElement('button');
clipContainer.classList.add('clip');
audio.setAttribute('controls', '');
deleteButton.innerHTML = "Delete";
clipLabel.innerHTML = clipName;
clipContainer.appendChild(audio);
clipContainer.appendChild(clipLabel);
clipContainer.appendChild(deleteButton);
soundClips.appendChild(clipContainer);
audio.controls = true;
var blob = new Blob(chunks, { 'type' : 'audio/ogg; codecs=opus' });
chunks = [];
var audioURL = URL.createObjectURL(blob);
audio.src = audioURL;
console.log("recorder stopped");
deleteButton.onclick = function(e) {
evtTgt = e.target;
evtTgt.parentNode.parentNode.removeChild(evtTgt.parentNode);
}
}
mediaRecorder.ondataavailable = function(e) {
chunks.push(e.data);
}
})
.catch(function(err) {
console.log('The following error occured: ' + err);
})
}
// Prefer camera resolution nearest to 1280x720.
var constraints = { audio: true, video: { width: 1280, height: 720 } };
navigator.mediaDevices.getUserMedia(constraints)
.then(function(mediaStream) {
var video = document.querySelector('video');
video.srcObject = mediaStream;
video.onloadedmetadata = function(e) {
video.play();
};
})
.catch(function(err) { console.log(err.name + ": " + err.message); }); // always check for errors at the end.
selectAudioOutput()
提示用户选择特定的音频输出设备。
let mediaRecorder;
const tracks = []; // 媒体数据
function init() {
const options = {
mimeType: "video/webm; codecs = vp8", // 媒体格式
};
let constraints = { video: true };
// 初始化请求用户授权监控(视频共享)
navigator.mediaDevices.getDisplayMedia(constraints).then((stream) => {
// 对音视流进行操作
// start(stream);
live(stream);
});
// 开始录制方法
function start(stream) {
// 创建 MediaRecorder 的实例对象,对指定的媒体流进行录制
mediaRecorder = new MediaRecorder(stream, options);
// 当生成媒体流数据时触发该事件,回调传参 event 指本次生成处理的媒体数据
mediaRecorder.ondataavailable = (event) => {
if (event.data && event.data.size && event.data.size > 0) {
tracks.push(event.data); // 存储媒体数据
}
};
mediaRecorder.start();
console.log("************开始录制************");
}
}
// 结束录制方法
function stop() {
mediaRecorder.stop();
console.log("************录制结束************");
}
// 定义constraints数据类型
// interface constraints {
// audio: boolean | MediaTrackConstraints, // 指定是否请求音轨或者约束轨道属性值的对象
// video: boolean | MediaTrackConstraints, // 指定是否请求视频轨道或者约束轨道属性值的对象
// }
// 直播
function live(stream) {
const video = document.getElementById("video");
video.srcObject = window.stream || stream;
video.controls = true;
video.play();
}
// 回放录制内容
function replay() {
const video1 = document.getElementById("video");
const blob = new Blob(tracks, { type: "video/webm" });
video1.src = window.URL.createObjectURL(blob);
video.srcObject = null;
video1.controls = true;
video1.play();
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<!-- <meta http-equiv="Content-Security-Policy" content="default-src 'self'; script-src 'self'">
<meta http-equiv="X-Content-Security-Policy" content="default-src 'self'; script-src 'self'"> -->
<!-- <meta name="description"
content="default-src script-src 'self' 'sha256-ThhI8UaSFEbbl6cISiZpnJ4Z44uNSq2tPKgyRTD3LyU='"> -->
<!-- <meta http-equiv="Content-Security-Policy" content="default-src 'self'
data:gap: http://www.visitsingapore.com
https://ssl.gstatic.com 'unsafe-eval';
style-src 'self' 'unsafe-inline';
media-src *;
script-src 'sha256-V+/U3qbjHKP0SaNQhMwYNm62gfWX4QHwPJ7We1PXokI='
"> -->
<!-- <meta http-equiv="Content-Security-Policy" content="default-src 'none'
data:gap: http://www.visitsingapore.com
https://ssl.gstatic.com 'unsafe-eval';
style-src '*' 'unsafe-inline';
media-src *;
script-src 'sha256-V+/sha256-ThhI8UaSFEbbl6cISiZpnJ4Z44uNSq2tPKgyRTD3LyU='
"> -->
<!-- <meta http-equiv="Content-Security-Policy"
content="default-src *; connect-src * ws://* wss://*; style-src * 'unsafe-inline' 'unsafe-eval'; media-src * ; img-src * data:; font-src * ; script-src * 'unsafe-inline' 'unsafe-eval';" />
<meta http-equiv="X-Content-Security-Policy" content="default-src 'self'; script-src 'self'"> -->
<title>Document</title>
<style>
#video {
width: 200px;
height: 200px;
}
</style>
<script src="./index.js"></script>
</head>
<body>
<!-- <meta http-equiv="Content-Security-Policy" content="default-src 'self';
script-src 'self' https://example.com 'sha256-base64 encoded hash'"> -->
<!-- manifest.json:
{
"manifest_version": 2,
"name": "csp test",
"version": "1.0.0",
"minimum_chrome_version": "46",
"content_security_policy": "script-src 'self' 'sha256-WOdSzz11/3cpqOdrm89LBL2UPwEU9EhbDtMy2OciEhs='",
"background": {
"page": "background.html"
}
} -->
<!-- <!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Security-Policy"
content="script-src 'self' 'sha256-WOdSzz11/3cpqOdrm89LBL2UPwEU9EhbDtMy2OciEhs='">
</head>
<body>
<script>alert('foo');</script>
</body>
</html> -->
<button id="init">init</button>
<button id="stop">停止</button>
<button id="replay">replay</button>
<button id="live">live</button>
<video width="300" height="300" id="video"></video>
<!-- <vodie id="video"></vodie> -->
<script>
document.getElementById('init').onclick = function () {
init()
};
document.getElementById('stop').onclick = function () {
stop()
};
document.getElementById('replay').onclick = function () {
replay()
};
document.getElementById('live').onclick = function () {
live()
}
</script>
</body>
</html>
```javascript
const recordBtn = document.querySelector(".record-btn");
const player = document.querySelector(".audio-player");
if (navigator.mediaDevices.getUserMedia) {
var chunks = [];
const constraints = { audio: true };
navigator.mediaDevices.getUserMedia(constraints).then(
stream => {
console.log("授权成功!");
const mediaRecorder = new MediaRecorder(stream);
recordBtn.onclick = () => {
if (mediaRecorder.state === "recording") {
mediaRecorder.stop();
recordBtn.textContent = "record";
console.log("录音结束");
} else {
mediaRecorder.start();
console.log("录音中...");
recordBtn.textContent = "stop";
}
console.log("录音器状态:", mediaRecorder.state);
};
mediaRecorder.ondataavailable = e => {
chunks.push(e.data);
};
mediaRecorder.onstop = e => {
var blob = new Blob(chunks, { type: "audio/ogg; codecs=opus" });
chunks = [];
var audioURL = window.URL.createObjectURL(blob);
player.src = audioURL;
};
},
() => {
console.error("授权失败!");
}
);
} else {
console.error("浏览器不支持 getUserMedia");
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>audio record</title>
</head>
<body>
<div class="app">
<button class="record-btn">record</button>
<audio controls class="audio-player"></audio>
</div>
<script src="./recorder.js"></script>
</body>
</html>