This example demonstrates a request for a MediaStream
with a defined video
source for the constraint.
Please refer to the Basic Publisher Documentation to learn more about the basic setup.
These examples use the WebRTC-based Publisher implementation from the Red5 Pro HTML SDK. However, there is failover support to allow for Flash-base publisher on unsupported browsers.
Allow the User to select from a list of cameras detected by their browser. To access the list of camera devices, use the enumerateDevices
API:
function listDevices (devices) {
var cameras = devices.filter(function (item) {
return item.kind === 'videoinput';
})
var options = cameras.map(function (camera, index) {
return '<option value="' + camera.deviceId + '">' + (camera.label || 'camera ' + index) + '</option>';
});
cameraSelect.innerHTML = options.join(' ');
}
navigator.mediaDevices.enumerateDevices().then(listDevices).catch(onDeviceError);
The camera devices are filtered out from the list returned on enumerateDevices
based on the kind
attribute being of videoinput
value. The list is then provided a a select
element with an event handler assigned.
Upon a change
event, the camera deviceId
is used to assign the video
constraint for the MediaStream
.
Constraints for the audio and video components are defined when accessing a MediaStream
from the browser.
To define a stream with a specific camera device for publishing, update the video
constraint used in requesting a MediaStream
and declare a sourceId
with the selected camera deviceId
.
The following change
event handler is invoked upon User selection of a camera from the select
element populated in the previous section:
var mediaConstraints = {
audio: configuration.useAudio ? configuration.mediaConstraints.audio : false,
video: configuration.useVideo ? configuration.mediaConstraints.video : false,
};
function onCameraSelect () {
if (!configuration.useVideo) {
return;
}
var selection = cameraSelect.value;
if (mediaConstraints.video && typeof mediaConstraints.video !== 'boolean') {
mediaConstraints.video.deviceId = { exact: selection }
delete mediaConstraints.video.frameRate
}
else {
mediaConstraints.video = {
deviceId: { exact: selection }
};
}
updateStatistics(0, 0, 0, 0);
statisticsField.classList.add('hidden');
unpublish()
.then(restart)
.catch(function (error) {
console.error('[Red5ProPublisher] :: Error in unpublishing - ' + error);
restart();
});
publishButton.disabled = false;
}
With the mediaConstraints
object updated with the target camera, the initialization configuration is set to start a new publishing session using the onGetUserMedia
override to ensure proper listing of devices and labels:
var config = Object.assign({},
configuration,
defaultConfiguration,
getAuthenticationParams(),
{
onGetUserMedia: function () {
return new Promise(function (resolve, reject) {
if (targetPublisher && targetPublisher.getMediaStream()) {
targetPublisher.getMediaStream().getTracks().forEach(function(track) {
track.stop();
});
}
var stream;
var constraints = mediaConstraints;
navigator.mediaDevices.getUserMedia(constraints)
.then(function (mediastream) {
stream = mediastream;
return navigator.mediaDevices.enumerateDevices()
})
.then(function (devices) {
listDevices(devices);
stream.getVideoTracks().forEach(function (track) {
cameraSelect.value = track.getSettings().deviceId;
});
resolve(stream);
})
.catch(function (error) {
reject(error);
})
});
}
});
var rtcConfig = Object.assign({}, config, {
protocol: getSocketLocationFromProtocol().protocol,
port: getSocketLocationFromProtocol().port,
streamName: config.stream1
});
return new red5prosdk.RTCPublisher().init(rtcConfig);
More information: Media.getUserMedia from MDN