前面我們能夠打開攝像頭。getUserMedia()
時會傳入參數,在參數里我們可以指定寬高信息。通過寬高參數控制輸出的視頻分辨率。
html
在頁面上擺放一些元素,下面是主要部分
<div id="container">
<div id="buttons">
<button id="stop">停止</button>
<button id="b320">320x240</button>
<button id="b240-320">240x320</button>
<button id="b640">640x480</button>
<button id="b1280">1280x720</button>
<button id="b1920">1920x1080</button>
<button id="b2048">2048x1152</button>
</div>
<div id="videoblock" style="display: none">
<p id="dimensions" style="height: 1em;"></p>
<video playsinline autoplay style="background: none;height: auto;width: auto;"></video>
<div id="width">
<label>Width <span></span>px:</label>
<input type="range" min="0" max="7680" value="0">
</div>
<input id="isFullWidth" type="checkbox">視頻寬度100%<br>
<input id="aspectlock" type="checkbox">鎖定寬高比<br>
</div>
<p id="msg" style="display: none;"></p>
</div>
<script src="../js/adapter-latest.js" async></script> <!-- 使用本地的適配器 -->
<script src="js/main.js" async></script>
button
一些按鈕用來選擇分辨率videoblock
用來顯示視頻,默認隱藏dimensions
用來現實視頻的一些信息video
寬高先設置為auto#width input
滑動選擇視頻的寬度isFullWidth
讓video寬度為100%msg
顯示錯誤信息
js
拿到一些元素
const dimensionsInfo = document.querySelector('#dimensions');
const video = document.querySelector('video');
let stream;
const videoblock = document.querySelector('#videoblock'); // 視頻區域
const messagebox = document.querySelector('#msg');
const widthInput = document.querySelector('div#width input');
const widthOutput = document.querySelector('div#width span');
const aspectLock = document.querySelector('#aspectlock');
const fullWidSetting = document.querySelector('#isFullWidth');
啟動視頻
先把拿到流的處理方法寫出來
function gotStream(mediaStream) {
stream = window.stream = mediaStream; // 給控制台
video.srcObject = mediaStream;
messagebox.style.display = 'none';
videoblock.style.display = 'block';
const track = mediaStream.getVideoTracks()[0];
const constraints = track.getConstraints();
console.log('當前constraints: ' + JSON.stringify(constraints));
if (constraints && constraints.width && constraints.width.exact) {
widthInput.value = constraints.width.exact;
widthOutput.textContent = constraints.width.exact;
} else if (constraints && constraints.width && constraints.width.min) {
widthInput.value = constraints.width.min;
widthOutput.textContent = constraints.width.min;
}
}
拿到視頻流后,track.getConstraints()
獲取信息,顯示出當前信息並修改ui。
以按鈕320為例
document.querySelector('#b320').onclick = () => {
const c320 = {
video: { width: { exact: 320 }, height: { exact: 240 } }
};
startPlay(c320);
};
function startPlay(constraints) {
stopStream();
clearMsg();
videoblock.style.display = 'none';
navigator.mediaDevices.getUserMedia(constraints)
.then(gotStream)
.catch(e => {
showErrMsg('getUserMedia報錯 ' + e, JSON.stringify(constraints));
});
}
function stopStream() {
if (stream) {
stream.getTracks().forEach(track => {
track.stop();
});
}
}
- 定義配置
c320
,設定寬為320,高偉240 - 先把視頻停下來
- 調用
getUserMedia
並把參數配置傳進去
還可以監聽video的變化
let currentWidth = 0;
let currentHeight = 0;
// 顯示視頻尺寸信息
function displayVideoDimensions(whereSeen) {
if (video.videoWidth) {
dimensionsInfo.innerText = '實際video尺寸: ' + video.videoWidth +
'x' + video.videoHeight + 'px.';
if (currentWidth !== video.videoWidth ||
currentHeight !== video.videoHeight) {
console.log(whereSeen + ': ' + dimensionsInfo.innerText);
currentWidth = video.videoWidth;
currentHeight = video.videoHeight;
}
} else {
dimensionsInfo.innerText = '拿不到video的寬度';
}
}
// 載入meta信息
video.onloadedmetadata = () => {
displayVideoDimensions('loadedmetadata');
};
// 修改了尺寸
video.onresize = () => {
displayVideoDimensions('resize');
};
載入信息或者尺寸改變的時候顯示出來。
定義了多種常見的分辨率
document.querySelector('#b640').onclick = () => {
const c640 = {
video: { width: { exact: 640 }, height: { exact: 480 } }
};
startPlay(c640);
};
document.querySelector('#b1280').onclick = () => {
const c1280 = {
video: { width: { exact: 1280 }, height: { exact: 720 } }
};
startPlay(c1280);
};
滑動調整
我們放置了一個input
,type="range"
,它可以左右滑動。滑動的時候我們改變視頻設置的寬度。寬度信息也顯示在界面上。
widthInput.onchange = onConstraintChange;
function onConstraintChange(e) {
widthOutput.textContent = e.target.value;
const track = window.stream.getVideoTracks()[0];
let constraints;
if (aspectLock.checked) {
constraints = {
width: { exact: e.target.value },
aspectRatio: {
exact: video.videoWidth / video.videoHeight
}
};
} else {
constraints = { width: { exact: e.target.value } };
}
clearMsg();
console.log('使用配置 ' + JSON.stringify(constraints));
track.applyConstraints(constraints)
.then(() => {
console.log('配置成功');
displayVideoDimensions('applyConstraints');
})
.catch(err => {
showErrMsg('配置失敗 ', err.name);
});
}
改變的寬度寫在constraints
里,注意需要指定exact
參數。
window.stream.getVideoTracks()[0]
獲取到track
(視頻軌)。
調用track.applyConstraints(constraints)
讓修改后的參數生效。同樣這里可以監聽配置是否成功。
點不同的按鈕,可以看到視頻的尺寸不同。
在電腦顯示器上測試,選擇尺寸過大時,會報錯OverconstrainedError。
小結
本次示例也是getUserMedia()
方法的使用。前面打開攝像頭我們只指定了video: true
。在這個示例里我們指定了寬高信息。並以此控制輸出的視頻分辨率。
視頻正在顯示的時候,也可以用track.applyConstraints
方法來修改視頻的分辨率。
效果
網頁效果預覽
原文鏈接WebRTC視頻分辨率設置