Baseline Widely available
ãã®è¨äºã§ã¯ãå¶ç´ (constraints) ã¨è½å (capabilities) ã¨ãã 2 ã¤ã®æ¦å¿µã¨ãã¡ãã£ã¢è¨å®ã«ã¤ãã¦èª¬æããå¶ç´ã¨ã¯ãµãµã¤ã¶ã¼ã¨å¼ã°ããä¾ãæãã¦ãã¾ããå¶ç´ã¨ã¯ãµãµã¤ã¶ã¼ã§ã¯ãã³ã³ãã¥ã¼ã¿ã¼ã® A/V å ¥åæ©å¨ï¼ã¦ã§ãã«ã¡ã©ããã¤ã¯ãªã©ï¼ããå ¥åãããé³å£°ã¨æ åã®ãã©ãã¯ã«ãç°ãªãå½¢ã®å¶ç´è¨å®ã é©ç¨ããå ´åã®çµæã使ãåæãã試ããã¨ãã§ãã¾ãã
æ´å²çã«ã Web API ã¨å¯æ¥ã«é£æºããã¦ã§ãç¨ã®ã¹ã¯ãªããã使ãããã¨ã«ã¯ãããç¥ããã課é¡ãããã¾ããã å¤ãã®å ´åãã³ã¼ãã¯ãAPI ãåå¨ãããã©ãããåå¨ããå ´åã¯ããããå®è¡ãã¦ããã¦ã¼ã¶ã¼ã¨ã¼ã¸ã§ã³ãã®å¶éãç¥ãå¿ è¦ãããã¾ãã ãããçè§£ããã®ã¯é£ããå ´åãå¤ããé常ãå®è¡ãã¦ããã¦ã¼ã¶ã¼ã¨ã¼ã¸ã§ã³ãï¼ã¾ãã¯ãã©ã¦ã¶ã¼ï¼ã¨ãã®ãã¼ã¸ã§ã³ã®çµã¿åããã調ã¹ãç¹å®ã®ãªãã¸ã§ã¯ããåå¨ãããã©ããã確èªãããããã¾ãã¾ãªãã®ãæ©è½ãããã©ããã確èªããããã©ã®ã¨ã©ã¼ãçºçãããã夿ãããããå¿ è¦ãããã¾ããã ãã®çµæãé常ã«èå¼±ãªã³ã¼ãã大éã«çºçãããããã®ãããªåé¡ã解決ããã©ã¤ãã©ãªã¼ã«ä¾åããããããªãã£ã«ãå®è£ ãã¦å®è£ ã®ç©´ã«ããããå½ã¦ãããã¾ããã
è½åã¨å¶ç´ã«ããããã©ã¦ã¶ã¼ã¨ã¦ã§ããµã¤ãã¾ãã¯ã¢ããªã±ã¼ã·ã§ã³ã¯ããã©ã¦ã¶ã¼ã®å®è£ ã対å¿ãã¦ãã å¶ç´å¯è½ãªãããã㣠ã¨ãããããã«ã¤ãã¦å¯¾å¿ãã¦ããå¤ã«ã¤ãã¦ã®æ å ±ã交æãããã¨ãã§ãã¾ãã
æ¦è¦ããã»ã¹ã¯æ¬¡ã®ããã«åä½ãã¾ãï¼ä¾ã¨ã㦠MediaStreamTrack
ã使ç¨ï¼ã
MediaDevices.getSupportedConstraints()
ãå¼ã³åºãã¦ã対å¿ãã¦ããå¶ç´ (supported constraints) ã®ãªã¹ããåå¾ãã¾ãã ããã«ããããã©ã¦ã¶ã¼ãç¥ã£ã¦ããå¶ç´å¯è½ãªããããã£ããããã¾ãã ããã¯å¿
ãããå¿
è¦ãªããã§ã¯ããã¾ããã ç¥ããªããã®ã¯æå®ããã¨åã«ç¡è¦ãããããã§ãã ãã ãããããªãã§ã¯æã«å
¥ããªããã®ãããå ´åã¯ããªã¹ãã«è¼ã£ã¦ãããã¨ã確èªãããã¨ããå§ãããã¨ãã§ãã¾ããgetCapabilities()
ã¡ã½ããã«ãã£ã¦è¿ããããªãã¸ã§ã¯ãã調ã¹ããã¨ã«ãããAPI ã¨ãã®å®è£
ã®è½åã確èªã§ãã¾ãã ãã®ãªãã¸ã§ã¯ãã¯ã対å¿ãã¦ããåå¶ç´ã¨ã対å¿ãã¦ããå¤ã¾ãã¯å¤ã®ç¯å²ããªã¹ããã¾ããapplyConstraints()
ã¡ã½ãããå¼ã³åºãã¦ã好ã¿ã®å¶ç´å¯è½ãªããããã£ã«ä½¿ç¨ããå¤ã¾ãã¯å¤ã®ç¯å²ãæå®ãããã¨ã«ãããå¿
è¦ã«å¿ã㦠API ãæ§æãã¾ããgetConstraints()
ã¡ã½ããã¯ãapplyConstraints()
ã®ææ°ã®å¼ã³åºãã«æ¸¡ãããå¶ç´ã»ãããè¿ãã¾ãã ããã¯ãè¦æ±ãããå¤ã調æ´ããå¿
è¦ãããããããã£ã¨ããã©ãããã©ã¼ã ã®æ¢å®å¤ã表ããã¦ããªãããããã©ãã¯ã®å®éã®ç¾å¨ã®ç¶æ
ã表ãã¦ããªãå ´åãããã¾ãã ãã©ãã¯ã®ç¾å¨ã®æ§æãå®å
¨ã«è¡¨ç¾ããã«ã¯ãgetSettings()
ã使ç¨ãã¾ããã¡ãã£ã¢ãã£ããã£ã¨ã¹ããªã¼ã API ã§ã¯ãMediaStream
㨠MediaStreamTrack
ã®ä¸¡æ¹ã«å¶ç´å¯è½ãªããããã£ãããã¾ãã
ç¹å®ã®å¶ç´ã«ã¦ã¼ã¶ã¼ã¨ã¼ã¸ã§ã³ãã対å¿ãã¦ãããã©ãããç¥ãå¿
è¦ãããå ´åã¯ã次ã®ããã« navigator.mediaDevices.getSupportedConstraints()
ãå¼ã³åºãã¦ããã©ã¦ã¶ã¼ãç¥ã£ã¦ããå¶ç´å¯è½ãªããããã£ã®ãªã¹ããåå¾ãã¾ãã
const supported = navigator.mediaDevices.getSupportedConstraints();
document.getElementById("frameRateSlider").disabled = !supported["frameRate"];
ãã®ä¾ã§ã¯ã対å¿ãã¦ããå¶ç´ãåå¾ããframeRate
å¶ç´ã«å¯¾å¿ãã¦ããªãå ´åãã¦ã¼ã¶ã¼ããã¬ã¼ã ã¬ã¼ããæ§æã§ããã³ã³ããã¼ã«ãç¡å¹ã«ãã¾ãã
åä¸ã®å¶ç´ã¯ãç®çã®å¤ã¾ãã¯å¤ã®ç¯å²ãæå®ããã¦ããå¶ç´å¯è½ãªããããã£ã¨ååãä¸è´ãããªãã¸ã§ã¯ãã§ãã ãã®ãªãã¸ã§ã¯ãã«ã¯ã0 å以ä¸ã®åå¥ã®å¶ç´ã¨ãadvanced
ã¨ãããªãã·ã§ã³ã®ãµããªãã¸ã§ã¯ããå«ã¾ãã¾ãã ãã®ãµããªãã¸ã§ã¯ãã«ã¯ãã¦ã¼ã¶ã¼ã¨ã¼ã¸ã§ã³ããå¯è½ãªéãæºããå¿
è¦ããã 0 å以ä¸ã®å¶ç´ã®å¥ã®ã»ãããå«ã¾ãã¾ãã ã¦ã¼ã¶ã¼ã¨ã¼ã¸ã§ã³ãã¯ãå¶ç´ã»ããã§æå®ãããé åºã§å¶ç´ãæºãããã¨ã試ã¿ã¾ãã
çè§£ãã¹ãæãéè¦ãªãã¨ã¯ãã»ã¨ãã©ã®å¶ç´ã¯å¿ è¦æ¡ä»¶ã§ã¯ãªãã¨ãããã¨ã§ãã ãããããããããããã¯è¦æ±ã§ãã ä¾å¤ããããããã«ãããã«å°éãã¾ãã
è¨å®ã«ç¹å®ã®å¤ãè¦æ±æãç°¡åã«ã¯ãåå¶ç´ã¯ãè¨å®ã«å¿ è¦ãªå¤ã示ãç¹å®ã®å¤ã§ããå ´åãããã¾ãã ä¾ãã°ã次ã®ããã«ã§ãã
const constraints = {
width: 1920,
height: 1080,
aspectRatio: 1.777777778,
};
myTrack.applyConstraints(constraints);
ãã®å ´åãå¶ç´ã¯ãã»ã¼ãã¹ã¦ã®ããããã£ã§ä»»æã®å¤ãé©åã§ãããã¨ã示ãã¾ãããæ¨æºã® 16:9 ã®ã¢ã¹ãã¯ãæ¯ã§æ¨æºã®é«è§£å度 (HD) åç»ãµã¤ãºãæã¾ãããã¨ã示ãã¾ãã çµæã®ãã©ãã¯ããããã®ããããã«ä¸è´ããã¨ããä¿è¨¼ã¯ããã¾ããããã¦ã¼ã¶ã¼ã¨ã¼ã¸ã§ã³ãã¯å¯è½ãªéãä¸è´ããããã«æåãå°½ããå¿ è¦ãããã¾ãã
ããããã£ã®åªå é ä½ä»ãã¯ç°¡åã§ãã 2 ã¤ã®ããããã£ã®è¦æ±å¤ãç¸äºã«æä»çã§ããå ´åãå¶ç´ã»ããã®æåã«ãªã¹ãããã¦ããå¤ã使ç¨ãã¾ãã ä¾ã¨ãã¦ãä¸è¨ã®ã³ã¼ããå®è¡ãã¦ãããã©ã¦ã¶ã¼ã¯ 1920x1080 ã®ãã©ãã¯ãæä¾ã§ããªããã1920x900 ãæä¾ã§ããå ´åããããæä¾ãã¾ãã
åä¸ã®å¤ãæå®ãããããã®ãããªåç´ãªå¶ç´ã¯ã常ã«å¿
é ã§ãªããã®ã¨ãã¦æ±ããã¾ãã ã¦ã¼ã¶ã¼ã¨ã¼ã¸ã§ã³ãã¯ãããªããè¦æ±ãããã®ãæä¾ãããã¨ãã¾ãããããªããå¾ããã®ãä¸è´ãããã¨ãä¿è¨¼ãã¾ããã ããããªããã MediaStreamTrack.applyConstraints()
ãå¼ã³åºãã¨ãã«ããããã£ã«åç´ãªå¤ã使ç¨ããã¨ããããã®å¤ã¯å¿
è¦æ¡ä»¶ã§ã¯ãªãè¦æ±ã¨è¦ãªããããããè¦æ±ã¯å¸¸ã«æåãã¾ãã
å ´åã«ãã£ã¦ã¯ãç¯å²å ã®ä»»æã®å¤ãããããã£ã®å¤ã¨ãã¦åãå ¥ãããããã¨ãããã¾ãã ç¯å²ã¯ãæå°å¤ã¨æå¤§å¤ã®ããããã¾ãã¯ä¸¡æ¹ãæå®ã§ããå¿ è¦ã«å¿ãã¦ç¯å²å ã§çæ³çãªå¤ ideal ãæçµçµæã¨ãã¦æå®ã§ãã¾ãã çæ³çãªå¤ãæå®ããã¨ããã©ã¦ã¶ã¼ã¯ãæå®ãããä»ã®å¶ç´ã«å¿ãã¦ããã®å¤ã«ã§ããã ãä¸è´ããããã«è¿ã¥ãããã¨ãã¾ãã
const supports = navigator.mediaDevices.getSupportedConstraints();
if (
!supports["width"] ||
!supports["height"] ||
!supports["frameRate"] ||
!supports["facingMode"]
) {
// å¿
è¦ãªããããã£ãä¸è¶³ãã¦ããããããã®ã¨ã©ã¼ãå¦çãã¾ãã
} else {
const constraints = {
width: { min: 640, ideal: 1920, max: 1920 },
height: { min: 400, ideal: 1080 },
aspectRatio: 1.777777778,
frameRate: { max: 30 },
facingMode: { exact: "user" },
};
myTrack
.applyConstraints(constraints)
.then(() => {
/* å¶ç´ãæ£å¸¸ã«é©ç¨ããããä½ãããã */
})
.catch((reason) => {
/* å¶ç´ãé©ç¨ã§ãã¾ããã§ããã reason ãçç± */
});
}
ããã§ã¯ãä¸è´ãè¦ã¤ããå¿
è¦ã®ããå¶ç´å¯è½ãªãããã㣠(width
, height
, frameRate
, facingMode
) ããµãã¼ãããã¦ãããã¨ã確èªããå¾ãå¹
㯠640 ä»¥ä¸ 1920 以ä¸ï¼ã§ããã° 1920ï¼ãé«ã㯠400 以ä¸ï¼çæ³çã«ã¯ 1080ï¼ãã¢ã¹ãã¯ãæ¯ã¯ 16:9 (1.777777778)ããã¬ã¼ã ã¬ã¼ã㯠30 ãã¬ã¼ã /ç§ä»¥ä¸ãè¦æ±ããå¶ç´ãè¨å®ãã¾ãã ããã«ãå¯ä¸ã®è¨±å®¹å¯è½ãªå
¥åããã¤ã¹ã¯ãã¦ã¼ã¶ã¼ã«é¢ããã«ã¡ã©ï¼èªæ®ãã«ã¡ã©ï¼ã§ãã width
ãheight
ãframeRate
ãfacingMode
ã®å¶ç´ãæºããããªãå ´åã applyConstraints()
ã«ãã£ã¦è¿ããããããã¹ã¯æå¦ããã¾ãã
ã¡ã¢: max
ãmin
ãexact
ã®ããããã¾ãã¯ãã¹ã¦ã使ç¨ãã¦æå®ãããå¶ç´ã¯ã常ã«å¿
é ã¨ãã¦æ±ããã¾ãã applyConstraints()
ãå¼ã³åºãã¦ã使ç¨ããå¶ç´ã 1 ã¤ä»¥ä¸ãæºãããã¨ãã§ããªãå ´åããããã¹ã¯æå¦ããã¾ãã
advanced
ããããã£ãå¶ç´ã»ããã«è¿½å ããã¨ãããããé«åº¦ãªå¶ç´ã使ããã¾ãã ãã®ããããã£ã®å¤ã¯ããªãã·ã§ã³ã¨è¦ãªããã追å ã®å¶ç´ã»ããã®é
åã§ãã ãã®æ©è½ã®ã¦ã¼ã¹ã±ã¼ã¹ã¯ã»ã¨ãã©ãªãã仿§ããåãé¤ããã¨ã«é¢å¿ããããããããã§ã¯èª¬æãã¾ããã 詳細ã«ã¤ãã¦ã¯ãMedia Capture and Streams 仿§æ¸ã®ã»ã¯ã·ã§ã³ 11ãéå»ã®ä¾ 2 ãåç
§ãã¦ãã ããã
MediaStreamTrack.getCapabilities()
ãå¼ã³åºãã¦ã対å¿ãã¦ãããã¹ã¦ã®è½åã¨ããã®ãããããç¾å¨ã®ãã©ãããã©ã¼ã ã¨ã¦ã¼ã¶ã¼ã¨ã¼ã¸ã§ã³ãã§åãå
¥ããããå¤ã¾ãã¯å¤ã®ç¯å²ã®ãªã¹ããåå¾ã§ãã¾ãã ãã®é¢æ°ã¯ããã©ã¦ã¶ã¼ã対å¿ãã¦ããåå¶ç´å¯è½ãªããããã£ã¨ããããã®ããããã£ã®ããããã対å¿ãã¦ããå¤ã¾ãã¯å¤ã®ç¯å²ãåæãããªãã¸ã§ã¯ããè¿ãã¾ãã
ã¡ã¢: getCapabilities()
ã¯ãã¾ã ãã¹ã¦ã®ä¸»è¦ãªãã©ã¦ã¶ã¼ã§å®è£
ããã¦ãã¾ããã ã¨ãããããããªãã¯å¿
è¦ãªãã®ãæã«å
¥ãããã¨ããå¿
è¦ãããããããããã§ããªããã°ããã®æç¹ã§ä½ããã¹ãããæ±ºå®ãã¾ãã ä¾ãã°ã Firefox ãã° 1179084 ãåç
§ãã¦ãã ããã
å¶ç´ã使ç¨ããæåã®æãä¸è¬çãªæ¹æ³ã¯ã次ã®ããã« getUserMedia()
ãå¼ã³åºãã¨ãã«å¶ç´ãæå®ãããã¨ã§ãã
navigator.mediaDevices
.getUserMedia({
video: {
width: { min: 640, ideal: 1920 },
height: { min: 400, ideal: 1080 },
aspectRatio: { ideal: 1.7777777778 },
},
audio: {
sampleSize: 16,
channelCount: 2,
},
})
.then((stream) => {
videoElement.srcObject = stream;
})
.catch(handleError);
ãã®ä¾ã§ã¯ãgetUserMedia()
ã®æç¹ã§å¶ç´ãé©ç¨ãããåç»ã®ããã®ãã©ã¼ã«ããã¯ãåããçæ³çãªãªãã·ã§ã³ã®ã»ãããè¦æ±ããã¾ãã
ã¡ã¢: 1 ã¤ä»¥ä¸ã®ã¡ãã£ã¢å
¥åããã¤ã¹ ID ãæå®ãã¦ãå
¥åã½ã¼ã¹ã許å¯ãããå¶éãè¨å®ã§ãã¾ãã å©ç¨å¯è½ãªããã¤ã¹ã®ãªã¹ããåéããã«ã¯ãnavigator.mediaDevices.enumerateDevices()
ãå¼ã³åºãã¦ãããç®çã®æ¡ä»¶ãæºããåããã¤ã¹ã«å¯¾ãã¦ããã® deviceId
ã MediaConstraints
ãªãã¸ã§ã¯ãã«è¿½å ãã¦ãæçµçã« getUserMedia()
ã«æ¸¡ãã¾ãã
次ã®ããã«ãã©ãã¯ã® applyConstraints()
ã¡ã½ãããå¼ã³åºãããã©ãã¯ã«é©ç¨ããå¶ç´ã表ããªãã¸ã§ã¯ããæ¸¡ããã¨ã§ãæ¢åã® MediaStreamTrack
ã®å¶ç´ãè¨æ©å¿å¤ã«å¤æ´ãããã¨ãã§ãã¾ãã
videoTrack.applyConstraints({
width: 1920,
height: 1080,
});
ãã®ã¹ããããã§ã¯ãvideoTrack
ãåç
§ããæ åãã©ãã¯ãæ´æ°ããããã®è§£å度ãå¯è½ãªéã 1920x1080 ãã¯ã»ã«ï¼1080p é«è§£å度ï¼ã«ä¸è´ããããã«ãªãã¾ãã
å¶ç´ã¨è¨å® (settings) ã®éããè¦ãã¦ãããã¨ã¯éè¦ã§ãã å¶ç´ã¯ãï¼MediaTrackConstraints
ã®è¨äºã§èª¬æããã¦ããããã«ï¼ãã¾ãã¾ãªå¶ç´å¯è½ãªããããã£ã«å¿
è¦ãªå¤ã叿ããå¤ãããã³åãå
¥ããå¤ãæå®ããæ¹æ³ã§ãã 䏿¹ãè¨å®ã¯ç¾å¨ã®åå¶ç´å¯è½ãªããããã£ã®å®éã®å¤ã§ãã
ç¾å¨ã¡ãã£ã¢ã«é©ç¨ããã¦ããå¶ç´ã»ãããåå¾ããå¿
è¦ãããå ´åã¯ã次ã®ä¾ã«ç¤ºãããã«ãMediaStreamTrack.getConstraints()
ãå¼ã³åºããã¨ã§ãã®æ
å ±ãåå¾ã§ãã¾ãã
function switchCameras(track, camera) {
const constraints = track.getConstraints();
constraints.facingMode = camera;
track.applyConstraints(constraints);
}
ãã®é¢æ°ã¯ãMediaStreamTrack
ã¨ä½¿ç¨ããã«ã¡ã©ã«é¢ããã¢ã¼ãã示ãæååãåãå
¥ããç¾å¨ã®å¶ç´ãåå¾ããMediaTrackConstraints.facingMode
ã®å¤ãæå®ãããå¤ã«è¨å®ããæ´æ°ãããå¶ç´ã»ãããé©ç¨ãã¾ãã
å³å¯ãªå¶ç´ã®ã¿ã使ç¨ããªãéãï¼ããã¯é常ã«å¶éçã§ãã®ã§ãããã®æå³ãããã¨ã確èªãã¦ãã ããï¼ï¼ãå¶ç´ãé©ç¨ãããå¾ã«å®éã«ä½ãå¾ãããããä¿è¨¼ãããã®ã§ã¯ããã¾ããã çµæã®ã¡ãã£ã¢ã«å®éã«åå¨ããå¶ç´å¯è½ãªããããã£ã®å¤ã¯ãè¨å®ã¨å¼ã°ãã¾ãã ã¡ãã£ã¢ã®å®éã®å½¢å¼ããã®ä»ã®ããããã£ãç¥ãå¿
è¦ãããå ´åã¯ãMediaStreamTrack.getSettings()
ãå¼ã³åºãã¦ãããã®è¨å®ãåå¾ã§ãã¾ãã ããã¯ããã£ã¯ã·ã§ã㪠MediaTrackSettings
ã«åºã¥ããªãã¸ã§ã¯ããè¿ãã¾ãã ä¾ãã°æ¬¡ã®ããã«ã§ãã
function whichCamera(track) {
return track.getSettings().facingMode;
}
ãã®é¢æ°ã¯ãgetSettings()
ã使ç¨ãã¦ããã©ãã¯ã®å¶ç´å¯è½ãªããããã£ã®ç¾å¨ä½¿ç¨ä¸ã®å¤ãåå¾ããfacingMode
ã®å¤ãè¿ãã¾ãã
ãã®ä¾ã§ã¯ãé³å£°ãã©ãã¯ã¨æ åãã©ãã¯ã®å¶ç´ã»ãããè¨è¿°ããã½ã¼ã¹ã³ã¼ããç·¨éãã¦ãã¡ãã£ã¢ã®å¶ç´ã試ããã¨ãã§ããã¨ã¯ãµãµã¤ã¶ã¼ã使ãã¾ãã ãã®å¾ããããã®å¤æ´ãé©ç¨ãã¦ãã¹ããªã¼ã ã®å¤è¦³ããæ°ããå¶ç´ãé©ç¨ããå¾ã®å®éã®ã¡ãã£ã¢è¨å®ã®ä¸¡æ¹ãå«ãçµæã確èªã§ãã¾ãã
ãã®ä¾ã® HTML 㨠CSS ã¯é常ã«åç´ã§ãããããã«ã¯ç¤ºããã¦ãã¾ããã ãããã¯ãªãã¯ããã¨ãå®å ¨ãªä¾ãè¦ããã¨ãã§ãã¾ãã
<p>
ã¡ãã£ã¢ã®å¶ç´ã試ãã¦ãã ããï¼
å·¦å´ã®ç·¨éããã¯ã¹ã§æ åãã©ãã¯ã¨é³å£°ãã©ãã¯ã®å¶ç´ã»ãããç·¨éãã[å¶ç´ã®é©ç¨]
ãã¿ã³ãã¯ãªãã¯ãã¦è©¦ãã¦ãã ããã
ãã©ã¦ã¶ã¼ã鏿ãã¦ä½¿ç¨ãã¦ããå®éã®è¨å®ã¯ãå³å´ã®ããã¯ã¹ã«è¡¨ç¤ºããã¾ãã
ãã®ãã¹ã¦ã®ä¸ã«ãåç»èªä½ã表示ããã¾ãã
</p>
<p>[éå§] ãã¿ã³ãã¯ãªãã¯ãã¦éå§ãã¾ãã</p>
<h3>使ç¨ã§ããå¶ç´å¯è½ãªããããã£:</h3>
<ul id="supportedConstraints"></ul>
<div id="startButton" class="button">éå§</div>
<div class="wrapper">
<div class="trackrow">
<div class="leftside">
<h3>è¦æ±ããåç»ã®å¶ç´:</h3>
<textarea id="videoConstraintEditor" cols="32" rows="8"></textarea>
</div>
<div class="rightside">
<h3>å®éã®åç»ã®è¨å®:</h3>
<textarea id="videoSettingsText" cols="32" rows="8" disabled></textarea>
</div>
</div>
<div class="trackrow">
<div class="leftside">
<h3>è¦æ±ããé³å£°ã®å¶ç´:</h3>
<textarea id="audioConstraintEditor" cols="32" rows="8"></textarea>
</div>
<div class="rightside">
<h3>å®éã®é³å£°ã®è¨å®:</h3>
<textarea id="audioSettingsText" cols="32" rows="8" disabled></textarea>
</div>
</div>
<div class="button" id="applyButton">å¶ç´ã®é©ç¨</div>
</div>
<video id="video" autoplay></video>
<div class="button" id="stopButton">忢</div>
<div id="log"></div>
body {
font:
14px "Open Sans",
"Arial",
sans-serif;
}
video {
margin-top: 20px;
border: 1px solid black;
}
.button {
cursor: pointer;
width: 150px;
border: 1px solid black;
font-size: 16px;
text-align: center;
padding-top: 2px;
padding-bottom: 4px;
color: white;
background-color: darkgreen;
}
.wrapper {
margin-bottom: 10px;
width: 600px;
}
.trackrow {
height: 200px;
}
.leftside {
float: left;
width: calc(calc(100% / 2) - 10px);
}
.rightside {
float: right;
width: calc(calc(100% / 2) - 10px);
}
textarea {
padding: 8px;
}
h3 {
margin-bottom: 3px;
}
#supportedConstraints {
column-count: 2;
}
#log {
padding-top: 10px;
}
æ¢å®å¤ã¨å¤æ°
æåã«ãæååã¨ãã¦æ¢å®ã®å¶ç´ã»ãããããã¾ãã ãããã®æååã¯ç·¨éå¯è½ãª <textarea>
ã«è¡¨ç¤ºããã¾ãããããã¯ã¹ããªã¼ã ã®åææ§æã§ãã
const videoDefaultConstraintString =
'{\n "width": 320,\n "height": 240,\n "frameRate": 30\n}';
const audioDefaultConstraintString =
'{\n "sampleSize": 16,\n "channelCount": 2,\n "echoCancellation": false\n}';
ãããã®æ¢å®å¤ã¯ãããªãä¸è¬çãªã«ã¡ã©æ§æãè¦æ±ãã¾ãããç¹ã«éè¦ãªããããã£ã§ãããã¨ã主張ãã¾ããã ãã©ã¦ã¶ã¼ã¯ããããã®è¨å®ã«ä¸è´ããããã«æåãå°½ããå¿ è¦ãããã¾ãããè¿ãä¸è´ã¨è¦ãªããããã®ãªãä½ã§ãããã§è§£æ±ºãã¾ãã
次ã«ãæ åãã©ãã¯ããã³é³å£°ãã©ãã¯ã® MediaTrackConstraints
ãªãã¸ã§ã¯ããä¿æãã夿°ã¨ãæ åãã©ãã¯ããã³é³å£°ãã©ãã¯èªä½ã¸ã®åç
§ãä¿æãã夿°ã null
ã«åæåãã¾ãã
let videoConstraints = null;
let audioConstraints = null;
let audioTrack = null;
let videoTrack = null;
ããã¦ãã¢ã¯ã»ã¹ããå¿ è¦ã®ãããã¹ã¦ã®è¦ç´ ã¸ã®åç §ãåå¾ãã¾ãã
const videoElement = document.getElementById("video");
const logElement = document.getElementById("log");
const supportedConstraintList = document.getElementById("supportedConstraints");
const videoConstraintEditor = document.getElementById("videoConstraintEditor");
const audioConstraintEditor = document.getElementById("audioConstraintEditor");
const videoSettingsText = document.getElementById("videoSettingsText");
const audioSettingsText = document.getElementById("audioSettingsText");
ãããã®è¦ç´ ã¯æ¬¡ã®ã¨ããã§ãã
videoElement
ã¹ããªã¼ã ã表示ãã <video>
è¦ç´ ã
logElement
ã¨ã©ã¼ã¡ãã»ã¼ã¸ããã®ä»ã®ãã°ã®ç¨®é¡ã®åºåãæ¸ãè¾¼ã¾ãã <div>
ã
supportedConstraintList
ã¦ã¼ã¶ã¼ã®ãã©ã¦ã¶ã¼ããµãã¼ããã¦ããåå¶ç´å¯è½ãªããããã£ã®ååãããã°ã©ã ã§è¿½å ãã <ul>
ï¼é åºãªããªã¹ãï¼ã
videoConstraintEditor
ã¦ã¼ã¶ã¼ãæ åãã©ãã¯ã®å¶ç´ã»ããã®ã³ã¼ããç·¨éã§ããããã«ãã <textarea>
è¦ç´ ã
audioConstraintEditor
ã¦ã¼ã¶ã¼ãé³å£°ãã©ãã¯ã®å¶ç´ã»ããã®ã³ã¼ããç·¨éã§ããããã«ãã <textarea>
è¦ç´ ã
videoSettingsText
æ åãã©ãã¯ã®å¶ç´å¯è½ãªããããã£ã®ç¾å¨ã®è¨å®ã表示ãã <textarea>
ï¼å¸¸ã«ç¡å¹ï¼ã
audioSettingsText
é³å£°ãã©ãã¯ã®å¶ç´å¯è½ãªããããã£ã®ç¾å¨ã®è¨å®ã表示ãã <textarea>
ï¼å¸¸ã«ç¡å¹ï¼ã
æå¾ã«ã2 ã¤ã®å¶ç´ã»ããã¨ãã£ã¿ã¼è¦ç´ ã®ç¾å¨ã®å å®¹ãæ¢å®å¤ã«è¨å®ãã¾ãã
videoConstraintEditor.value = videoDefaultConstraintString;
audioConstraintEditor.value = audioDefaultConstraintString;
è¨å®ã®è¡¨ç¤ºã®æ´æ°
åå¶ç´ã»ããã¨ãã£ã¿ã¼ã®å³å´ã«ã¯ããã©ãã¯ã®æ§æå¯è½ãªããããã£ã®ç¾å¨ã®æ§æã表示ããããã«ä½¿ç¨ãã 2 çªç®ã®ããã¹ãããã¯ã¹ãããã¾ãã ãã®è¡¨ç¤ºã颿° getCurrentSettings()
ã§æ´æ°ãã¾ãã ãã®é¢æ°ã¯ãé³å£°ãã©ãã¯ã¨æ åãã©ãã¯ã®ç¾å¨ã®è¨å®ãåå¾ããvalue
ãè¨å®ãããã¨ã§å¯¾å¿ããã³ã¼ãããã©ãã¯ã®è¨å®è¡¨ç¤ºããã¯ã¹ã«æ¿å
¥ãã¾ãã
function getCurrentSettings() {
if (videoTrack) {
videoSettingsText.value = JSON.stringify(videoTrack.getSettings(), null, 2);
}
if (audioTrack) {
audioSettingsText.value = JSON.stringify(audioTrack.getSettings(), null, 2);
}
}
ããã¯ã以ä¸ã«ç¤ºãããã«ãæ´æ°ããå¶ç´ãé©ç¨ããã¨ãã ãã§ãªããã¹ããªã¼ã ã®æåã®èµ·åå¾ã«ãå¼ã³åºããã¾ãã
ãã©ãã¯ã®å¶ç´ã»ãããªãã¸ã§ã¯ãã®æ§ç¯buildConstraints()
颿°ã¯ã2 ã¤ã®ãã©ãã¯ã®å¶ç´ã»ããç·¨éããã¯ã¹å
ã®ã³ã¼ãã使ç¨ãã¦ãé³å£°ãã©ãã¯ã¨æ åãã©ãã¯ã® MediaTrackConstraints
ãªãã¸ã§ã¯ããæ§ç¯ãã¾ãã
function buildConstraints() {
try {
videoConstraints = JSON.parse(videoConstraintEditor.value);
audioConstraints = JSON.parse(audioConstraintEditor.value);
} catch (error) {
handleError(error);
}
}
ãã㯠JSON.parse()
ã使ç¨ãã¦ãåã¨ãã£ã¿ã¼å
ã®ã³ã¼ãããªãã¸ã§ã¯ãã«è§£æãã¾ãã JSON.parse()
ã®å¼ã³åºãã®ã©ã¡ãããä¾å¤ãã¹ãã¼ããå ´åãhandleError()
ãå¼ã³åºããã¦ã¨ã©ã¼ã¡ãã»ã¼ã¸ããã°ã«åºåããã¾ãã
startVideo()
ã¡ã½ããã¯ãåç»ã¹ããªã¼ã ã®ã»ããã¢ããã¨éå§ãå¦çãã¾ãã
function startVideo() {
buildConstraints();
navigator.mediaDevices
.getUserMedia({
video: videoConstraints,
audio: audioConstraints,
})
.then((stream) => {
const audioTracks = stream.getAudioTracks();
const videoTracks = stream.getVideoTracks();
videoElement.srcObject = stream;
if (audioTracks.length > 0) {
audioTrack = audioTracks[0];
}
if (videoTracks.length > 0) {
videoTrack = videoTracks[0];
}
})
.then(() => {
return new Promise((resolve) => {
videoElement.onloadedmetadata = resolve;
});
})
.then(() => {
getCurrentSettings();
})
.catch(handleError);
}
ããã«ã¯ã次ã®ãããªããã¤ãã®æé ãããã¾ãã
buildConstraints()
ãå¼ã³åºãã¦ãç·¨éããã¯ã¹å
ã®ã³ã¼ããã 2 ã¤ã®ãã©ãã¯ã® MediaTrackConstraints
ãªãã¸ã§ã¯ãã使ãã¾ããnavigator.mediaDevices.getUserMedia()
ãå¼ã³åºããæ åãã©ãã¯ããã³é³å£°ãã©ãã¯ã®å¶ç´ãªãã¸ã§ã¯ããæ¸¡ãã¾ãã ããã«ãããå
¥åã«ä¸è´ããã½ã¼ã¹ããã®é³å£°ã¨åç»ãå«ã MediaStream
ãè¿ããã¾ãï¼é常ã¯ã¦ã§ãã«ã¡ã©ã§ãããé©åãªå¶ç´ãæå®ããã¨ä»ã®ã½ã¼ã¹ããã¡ãã£ã¢ãåå¾ã§ãã¾ãï¼ã<video>
è¦ç´ ã«æ·»ä»ããé³å£°ãã©ãã¯ã¨æ åãã©ãã¯ã夿° audioTrack
㨠videoTrack
ã«åãè¾¼ã¿ã¾ããloadedmetadata
ã¤ãã³ããçºçããã¨ãã«è§£æ±ºãããããã¹ãè¨å®ãã¾ããgetCurrentSettings()
颿°ï¼ä¸è¨ãåç
§ï¼ãå¼ã³åºãã¦ãå¶ç´ã¨ãã¼ãã¦ã§ã¢ã®è½åãèæ
®ããå¾ã«ãã©ã¦ã¶ã¼ã決å®ããå®éã®è¨å®ã表示ãã¾ããhandleError()
ã¡ã½ããã使ç¨ãã¦ãã°ã«è¨é²ãã¾ããã¾ãã[éå§] ãã¿ã³ãã¯ãªãã¯ãããã®ãç£è¦ããã¤ãã³ããªã¹ãã¼ãè¨å®ããå¿ è¦ãããã¾ãã
document.getElementById("startButton").addEventListener(
"click",
() => {
startVideo();
},
false,
);
å¶ç´ã»ããã®æ´æ°ã®é©ç¨
次ã«ã[å¶ç´ã®é©ç¨] ãã¿ã³ã®ã¤ãã³ããªã¹ãã¼ãè¨å®ãã¾ãã ã¯ãªãã¯ãããã¾ã 使ç¨ä¸ã®ã¡ãã£ã¢ããªãå ´åã¯ãstartVideo()
ãå¼ã³åºããæå®ãããè¨å®ã§ã¹ããªã¼ã ãéå§ããæ©è½ããã®é¢æ°ã«å¦çããã¾ãã ãã以å¤ã®å ´åã¯ãæ¬¡ã®æé ã«å¾ã£ã¦ãæ´æ°æ¸ã¿ã®å¶ç´ãæ¢ã«ã¢ã¯ãã£ããªã¹ããªã¼ã ã«é©ç¨ãã¾ãã
buildConstraints()
ããé³å£°ãã©ã㯠(audioConstraints
) ããã³æ åãã©ã㯠(videoConstraints
) ã®æ´æ°ããã MediaTrackConstraints
ãªãã¸ã§ã¯ããæ§ç¯ããããã«å¼ã³åºãã¾ããMediaStreamTrack.applyConstraints()
ããæ°ãã videoConstraints
ãé©ç¨ããããã«æ åãã©ãã¯ï¼åå¨ããå ´åï¼ã§å¼ã³åºãã¾ãã ãããæåããããæ åãã©ãã¯ã®ç¾å¨ã®è¨å®ããã¯ã¹ã®å
容ããgetSettings()
ã¡ã½ãããå¼ã³åºããçµæã«åºã¥ãã¦æ´æ°ãã¾ããapplyConstraints()
ãé³å£°ãã©ãã¯ï¼åå¨ããå ´åï¼ã§å¼ã³åºãã¾ãã ãããæåããããé³å£°ãã©ãã¯ã®ç¾å¨ã®è¨å®ããã¯ã¹ã®å
容ããgetSettings()
ã¡ã½ãããå¼ã³åºããçµæã«åºã¥ãã¦æ´æ°ãããhandleError()
ã使ç¨ãã¦ã¡ãã»ã¼ã¸ããã°ã«åºåãã¾ããdocument.getElementById("applyButton").addEventListener(
"click",
() => {
if (!videoTrack && !audioTrack) {
startVideo();
} else {
buildConstraints();
const prettyJson = (obj) => JSON.stringify(obj, null, 2);
if (videoTrack) {
videoTrack
.applyConstraints(videoConstraints)
.then(() => {
videoSettingsText.value = prettyJson(videoTrack.getSettings());
})
.catch(handleError);
}
if (audioTrack) {
audioTrack
.applyConstraints(audioConstraints)
.then(() => {
audioSettingsText.value = prettyJson(audioTrack.getSettings());
})
.catch(handleError);
}
}
},
false,
);
忢ãã¿ã³ã®å¦ç
次ã«ã[忢] ãã¿ã³ã®ãã³ãã©ã¼ãè¨å®ãã¾ãã
document.getElementById("stopButton").addEventListener("click", () => {
if (videoTrack) {
videoTrack.stop();
}
if (audioTrack) {
audioTrack.stop();
}
videoTrack = audioTrack = null;
videoElement.srcObject = null;
});
ããã¯åã«ã¢ã¯ãã£ããªãã©ãã¯ã忢ããvideoTrack
夿°ã¨ audioTrack
夿°ã null
ã«è¨å®ãã¦ãããããªããªã£ããã¨ããããããã«ããHTMLMediaElement.srcObject
ã null
ã«è¨å®ã㦠<video>
è¦ç´ ããã¹ããªã¼ã ãåãé¤ãã¾ãã
ãã®ã³ã¼ãã¯ãããããã®å¶ç´ç·¨éããã¯ã¹ããã©ã¼ã«ã¹ããã¦ããã¨ãã« Tab ãã¼ã§ 2 ã¤ã®ã¹ãã¼ã¹æåãæ¿å
¥ãããã¨ã«ããã<textarea>
è¦ç´ ã« Tab ã®åç´ãªãµãã¼ãã追å ãã¾ãã
function keyDownHandler(event) {
if (event.key === "Tab") {
const elem = event.target;
const str = elem.value;
const position = elem.selectionStart;
const beforeTab = str.substring(0, position);
const afterTab = str.substring(position, str.length);
const newStr = `${beforeTab} ${afterTab}`;
elem.value = newStr;
elem.selectionStart = elem.selectionEnd = position + 2;
event.preventDefault();
}
}
videoConstraintEditor.addEventListener("keydown", keyDownHandler, false);
audioConstraintEditor.addEventListener("keydown", keyDownHandler, false);
ãã©ã¦ã¶ã¼ããµãã¼ãããå¶ç´å¯è½ãªããããã£ã®è¡¨ç¤º
ããºã«ã®æå¾ã®éè¦ãªé¨åãã¦ã¼ã¶ã¼ã®åç
§ç¨ã«ããã©ã¦ã¶ã¼ããµãã¼ãããå¶ç´å¯è½ãªããããã£ã®ãªã¹ãã表示ããã³ã¼ãã§ãã åããããã£ã¯ãã¦ã¼ã¶ã¼ã®å©ä¾¿æ§ã®ããã« MDN ã®ããã¥ã¡ã³ãã¸ã®ãªã³ã¯ã§ãã ãã®ã³ã¼ãã®åä½ã®è©³ç´°ã«ã¤ãã¦ã¯ãMediaDevices.getSupportedConstraints()
ã®ä¾ãåç
§ãã¦ãã ããã
ã¡ã¢: ãã¡ããããã®ãªã¹ãã«ã¯éæ¨æºã®ããããã£ãå«ã¾ãã¦ããå ´åãããã¾ãã ãã®å ´åããã®ããã¥ã¡ã³ãã®ãªã³ã¯ã¯ãã¾ãå½¹ã«ç«ããªãã§ãããã
const supportedConstraints = navigator.mediaDevices.getSupportedConstraints();
for (const constraint in supportedConstraints) {
if (Object.hasOwn(supportedConstraints, constraint)) {
const elem = document.createElement("li");
elem.innerHTML = `<code><a href='https://developer.mozilla.org/docs/Web/API/MediaTrackSupportedConstraints/${constraint}' target='_blank'>${constraint}</a></code>`;
supportedConstraintList.appendChild(elem);
}
}
ã¨ã©ã¼å¦ç
ã¾ããããã¤ãã®ç°¡åãªã¨ã©ã¼å¦çã³ã¼ããããã¾ãã handleError()
ã¯å¤±æãããããã¹ãå¦çããããã«å¼ã³åºãããlog()
颿°ã¯åç»ã®ä¸ã®ç¹å¥ãªãã®ã³ã° <div>
ããã¯ã¹ã«ã¨ã©ã¼ã¡ãã»ã¼ã¸ã追å ãã¾ãã
function log(msg) {
logElement.innerHTML += `${msg}<br>`;
}
function handleError(reason) {
log(
`Error <code>${reason.name}</code> in constraint <code>${reason.constraint}</code>: ${reason.message}`,
);
}
çµæ
ããã§ãå®éã®å®å ¨ãªä¾ãè¦ããã¨ãã§ãã¾ãã
仿§æ¸ ãã©ã¦ã¶ã¼ã®äºææ§ é¢é£æ å ±RetroSearch is an open source project built by @garambo | Open a GitHub Issue
Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo
HTML:
3.2
| Encoding:
UTF-8
| Version:
0.7.4