Odpowiadając na własne pytanie, jak tam jest lepszy sposób za pomocą HTML5 jest dostępny.
Wariant 1, Dostęp do domyślnej kamery z systemu
HTML
Video Tag
<br/>
<div class="camera">
<video id="video">Video stream not available.</video>
<button id="startbutton">Take photo</button>
</div>
<br/>
Canvas
<br/>
<canvas id="canvas"></canvas>
Script
var width = 320;
var height = 0;
var streaming = false;
navigator.mediaDevices.getUserMedia({video: true, audio: false})
.then(function (stream) {
video.srcObject = stream;
video.play();
})
.catch(function (err) {
console.log("An error occured! " + err);
});
video.addEventListener('canplay', function (ev) {
if (!streaming) {
height = video.videoHeight/(video.videoWidth/width);
video.setAttribute('width', width);
video.setAttribute('height', height);
canvas.setAttribute('width', width);
canvas.setAttribute('height', height);
streaming = true;
}
}, false);
startbutton.addEventListener('click', function (ev) {
takepicture();
ev.preventDefault();
}, false);
clearphoto();
function clearphoto() {
var context = canvas.getContext('2d');
context.fillStyle = "#AAA";
context.fillRect(0, 0, canvas.width, canvas.height);
}
function takepicture() {
var context = canvas.getContext('2d');
if (width && height) {
canvas.width = width;
canvas.height = height;
context.drawImage(video, 0, 0, width, height);
var dataURL = canvas.toDataURL("image/jpeg", 0.95);
if (dataURL && dataURL != "data:,") {
var fileName = generateImageName();
uploadimage(dataURL, fileName);
} else {
alert("Image not available");
}
} else {
clearphoto();
}
}
function generateImageName() {
... generate image name logic here ...
return imageName;
}
function uploadimage(dataurl, filename) {
... upload logic here ...
}
zrzut ekranu

Wariant 2 Podać listę dostępnych kamer w systemie i pozwolić użytkownikowi wybrać kamerę.
HTML
<select id="videoSelect"></select>
<button id="startCameraButton">Start Camera</button>
<br/>
Video Tag
<br/>
<div class="camera">
<video id="video">Video stream not available.</video>
<button id="takePictureButton">Take photo</button>
</div>
<br/>
Canvas
<br/>
<canvas id="canvas">
</canvas>
Script
var width = 320;
var height = 0;
var streaming = false;
var localstream = null;
startCameraButton.onclick = start;
takePictureButton.onclick = takepicture;
navigator.mediaDevices.enumerateDevices()
.then(gotDevices)
.catch(function (err) {
console.log("An error occured while getting device list! " + err);
});
function gotDevices(deviceInfos) {
while (videoSelect.firstChild) {
videoSelect.removeChild(videoSelect.firstChild);
}
for (var i = 0; i !== deviceInfos.length; ++i) {
var deviceInfo = deviceInfos[i];
var option = document.createElement('option');
option.value = deviceInfo.deviceId;
if (deviceInfo.kind === 'videoinput') {
option.text = deviceInfo.label || 'Camera ' + (videoSelect.length + 1);
videoSelect.appendChild(option);
}
}
}
function start() {
stopVideo();
clearphoto();
var videoSource = videoSelect.value;
var constraints = {
audio: false,
video: {deviceId: videoSource ? {exact: videoSource} : undefined}
};
navigator.mediaDevices.getUserMedia(constraints).
then(gotStream).then(gotDevices).catch(handleError);
}
function gotStream(stream) {
localstream = stream;
video.srcObject = stream;
video.play();
// Refresh button list in case labels have become available
return navigator.mediaDevices.enumerateDevices();
}
function handleError(error) {
console.log('navigator.getUserMedia error: ', error);
}
video.addEventListener('canplay', function (ev) {
if (!streaming) {
height = video.videoHeight/(video.videoWidth/width);
video.setAttribute('width', width);
video.setAttribute('height', height);
canvas.setAttribute('width', width);
canvas.setAttribute('height', height);
streaming = true;
}
}, false);
clearphoto();
function clearphoto() {
var context = canvas.getContext('2d');
context.fillStyle = "#AAA";
context.fillRect(0, 0, canvas.width, canvas.height);
}
function takepicture() {
var context = canvas.getContext('2d');
if (width && height) {
canvas.width = width;
canvas.height = height;
context.drawImage(video, 0, 0, width, height);
var dataURL = canvas.toDataURL("image/jpeg", 0.95);
if (dataURL && dataURL != "data:,") {
var fileName = generateImageName();
fileName = fileName + ".txt"
uploadimage(dataURL, fileName);
} else {
console.log("Image not available");
}
} else {
clearphoto();
}
}
function generateImageName() {
... generate image name logic here ...
return imageName;
}
function uploadimage(dataurl, filename) {
... upload logic here ...
}
function stopVideo() {
if (localstream) {
localstream.getTracks().forEach(function (track) {
track.stop();
localstream = null;
});
}
}
zrzut ekranu

Wariant 3, niech użytkownik wybierz audio i źródeł wideo i wyjście audio
W wariancie 2, użytkownik może wybrać żadnego konkretnego aparatu. Ponadto, jeśli użytkownik chce wybrać źródło dźwięku i źródło wyjścia audio, zmodyfikuj powyższy kod, wprowadzając poniższe zmiany.
HTML
audioInputSelect
<br/>
<select id="audioInputSelect"></select>
<br/>
audioOutputSelect
<select id="audioOutputSelect"></select>
Script
function gotDevices(deviceInfos) {
while (videoSelect.firstChild) {
videoSelect.removeChild(videoSelect.firstChild);
}
for (var i = 0; i !== deviceInfos.length; ++i) {
var deviceInfo = deviceInfos[i];
var option = document.createElement('option');
option.value = deviceInfo.deviceId;
if (deviceInfo.kind === 'audioinput') {
option.text = deviceInfo.label || 'Microphone ' + (audioInputSelect.length + 1);
audioInputSelect.appendChild(option);
} else if (deviceInfo.kind === 'audiooutput') {
option.text = deviceInfo.label || 'Speaker ' + (audioOutputSelect.length + 1);
audioOutputSelect.appendChild(option);
} else if (deviceInfo.kind === 'videoinput') {
option.text = deviceInfo.label || 'Camera ' + (videoSelect.length + 1);
videoSelect.appendChild(option);
}
}
}
function start() {
stopVideo();
clearphoto();
var audioSource = audioInputSelect.value;
var videoSource = videoSelect.value;
var constraints = {
audio: {deviceId: audioSource ? {exact: audioSource} : undefined},
video: {deviceId: videoSource ? {exact: videoSource} : undefined}
};
navigator.mediaDevices.getUserMedia(constraints).
then(gotStream).then(gotDevices).catch(handleError);
}
Czy serwer i klient ta sama maszyna? – Quentin
Zajrzyj do podpisanego apletu java. Zrobiłem to dla tabliczki z topazami i działało świetnie, mogłem nawet uzyskać podpisany aplet, aby zainstalować sterowniki dla konsoli podpisów, więc wszystko, co musiałem zrobić, to podłączyć i odwiedzić stronę z apletem. – Zoidberg
Projekt będzie hostowany na serwerze, dzięki czemu będzie dostępny w sieci LAN biura, więc będą to różne systemy. –