我正在開發一個網絡應用程序。在網頁中訪問網絡攝像頭
在我的訪客註冊頁面我需要訪問網絡攝像頭爲客人拍照。
我拍攝的圖像可以存儲在指定的位置。
這將是執行此操作的最佳方式。
歡迎使用java,JSP,html,java腳本或任何其他方法。
我正在開發一個網絡應用程序。在網頁中訪問網絡攝像頭
在我的訪客註冊頁面我需要訪問網絡攝像頭爲客人拍照。
我拍攝的圖像可以存儲在指定的位置。
這將是執行此操作的最佳方式。
歡迎使用java,JSP,html,java腳本或任何其他方法。
的jQuery插件攝像頭的辛勤工作爲您提供:
如果這樣做,我會說這是理想的解決方案,所需的工作量最少,做得很好。 – Zoidberg 2012-03-02 13:15:16
我現在(辦公室)沒有攝像頭,經過測試後只有一個攝像頭,我可以評論它,對不起。 – 2012-03-02 13:26:20
我用一臺筆記本電腦測試了那個頁面。在第一個窗口顯示來自我的相機的輸入,但是當我點擊拍照時,它沒有顯示任何動作。 – 2012-03-02 13:41:55
回答自己的問題,因爲沒有使用HTML5提供一個更好的辦法。
選項1,從系統
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>
訪問默認的攝像頭腳本
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 ...
}
截屏
選項2,提供系統中可用攝像機的列表,並讓用戶選擇相機。
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>
腳本
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;
});
}
}
屏幕截圖
選項3,讓用戶選擇音頻和視頻源和音頻輸出
在選項2中,用戶可以選擇任何特定的攝像機。最重要的是,如果用戶還想選擇音頻源和音頻輸出源,請修改上面的代碼,修改如下。
HTML
audioInputSelect
<br/>
<select id="audioInputSelect"></select>
<br/>
audioOutputSelect
<select id="audioOutputSelect"></select>
腳本
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);
}
是服務器和客戶端在同一臺機器? – Quentin 2012-03-02 13:05:33
看看這個簽名的Java小程序。我爲一個topaz簽名板做了這個工作,它工作得很好,我甚至能夠得到簽名的applet來安裝簽名板的驅動程序,所以他們只需插入它並使用applet訪問該頁面即可。 – Zoidberg 2012-03-02 13:07:20
該項目將被託管在一臺服務器上,以便它可以在辦公室的局域網中使用,因此它將成爲不同的系統。 – 2012-03-02 13:08:27