概覽 mediaDevices 是 Navigator 對象的只讀屬性,一個單列對象,可以連接訪問相機和麥克風,屏幕共用等媒體輸入設備 方法 enumerateDevices 請求一個可用的媒體輸入和輸出設備列表,如麥克風、相機、耳機等。返回的 完成狀態中是一個帶有 "MediaDeviceInfo ...
概覽
mediaDevices 是 Navigator 對象的只讀屬性,一個單列對象,可以連接訪問相機和麥克風,屏幕共用等媒體輸入設備
方法
enumerateDevices
請求一個可用的媒體輸入和輸出設備列表,如麥克風、相機、耳機等。返回的
Promise
完成狀態中是一個帶有 MediaDeviceInfo 的數組
let mediaDevices = navigator.mediaDevices
if(!mediaDevices || !mediaDevices.enumerateDevices) return console.erorr('瀏覽器不支持enumerateDevices API')
navigator.mediaDevices.enumerateDevices()
.then((devices)=>{
for (let device of devices){
console.log(device.kind + ': ' +device.lable + ' id = '+ device.deviceId );
}
})
.catch(err=>{
console.error(err)
})
/*
audioinput: undefined id = default
audioinput: undefined id = communications
audioinput: undefined id = ac67d348685a08c75e5017f9a449b3d85f08dcb774c88ab95de82bbf2c0fc820
videoinput: undefined id = e41039bcfbc84d926a0b73cdc1d8b1daf3d67d36c62588202191d918fb076426
audiooutput: undefined id = default
audiooutput: undefined id = communications
audiooutput: undefined id = 015d73652e57bffb21679b937675d32c4d4a43862aba3774aaf0b5f1e983151f
*/
相容性
getSupportedConstraints
返回一個 MediaTrackSupportedConstraints 對象,其屬性都是客戶端所支持約束的屬性,值為 Boolean 類型
let supportedConstraints = navigator.mediaDevices.getSupportedConstraints()
for (let constraint of Object.keys(supportedConstraints)){
console.log(constraint)
}
/*
aspectRatio
autoGainControl
brightness
channelCount
colorTemperature
contrast
deviceId
echoCancellation
exposureCompensation
exposureMode
exposureTime
facingMode
focusDistance
focusMode
frameRate
groupId
height
iso
latency
noiseSuppression
pointsOfInterest
resizeMode
sampleRate
sampleSize
saturation
sharpness
torch
volume
whiteBalanceMode
width
zoom
*/
相容性
getDisplayMedia
提示用戶選擇和授予許可權來捕獲顯示或部分的內容,(如分屏共用時分享哪一屏的內容)然後使用 medieaStream Recording API 記錄生成的 stream,或作為 webRTC 會話的一部分進行傳輸。
可以傳遞一個MediaStreamConstraints 對象指定返回要求的 mediaStream。
async function startCapture(displayMediaOptions) {
let captureStream = null;
try {
captureStream = await navigator.mediaDevices.getDisplayMedia(displayMediaOptions);
} catch(err) {
console.error("Error: " + err);
}
return captureStream;
}
相容性
getUserMedia
提示用戶給予使用媒體輸入的許可(如麥克風,攝像機),當媒體輸入時產生一個 mediaStream包含所請求的媒體類型的軌道。該流可以包括視頻軌道(攝像機,視頻記錄設備,共屏等硬體或虛擬視頻流源)、音頻軌道(來自麥克風、A/D轉換器等硬體或虛擬音頻源),也可能是其它軌道類型
該方法返回一個Promise
對象,成功時 resolve
回調函數帶有mediaStream
對象。如果用戶拒絕授予使用許可權,或是媒體源不可用,則返回 reject
回調
Promise
可能既不會 resolve
也不會reject
,因為用戶不必做出選擇,可能只是忽略請求
// 想要獲取一個最接近 1280x720 的相機解析度
let constraints = { audio: true, video: { width: 1280, height: 720 } };
navigator.mediaDevices.getUserMedia(constraints)
.then(function(mediaStream) {
let video = document.querySelector('video');
video.srcObject = mediaStream;
video.onloadedmetadata = function(e) {
video.play();
};
})
.catch(function(err) { console.log(err.name + ": " + err.message); });
參數 constraints
一個mediaStreamConstraints對象指定請求的媒體類型和相對應參數,該對象包含
video
和audio
兩個屬性,必須一個或兩個同時被指定,如果無法找到指定的媒體類型或無法滿足對於的參數要求,Promise
將返回rejected
參數配置
配置 1
{audio:true,video:true}
屬性設置為 Truthy 則生成的stream
必須具有該類型的軌道,否則調用 getUserMedia
會拋出錯誤
配置 2
{
audio: true,
video: { width: 1280, height: 720 }
}
表示video
的解析度應為 1280x720 瀏覽器將試著滿足這個請求參數,如果無法滿足要求或選擇覆蓋,則可能返回其它的解析度
配置 3
{
audio: true,
video: {
width: { min: 1280 },
height: { min: 720 }
}
}
此配置要求了最低解析度,如果達不到要求,promise
將返回 reject
;還可配置 max、exact(min == max),而且用戶將不會得到要求授權的提示
配置 4
{
audio: true,
video: {
width: { min: 1024, ideal: 1280, max: 1920 },
height: { min: 776, ideal: 720, max: 1080 }
}
}
如果使用ideal
,瀏覽器將嘗試找到(如果相機有多個的話)最接近指定值的理想值的設備或相機
意味著上方的第一個解析度例子可簡寫為:
{
audio: true,
video: {
width: { ideal: 1280 },
height: { ideal: 720 }
}
}
配置 5
並不是所有的 constraint
都說數字,如在移動設備上優先使用前置相機
{ audio: true, video: { facingMode: "user" } }
強制使用後置相機
{ audio: true,
video: {
facingMode: { exact: "environment" }
}
}
APP許可權配置
"permissions": {
"audio-capture": {
"description": "Required to capture audio using getUserMedia()"
},
"video-capture": {
"description": "Required to capture video using getUserMedia()"
}
}
作為可能涉及重大隱私問題的API,getUserMedia()規範規定了瀏覽器有義務滿足的各種隱私和安全要求。
getUserMedia()是一個強大的功能,只能在安全的環境中使用; 在不安全的情境中,navigator.mediaDevices
是undefined,阻止訪問getUserMedia()
。
簡而言之,安全上下文是使用HTTPS
或 file:///URL
方案載入的頁面,或者是從中載入的頁面localhost
。
在舊的瀏覽器中使用新的API
推薦使用處理了約束的 adapter.jspolyfill
來替代。
// 老的瀏覽器可能根本沒有實現 mediaDevices,所以我們可以先設置一個空的對象
let mediaDevices = navigator.mediaDevices
if (mediaDevices === undefined) {
mediaDevices = {};
}
// 一些瀏覽器部分支持 mediaDevices。我們不能直接給對象設置 getUserMedia
// 因為這樣可能會覆蓋已有的屬性。這裡我們只會在沒有getUserMedia屬性的時候添加它。
if (mediaDevices.getUserMedia === undefined) {
mediaDevices.getUserMedia = function(constraints) {
// 首先,如果有getUserMedia的話,就獲得它
var getUserMedia = navigator.webkitGetUserMedia || navigator.mozGetUserMedia;
// 一些瀏覽器根本沒實現它 - 那麼就返回一個error到promise的reject來保持一個統一的介面
if (!getUserMedia) {
return Promise.reject(new Error('getUserMedia is not implemented in this browser'));
}
// 否則,為老的navigator.getUserMedia方法包裹一個Promise
return new Promise(function(resolve, reject) {
getUserMedia.call(navigator, constraints, resolve, reject);
});
}
}
mediaDevices.getUserMedia({ audio: true, video: true })
.then(function(stream) {
var video = document.querySelector('video');
// 舊的瀏覽器可能沒有srcObject
if ("srcObject" in video) {
video.srcObject = stream;
} else {
// 防止在新的瀏覽器里使用它,應為它已經不再支持了
video.src = window.URL.createObjectURL(stream);
}
video.onloadedmetadata = function(e) {
video.play();
};
})
.catch(function(err) {
console.log(err.name + ": " + err.message);
});