您好,登錄后才能下訂單哦!
利用JavaScript怎么調用網絡攝像頭?相信很多沒有經驗的人對此束手無策,為此本文總結了問題出現的原因和解決方法,通過這篇文章希望你能解決這個問題。
Java是一門面向對象編程語言,可以編寫桌面應用程序、Web應用程序、分布式系統和嵌入式系統應用程序。
基礎代碼
navigator.mediaDevices.getUserMedia({ audio: false, video: true }).then(async (stream) => { let video = document.getElementById('#video') // 兼容性監測 if( 'srcObject' in video ) { video.srcObject = stream } else { // 在支持srcObject的瀏覽器上,不再支持使用這種方式 video.src = URL.createObjectURL(stream) } await video.play() })
從caniuse的兼容性來看,整體兼容性一般,IE系列瀏覽器完全不支持,iOS不僅需要iOS 11以上的版本,而且在APP的嵌入式頁面也無法通過api進行調用。
瀏覽器控制臺提示mediaDevices.getUserMedia is not a function
由于受瀏覽器的限制,navigator.mediaDevices.getUserMedia在https協議下是可以正常使用的,而在http協議下只允許localhost/127.0.0.1這兩個域名訪問,因此在開發時應做好容災處理,上線時則需要確認生產環境是否處于https協議下。
let mediaDevices = navigator.mediaDevices || null if( mediaDevices === null ) { console.warn(`請確定是否處于https協議環境下`) return } mediaDevices.getUserMedia({ audio: false, video: true }).then(async (stream) => {})
獲取攝像頭的硬件參數
我在項目開發中需要用到的硬件參數主要有兩種:品牌,分辨率。獲取攝像頭的品牌名稱相對來說比較簡單,可直接通過mediaDevices.enumerateDevices()獲取電腦上可使用的外設列表,通過kind字段過濾出攝像頭。
if (!navigator.mediaDevices || !navigator.mediaDevices.enumerateDevices) { console.log("瀏覽器不支持enumerateDevices屬性") return } navigator.mediaDevices.enumerateDevices().then((devices) => { let devicesList = devices.filter((device) => device.kind === 'videoinput') // devicesList -> [{ kind: 'videoinput', name: 'FaceTime HD Camera (Built-in)', deviceId: xxx }] // 在devicesList獲取到的deviceId可以用于切換攝像頭 // 具體方法:mediaDevices.getUserMedia({ audio: false, video: { deviceId } }) })
分辨率則不能直接通過官方的api獲取到,從MDN上查到的理由是為了保護用戶的個人隱私,而分辨率就在保護的范疇內。(個人非常好奇分辨率為啥是隱私?)
MDN原文(鏈接):
由于隱私保護的原因,無法訪問用戶的攝像頭和麥克風信息
但也并不是完全無法獲取到,由于可以通過video標簽在網頁上播放攝像頭中所錄取到的內容,而video標簽會默認將大小設置為與攝像頭相同的大小,因此通過獲取video的大小來獲取攝像頭的分辨率。
經過測試,獲取到的值不受樣式的影響,所以可以通過樣式控制video的大小,但是不會影響到分辨率。
let mediaDevices = navigator.mediaDevices || null if( mediaDevices === null ) { console.warn(`請確定是否處于https協議環境下`) return } mediaDevices.getUserMedia({ audio: false, video: true }).then(async (stream) => { let video = document.getElementById('#video') video.srcObject = stream await video.play() // 1280,720 console.log(video.videoWidth, video.videoHeight) })
無攝像頭/無使用權限等錯誤的處理
getUserMedia本身集成了幾個比較常見的錯誤提示,比如常見的無攝像頭、無使用權限等,通過catch能處理大部分類似的錯誤。
let mediaDevices = navigator.mediaDevices || null if( mediaDevices === null ) { console.warn(`請確定是否處于https協議環境下`) return } mediaDevices.getUserMedia({ audio: false, video: true }).then(async (stream) => { let video = document.getElementById('#video') video.srcObject = stream await video.play() }).catch((error) => { let message = error.message || error, response = { 'permission denied': '瀏覽器禁止本頁面使用攝像頭,請開啟相關的權限', 'requested device not found': '未檢測到攝像頭' } alert(response[ message.toLowerCase() ] || '未知錯誤') })
攝像頭拔出檢查
手機端由于攝像頭是手機自帶的,所以一般不需要對攝像頭是否拔出進行檢查。但在PC上有拔出攝像頭數據線的情況發生,這種時候就需要對攝像頭的狀態進行監控。
最開始想到的是,getUserMedia在攝像頭拔出時可能會通過catch報錯。然而經過多次的實驗,getUserMedia在攝像頭拔出時,不會響應找不到攝像頭的錯誤,想通過catch直接監控這種方法并不可行。
在幾乎沒有思路的時候,在getUserMedia文檔上看到了這么一句話:
getUserMedia返回一個 Promise , 這個Promise成功后的回調函數帶一個 MediaStream 對象作為其參數。
MediaStream是接收多媒體(包括音頻、視頻)內容流的一個對象,在谷歌瀏覽器(其他瀏覽器未測試)的控制臺上打印之后,其屬性值如下:
id是MediaStream對象的唯一標識符,active是當前內容流是否處于活動狀態,下面幾個字段則是谷歌瀏覽器提供的鉤子。
在攝像頭拔出的一瞬間,active會從true變更為false,同時觸發oninactive鉤子,有了狀態監聽之后事情就簡單了許多。代碼經過測試后發現,對用戶變更攝像頭權限也有效。
// 判斷攝像頭是否在線 let cameraIsOnline = false const loadWebCamera = () => { let mediaDevices = navigator.mediaDevices || null if( mediaDevices === null ) { console.warn(`請確定是否處于https協議環境下`) return } mediaDevices.getUserMedia({ audio: false, video: true }).then(async (stream) => { let video = document.getElementById('#video') video.srcObject = stream // 兼容性處理 if( stream.oninactive === null ) { // 監聽流中斷,流中斷后將重新進行調用自身進行狀態監測 stream.oninactive = () => loadWebCamera() } await video.play() cameraIsOnline = true }).catch((error) => { let message = error.message || error, response = { 'permission denied': '瀏覽器禁止本頁面使用攝像頭,請開啟相關的權限', 'requested device not found': '未檢測到攝像頭', 'could not start video source': '無法訪問到攝像頭,請重新插拔后重試' } cameraIsOnline = false alert(response[ message.toLowerCase() ] || '未知錯誤') }) }
看完上述內容,你們掌握利用JavaScript怎么調用網絡攝像頭的方法了嗎?如果還想學到更多技能或想了解更多相關內容,歡迎關注億速云行業資訊頻道,感謝各位的閱讀!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。