2012-03-02 114 views
5

我正在開發一個網絡應用程序。在網頁中訪問網絡攝像頭

在我的訪客註冊頁面我需要訪問網絡攝像頭爲客人拍照。

我拍攝的圖像可以存儲在指定的位置。

這將是執行此操作的最佳方式。

歡迎使用java,JSP,html,java腳本或任何其他方法。

+0

是服務器和客戶端在同一臺機器? – Quentin 2012-03-02 13:05:33

+2

看看這個簽名的Java小程序。我爲一個topaz簽名板做了這個工作,它工作得很好,我甚至能夠得到簽名的applet來安裝簽名板的驅動程序,所以他們只需插入它並使用applet訪問該頁面即可。 – Zoidberg 2012-03-02 13:07:20

+0

該項目將被託管在一臺服務器上,以便它可以在辦公室的局域網中使用,因此它將成爲不同的系統。 – 2012-03-02 13:08:27

回答

4

的jQuery插件攝像頭的辛勤工作爲您提供:

http://www.xarg.org/project/jquery-webcam-plugin/

+0

如果這樣做,我會說這是理想的解決方案,所需的工作量最少,做得很好。 – Zoidberg 2012-03-02 13:15:16

+0

我現在(辦公室)沒有攝像頭,經過測試後只有一個攝像頭,我可以評論它,對不起。 – 2012-03-02 13:26:20

+1

我用一臺筆記本電腦測試了那個頁面。在第一個窗口顯示來自我的相機的輸入,但是當我點擊拍照時,它沒有顯示任何動作。 – 2012-03-02 13:41:55

4

回答自己的問題,因爲沒有使用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 ... 
} 

截屏

Screen shot

選項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; 
     }); 
    } 
} 

屏幕截圖

enter image description here

選項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); 
}