10.2 MediaDevices Interface Extensions | Media Capture and Streams
partial interface MediaDevices {
Promise<MediaStream> getUserMedia(optional MediaStreamConstraints constraints);
};
・使い方
navigator.mediaDevices.getUserMedia(constraints)
.then(stream => {})
.catch(err => {});
Promise
が返り、resolveされるとMediaStream
が取得できます。
// navigatorに生えてるし、コールバックベースである
navigator.getUserMedia(constraints, successCallback, errorCallback);
// なんか変な接頭辞ついてる
navigator.mozGetUserMedia(constraints, successCallback, errorCallback);
navigator.webkitGetUserMedia(constraints, successCallback, errorCallback);
2017年になっても謎の圧力によって古いブラウザを切れない人は、がんばってください・・。
// コレ
const constraints = { video: true };
navigator.mediaDevices.getUserMedia(constraints); // <- コレ!!
getUserMedia()
には、どういうMediaStream
が欲しいかを決めるオプションを渡すことができます。
オプションというより、Constraints: 制約を課すイメージ。
dictionary MediaStreamConstraints {
(boolean or MediaTrackConstraints) video = false;
(boolean or MediaTrackConstraints) audio = false;
};
audio
とvideo
それぞれ、どうしたいか決められる。
// カメラもマイクもくださいな
navigator.mediaDevices.getUserMedia({ video: true, audio: true });
// マイクのストリームだけくださいな
navigator.mediaDevices.getUserMedia({ audio: true });
false
または未定義の場合は、取得しない。
dictionary MediaStreamConstraints {
(boolean or MediaTrackConstraints) video = false;
(boolean or MediaTrackConstraints) audio = false;
};
実はコレ・・・、bool
以外にも指定できます!!
指定してるとこ、見たことありますよね?その指定の意味、把握してますよね?!
{
video: {
width: 1280,
height: 720,
frameRate: 15,
},
}
これはわかる!
{
video: {
width: 1280,
height: 720,
aspectRatio: 1.5,
},
}
これもわかる・・と思ったけど、この場合のアスペクト比はどうなる・・?
{
video: {
width: { min: 320, ideal: 1280, max: 1920 },
height: { min: 240, ideal: 720, max: 1080 },
frameRate: 30,
facingMode: { exact: 'environment' },
}
}
なんとなくわかる気はするけど、謎のキーワードがいっぱいある・・うっ・・。
{
audio: {
advanced: [{
echoCancellation: {
exact: true
}
}, {
googEchoCancellation: {
exact: true
}
}, {
googExperimentalEchoCancellation: {
exact: true
}
}, {
googNoiseSuppression: {
exact: true
}
}, {
googExperimentalNoiseSuppression: {
exact: true
}
}, {
googAutoGainControl: {
exact: true
}
}, {
googExperimentalAutoGainControl: {
exact: true
}
}, {
googHighpassFilter: {
exact: true
}
}, {
googTypingNoiseDetection: {
exact: true
}
}, {
googAudioMirroring: {
exact: false
}
}, {
deviceId: {
exact: ["default"]
}
}]
},
}
全然わからない(^ω^#)
dictionary MediaTrackConstraints : MediaTrackConstraintSet {
sequence<MediaTrackConstraintSet> advanced;
};
dictionary MediaTrackConstraintSet {
ConstrainLong width;
ConstrainLong height;
ConstrainDouble aspectRatio;
ConstrainDouble frameRate;
ConstrainDOMString facingMode;
ConstrainDouble volume;
ConstrainLong sampleRate;
ConstrainLong sampleSize;
ConstrainBoolean echoCancellation;
ConstrainBoolean autoGainControl;
ConstrainBoolean noiseSuppression;
ConstrainDouble latency;
ConstrainLong channelCount;
ConstrainDOMString deviceId;
ConstrainDOMString groupId;
};
これがvideo
とaudio
の直下に指定できるものたち。それに加えて、advanced
にも指定できる。
さっきのgoogXxxx
はChromeが勝手にやってる独自プロパティで、仕様書にはない😇
「絶対これに制限したいです!」という指定。
{
video: {
facingMode: { exact: 'environment' }
}
}
リアカメラのないMacbook Proとかでコレやると、rejectされます。
{
video: {
width: { min: 1920, },
}
}
Macbook ProのFaceカメラは720pなので、width: 1280
以上を指定するとrejectされます。
なのでとりあえず付けておくものではない!
「なにも制限せずブラウザに委ねます」という指定。
{
video: {
width: { ideal: 1920, },
}
}
実はこれ、値を直指定するのと同じ。
{
video: {
width: 1920,
}
}
ただ、指定したからといってそうなる保証はない。←重要
「できたら制限したいんですよねー、無理なら別に良いんですけど」という指定。
{
video: {
width: { min: 640, ideal: 1280 },
height: { min: 480, ideal: 720 },
// 値として使うキーワードではない
advanced: [
{ width: 1920, height: 1280 },
{ aspectRatio: 1.3333333333 },
]
},
}
最低でも640x480以上の解像度がいいです!
「でもできたら解像度は1920x1280がいいんですよねー。 それがダメならアス比は4:3のやつにしてもらえます?」
もしそれもダメならもう1280x720に近いやつでいいです・・。
{
video: {
advanced: [
// exactと同じ
{ aspectRatio: 1.3333333333 },
// こっちはフォールバック
{ aspectRatio: 1 },
// widthだけOKでもheightがNGなら両方NGになる
{ width: 1920, height: 1280 },
]
},
}
exact
と同じ意味処理の流れ。
大事なことはすべてこの章から教わりました。
{
video: {
width: 1280,
height: 720,
aspectRatio: 1.5,
},
}
width / height
は1.777
なので、3/3は満たせない。
この場合の組合せは3C2の3通りだが、どれになるかはブラウザがよしなにする。
手元のChromeはwidth
x height
になりました。
navigator.mediaDevices.getUserMedia({ video: { width: 100 } });
サイズ指定をしてないvideo
に、これで取得したストリームを表示した際、どうなるか。
今日時点の最新バージョン、いずれもMacbook Proの付属カメラにて。
{ video: { width: 100 } }
この指定はideal
なので、制約が受け入れられるかはブラウザ次第。FirefoxもEdgeも、挙動としては仕様書通り。
{ video: { width: { exact: 100 } } }
ちなみにこうするとRejectされる。
・・・Safari?知らない子ですね・・。
ideal
)navigator.mediaDevices.getSupportedConstraints();
仕様書的には、これで事前に確認しろって書いてあるけど、ブラウザは解釈できないプロパティを無視するので気休め。
(ちなみにSafariはwidth: true
って返してくる😇)
// Google ハングアウトより
{
audio: {
advanced: [
{
googEchoCancellation: {
exact: true
}
},
{
googExperimentalEchoCancellation: {
exact: true
}
},
{
googAutoGainControl: {
exact: true
}
},
{
googExperimentalAutoGainControl: {
exact: true
}
},
{
googNoiseSuppression: {
exact: true
}
},
{
googHighpassFilter: {
exact: true
}
},
{
googAudioMirroring: {
exact: false
}
},
{
googExperimentalNoiseSuppression: {
exact: true
}
}
]
}
}
chrome://webrtc-internals
で色んなサービスを探すと色々見つかる。
Chromiumのコードサーチでのみ色々見つかる。
chrome://webrtc-internals
により、video
だけでもこれだけの発掘に成功・・・!
それらしいプロパティは山ほど見つかるけど、
This interface is being deprecated in Chrome, and may be removed from WebRTC too.
とか書いてあるファイルもありよくわからん。(誰かChromiumのコードの追い方教えてください・・)
ただまぁ実際に動いてるから各サービスも使ってるんやろうけど・・。
触らぬ神に祟りなし! <- おすすめ
or
自己責任で使う