javascript
使用基于 WebRTC 的 JavaScript API 在浏览器环境里调用本机摄像头
HTML5,JavaScript 和現代瀏覽器這套三駕馬車的組合,使得傳統的 Web 應用較之過去能實現更多更豐富的同用戶交互的功能。攝像頭如今已成為智能手機的標配,前端 Web 應用也出現了越來越多的打開本機攝像頭,掃描條形碼,二維碼等需求。
本文介紹兩種通過 JavaScript 實現在瀏覽器環境里調用設備攝像頭的開發技術。
方法1:基于現代瀏覽器支持的 WebRTC API 實現
我采用該思路實現了一個簡單的 Web 頁面,全部源代碼維護在如下的 Github 代碼倉庫里:
https://github.com/wangzixi-diablo/WebAppCollection/tree/main/WebContent/camera
首先看看運行該 Web 應用的效果。
通過筆記本電腦訪問,瀏覽器會彈出窗口詢問用戶是否允許該應用訪問設備上的攝像頭:
點擊允許之后,應用下方區域就會實時顯示我的攝像頭正對著的區域的圖像:
點擊“拍照”按鈕后,攝像頭顯示的圖像就會被固化在該按鈕下方,并且以圖片的方式自動保存到本地。
在我的三星手機上訪問該鏈接,首先一樣要授權該應用使用攝像頭:
對準我電腦面前一個異形手辦進行拍照:
自動生成一張圖片并保存到手機上:
幾個關鍵的實現點說明:
(1) JavaScript 之所以通過瀏覽器能夠識別到設備可用攝像頭(包括可用的音頻輸入和輸出設備),是因為現代瀏覽器支持的一組名為 WebRTC(Web Real Time Communication,網頁即時通信)的 API. 這個 API 能幫助 Web 應用開發人員通過簡單的 JavaScript 編程就能實現功能豐富的實時多媒體應用,而無需學習多媒體的數字信號處理知識。Web 應用的使用者也無需下載額外的插件。
用 JavaScript 進行設備可用多媒體設備的檢測,核心代碼如下:
navigator.mediaDevices.enumerateDevices().then(gotDevices).catch(handleError);這句代碼前半段 navigator.mediaDevices.enumerateDevices() 是瀏覽器支持的原生 API,這是一個異步調用,返回一個 promise 對象:
等到該異步調用的結果可供應用程序使用之后,我們通過鏈式調用 then 傳入的回調函數 gotDevices 被觸發,輸入的參數就是 navigator.mediaDevices.enumerateDevices() 調用的返回值。在調試器里看看這個返回值的明細:
從調試器里得知 enumerateDevices 這個函數返回了我筆記本電腦上一系列可用的音視頻設備,這些信息和我通過操作系統里看到的設備信息一致:
(2) 我的 html 頁面里定義了一個 HTML5 原生支持的 video 標簽, 用于顯示通過設備攝像頭觀察到的圖像。
但是我們還需要把設備攝像頭同這個 video 標簽關聯起來。方式是給這個標簽的 dom 對象的srcObject 屬性賦一個 MediaStream (媒體數據流)對象。
這個 MediaStream 對象從哪里來?同理,通過鏈式調用navigator.mediaDevices.getUserMedia(constraints) 得到:
(3) 點擊拍照按鈕后,自動生成圖片并下載到本地的功能在按鈕的 click 事件響應函數里實現。首先調用 canvas 標簽對應 Context 的 API drawImage 將顯示攝像頭內容的 video 標簽當前顯示的內容繪制到 canvas 標簽頁上,然后用此內容生成格式為 jpeg 的圖片,下載到本地。
方法2:使用 SAP UI5 自定義控件
這種方式本質上同方法一異曲同工,只不是封裝性更好,將方法1 描述的步驟,封裝成一個 SAP UI5 可重用控件,方便使用 SAP UI5 這個前端框架進行開發的前端程序員直接使用。
關于 SAP UI5 這個企業級前端開發框架的介紹,參考筆者之前的 InfoQ 文章:面向企業級前端應用的開發框架 UI5 的發展簡史介紹。
先回憶方法1 技術實現的要點:
(1) 在 web 應用的 HTML 頁面里定義 HTML5 用于顯示視頻的原生標簽: video
(2) 使用 WebRTC 的 API,獲取設備攝像頭對應的 MediaStream 對象,再將這個對象實例賦給 video 標簽對應的 DOM對象的 srcObject 屬性.
以上兩步實現之后,我們通過攝像頭觀察到的視頻圖像,就能實時顯示在 web 應用的 video 標簽里了。至于將某一時間點里 video 標簽里顯示的視頻內容保存成圖片并下載,其對應的 JavaScript 代碼對于所有的前端框架并沒有太大的不同,本文略過。
因此,使用 SAP UI5 開發,我們無非得重復以上兩個步驟。
SAP UI5 應用最常用的視圖格式為 XML 視圖。我們直接在 XML 視圖里加上 HTML 原生的 video 或者 div 標簽,會發生什么?
404 錯誤,UI5 框架加載不了 div.js 這個腳本文件。
筆者以前還在 SAP 成都研究院 CRM Fiori 應用開發團隊工作時,曾經寫過一個 SAP UI5 框架代碼的學習教程,里面有兩篇文章,詳細介紹了 SAP UI5 XML 視圖運行時的渲染原理:
簡單地說,就是 SAP UI5 里有個 XMLTemplateProcessor.js 的實現,運行時當 XML 視圖的源文件被瀏覽器加載解析成 DOM 后,它會對 DOM 樹進行深度優先遍歷,對遇到的每一個 UI5 標簽,加載其實現文件(如果是在 UI5 調試模式下),然后創建這個標簽對應的實例。
回到本文的例子,我寫到 SAP UI5 XML 視圖里的 div 標簽被當成了一個 SAP UI5 XML 的控件,所以 UI5 框架自動去找這個根本不存在的 div 控件的實現文件,當然找不到了。
知道問題出在哪里,解決的思路自然就有了。自己把 HTML5 原生標簽 video 封裝成 UI5 控件不就行了?
SAP UI5 開源社區里已經有一個封裝好的 library:
https://github.com/tiagobalmeida/openui5-camera
先看這個例子在筆記本電腦上訪問的效果:
點擊頁面上顯示的攝像頭拍攝的內容,能自動保存成一張圖片。
手機上的顯示效果:
然后再來看這個 library 的實現原理。
這個 camera 自定義 UI5 控件實現的層級結果如下:
SAP UI5 自定義控件的實現包括三個 JavaScript 文件:
-
library.js:定義這個控件抬頭級別的控制信息,比如名稱,版本號,依賴等。
-
Camera.js:實現了將 WebRTC API 獲得的 MediaStream 對象實例綁定到控件封裝的 video 元素上的步驟。
- CameraRender.js:負責將這個自定義控件在XML視圖里的標簽 Camera 渲染成原生的video和canvas標簽的組合。
SAP UI5 的每一個控件都有一個與之對應的渲染類,用于完成 XML 視圖里 UI5 的標簽到 HTML5 原生標簽的轉換:
如何使用這個自定義控件呢?
在 XML 視圖里使用如下定義即可:
<cam:Cameraid="idCamera"width="800"height="600"snapshot=".onSnapshot" />總結
本文介紹了基于 WebRTC 技術使用 JavaScript 調用本機攝像頭的解決方案。WebRTC 可以為基于開放標準的應用程序添加實時通信功能,支持在對等點之間發送視頻、語音和通用數據,允許開發人員構建強大的語音和視頻通信解決方案。
WebRTC 可用于所有現代瀏覽器以及所有主流操作系統的本地客戶端。WebRTC 背后的技術是作為一個開放的 Web 標準實現,并且可以在所有主流瀏覽器中作為常規 JavaScript API 使用。
本文兩個例子在 Windows 10 操作系統的 Chrome 瀏覽器里實現并通過測試。對于原生客戶端,如 Android 和 iOS 應用程序,可以使用提供相同功能的 WebRTC 庫。
希望本文介紹的知識點對大家采取 JavaScript 實現瀏覽器環境里調用本機攝像頭的需求能有所幫助,感謝閱讀。
總結
以上是生活随笔為你收集整理的使用基于 WebRTC 的 JavaScript API 在浏览器环境里调用本机摄像头的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 冯诺依曼结构计算机包括哪五大部分?
- 下一篇: 如何使用 Chrome 开发者工具 Pe