用例:通过从下拉列表中进行选择来更改可用的视频src。视频也在播放。
我想更改navigator.mediaDevices.getUserMedia启动的正在进行的视频流的视频源。我尝试过,关闭现有曲目,使srcObject为null,然后通过将新的设备ID传递给约束来重新启动它。
JS-
$(document).ready(function() {
var videoDeviceList = [];
var selectedDeviceId = "";
if (!navigator.mediaDevices.enumerateDevices) {
console.log("enumerateDevices() not supported.");
} else {
// List cameras and microphones.
navigator.mediaDevices.enumerateDevices()
.then((devices) => {
devices.forEach((device) => {
if (device.kind === 'videoinput') {
selectedDeviceId = selectedDeviceId === "" ? device.deviceId : selectedDeviceId;
videoDeviceList.push({
deviceId: device.deviceId,
deviceLabel: device.label
});
}
});
videoDeviceList.forEach((item) => {
$("#videoList").append("<option id='" + item.deviceId + "'>" + item.deviceLabel + "</option>");
});
})
.catch((err) => {
console.error(`${err.name}: ${err.message}`);
});
}
$("#btn").click(function() {
$(this).attr("disabled", true);
startOrUpdateCameraFeed();
});
$('#videoList').change(function() {
selectedDeviceId = $(this).find('option:selected').attr('id');
console.log("selectedDeviceId: ", selectedDeviceId);
startOrUpdateCameraFeed();
});
function startOrUpdateCameraFeed() {
const video = document.getElementById('video');
// to shut all the open or running video streams
if (window.videoStream !== null && window.videoStream !== undefined && window.videoStream.length > 0 &&
video) {
window.videoStream.forEach((stream) => {
if (stream) {
if ('getTracks' in stream && stream.getTracks().length > 0) {
stream.getTracks().forEach((track) => stopTrack(track));
}
if ('getVideoTracks' in stream && stream.getVideoTracks().length > 0) {
stream.getVideoTracks().forEach((track) => stopTrack(track));
}
if ('getAudioTracks' in stream && stream.getAudioTracks().length > 0) {
stream.getAudioTracks().forEach((track) => stopTrack(track));
}
}
});
window.videoStream = [];
video.srcObject = null;
}
// start a new feed with changed camera device id
var constraints = {
deviceId: {
exact: selectedDeviceId
}
};
console.log("constraints: ", constraints);
navigator.mediaDevices
.getUserMedia({
video: true,
video: {
width: {
ideal: 4096,
max: 4096
},
height: {
ideal: 2160,
max: 2160
},
deviceId: constraints,
}
}).then(function(selfStream) {
if (window.videoStream === null || window.videoStream === undefined) {
window.videoStream = [];
}
if (video) {
console.log('called video: ', window.videoStream);
video.srcObject = selfStream;
window.videoStream.push(selfStream);
}
})
.catch(function(err0r) {
console.log('Something went wrong regular before video!', err0r);
});
}
function stopTrack (track){
if (track && 'stop' in track) {
track.stop();
}
};
});
HTML&;CSS
<b>Please give permissions for the site to view the camera list. </b><br/><br/>
Change the camera source:
<select id="videoList">
<option disabled>Select</option>
</select>
<div id="videoContainer">
<video id="video" height="100%" width="100%" autoplay></video>
</div>
<button id="btn">
Start initial feed
</button>
video {
height: 100%;
width:100%;
border: 1px solid red;
}
#videoContainer {
height: 150px;
width: 250px;
}
请查看问题的小提琴链接。https://jsfiddle.net/jivansupe/576qjcn9/1/
视频元素显示新的设备id,但源不会更改。提前谢谢。
我在传递新设备ID时犯了一个错误。
修复:
var constraints = {
exact: selectedDeviceId
};
更新代码:
$(document).ready(function() {
var videoDeviceList = [];
var selectedDeviceId = "";
if (!navigator.mediaDevices.enumerateDevices) {
console.log("enumerateDevices() not supported.");
} else {
// List cameras and microphones.
navigator.mediaDevices.enumerateDevices()
.then((devices) => {
devices.forEach((device) => {
if (device.kind === 'videoinput') {
selectedDeviceId = selectedDeviceId === "" ? device.deviceId : selectedDeviceId;
videoDeviceList.push({
deviceId: device.deviceId,
deviceLabel: device.label
});
}
});
videoDeviceList.forEach((item) => {
$("#videoList").append("<option id='" + item.deviceId + "'>" + item.deviceLabel + "</option>");
});
})
.catch((err) => {
console.error(`${err.name}: ${err.message}`);
});
}
$("#btn").click(function() {
$(this).attr("disabled", true);
startOrUpdateCameraFeed();
});
$('#videoList').change(function() {
selectedDeviceId = $(this).find('option:selected').attr('id');
console.log("selectedDeviceId: ", selectedDeviceId);
startOrUpdateCameraFeed();
});
function startOrUpdateCameraFeed() {
const video = document.getElementById('video');
// to shut all the open or running video streams
if (window.videoStream !== null && window.videoStream !== undefined && window.videoStream.length > 0 &&
video) {
window.videoStream.forEach((stream) => {
if (stream) {
if ('getTracks' in stream && stream.getTracks().length > 0) {
stream.getTracks().forEach((track) => stopTrack(track));
}
if ('getVideoTracks' in stream && stream.getVideoTracks().length > 0) {
stream.getVideoTracks().forEach((track) => stopTrack(track));
}
if ('getAudioTracks' in stream && stream.getAudioTracks().length > 0) {
stream.getAudioTracks().forEach((track) => stopTrack(track));
}
}
});
window.videoStream = [];
video.srcObject = null;
}
// start a new feed with changed camera device id
// BELOW IS THE CODE CHANGE
var constraints = {
exact: selectedDeviceId
};
console.log("constraints: ", constraints);
navigator.mediaDevices
.getUserMedia({
video: true,
video: {
width: {
ideal: 4096,
max: 4096
},
height: {
ideal: 2160,
max: 2160
},
deviceId: constraints,
}
}).then(function(selfStream) {
if (window.videoStream === null || window.videoStream === undefined) {
window.videoStream = [];
}
if (video) {
console.log('called video: ', window.videoStream);
video.srcObject = selfStream;
window.videoStream.push(selfStream);
}
})
.catch(function(err0r) {
console.log('Something went wrong regular before video!', err0r);
});
}
function stopTrack (track){
if (track && 'stop' in track) {
track.stop();
}
};
});
谢谢。