欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

js實(shí)現(xiàn)調(diào)用網(wǎng)絡(luò)攝像頭及常見(jiàn)錯(cuò)誤處理

 更新時(shí)間:2021年03月07日 10:55:13   作者:飛灰  
這篇文章主要介紹了js實(shí)現(xiàn)調(diào)用網(wǎng)絡(luò)攝像頭及常見(jiàn)錯(cuò)誤處理,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧

最近由于業(yè)務(wù)的原因,需要在Web端頁(yè)面接入調(diào)試各類的網(wǎng)絡(luò)攝像頭,遇到了很多匪夷所思的問(wèn)題(說(shuō)的就是讀得出攝像頭的品牌,讀不出攝像頭的分辨率)。于是整理了這篇文章作為備忘錄,也希望能幫到有類似的小伙伴們。

基礎(chǔ)代碼

navigator.mediaDevices.getUserMedia({ audio: false, video: true }).then(async (stream) => {

  let video = document.getElementById('#video')
 
  // 兼容性監(jiān)測(cè)
  if( 'srcObject' in video ) {
    
    video.srcObject = stream
  } else {
    // 在支持srcObject的瀏覽器上,不再支持使用這種方式
    video.src = URL.createObjectURL(stream)
  }
  
  await video.play()
})

兼容性

caniuse的兼容性來(lái)看,整體兼容性一般,IE系列瀏覽器完全不支持,iOS不僅需要iOS 11以上的版本,而且在APP的嵌入式頁(yè)面也無(wú)法通過(guò)api進(jìn)行調(diào)用。

開(kāi)發(fā)遇到的各種問(wèn)題

瀏覽器控制臺(tái)提示mediaDevices.getUserMedia is not a function

由于受瀏覽器的限制,navigator.mediaDevices.getUserMedia在https協(xié)議下是可以正常使用的,而在http協(xié)議下只允許localhost/127.0.0.1這兩個(gè)域名訪問(wèn),因此在開(kāi)發(fā)時(shí)應(yīng)做好容災(zāi)處理,上線時(shí)則需要確認(rèn)生產(chǎn)環(huán)境是否處于https協(xié)議下。

let mediaDevices = navigator.mediaDevices || null  
if( mediaDevices === null ) {    
  console.warn(`請(qǐng)確定是否處于https協(xié)議環(huán)境下`)
  return 
}  
mediaDevices.getUserMedia({ audio: false, video: true }).then(async (stream) => {})

獲取攝像頭的硬件參數(shù)

我在項(xiàng)目開(kāi)發(fā)中需要用到的硬件參數(shù)主要有兩種:品牌,分辨率。獲取攝像頭的品牌名稱相對(duì)來(lái)說(shuō)比較簡(jiǎn)單,可直接通過(guò)mediaDevices.enumerateDevices()獲取電腦上可使用的外設(shè)列表,通過(guò)kind字段過(guò)濾出攝像頭。

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 } })
})

分辨率則不能直接通過(guò)官方的api獲取到,從MDN上查到的理由是為了保護(hù)用戶的個(gè)人隱私,而分辨率就在保護(hù)的范疇內(nèi)。(個(gè)人非常好奇分辨率為啥是隱私?)

MDN原文(鏈接):

由于隱私保護(hù)的原因,無(wú)法訪問(wèn)用戶的攝像頭和麥克風(fēng)信息

但也并不是完全無(wú)法獲取到,由于可以通過(guò)video標(biāo)簽在網(wǎng)頁(yè)上播放攝像頭中所錄取到的內(nèi)容,而video標(biāo)簽會(huì)默認(rèn)將大小設(shè)置為與攝像頭相同的大小,因此通過(guò)獲取video的大小來(lái)獲取攝像頭的分辨率。

經(jīng)過(guò)測(cè)試,獲取到的值不受樣式的影響,所以可以通過(guò)樣式控制video的大小,但是不會(huì)影響到分辨率。

let mediaDevices = navigator.mediaDevices || null  
if( mediaDevices === null ) {    
  console.warn(`請(qǐng)確定是否處于https協(xié)議環(huán)境下`)
  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)
})

無(wú)攝像頭/無(wú)使用權(quán)限等錯(cuò)誤的處理

getUserMedia本身集成了幾個(gè)比較常見(jiàn)的錯(cuò)誤提示,比如常見(jiàn)的無(wú)攝像頭、無(wú)使用權(quán)限等,通過(guò)catch能處理大部分類似的錯(cuò)誤。

let mediaDevices = navigator.mediaDevices || null
  
if( mediaDevices === null ) {
  
  console.warn(`請(qǐng)確定是否處于https協(xié)議環(huán)境下`)
  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': '瀏覽器禁止本頁(yè)面使用攝像頭,請(qǐng)開(kāi)啟相關(guān)的權(quán)限',
      'requested device not found': '未檢測(cè)到攝像頭'
    }  
  alert(response[ message.toLowerCase() ] || '未知錯(cuò)誤')
})

攝像頭拔出檢查

手機(jī)端由于攝像頭是手機(jī)自帶的,所以一般不需要對(duì)攝像頭是否拔出進(jìn)行檢查。但在PC上有拔出攝像頭數(shù)據(jù)線的情況發(fā)生,這種時(shí)候就需要對(duì)攝像頭的狀態(tài)進(jìn)行監(jiān)控。
最開(kāi)始想到的是,getUserMedia在攝像頭拔出時(shí)可能會(huì)通過(guò)catch報(bào)錯(cuò)。然而經(jīng)過(guò)多次的實(shí)驗(yàn),getUserMedia在攝像頭拔出時(shí),不會(huì)響應(yīng)找不到攝像頭的錯(cuò)誤,想通過(guò)catch直接監(jiān)控這種方法并不可行。
在幾乎沒(méi)有思路的時(shí)候,在getUserMedia文檔上看到了這么一句話:

getUserMedia返回一個(gè) Promise , 這個(gè)Promise成功后的回調(diào)函數(shù)帶一個(gè) MediaStream 對(duì)象作為其參數(shù)。

MediaStream是接收多媒體(包括音頻、視頻)內(nèi)容流的一個(gè)對(duì)象,在谷歌瀏覽器(其他瀏覽器未測(cè)試)的控制臺(tái)上打印之后,其屬性值如下:

id是MediaStream對(duì)象的唯一標(biāo)識(shí)符,active是當(dāng)前內(nèi)容流是否處于活動(dòng)狀態(tài),下面幾個(gè)字段則是谷歌瀏覽器提供的鉤子。

在攝像頭拔出的一瞬間,active會(huì)從true變更為false,同時(shí)觸發(fā)oninactive鉤子,有了狀態(tài)監(jiān)聽(tīng)之后事情就簡(jiǎn)單了許多。代碼經(jīng)過(guò)測(cè)試后發(fā)現(xiàn),對(duì)用戶變更攝像頭權(quán)限也有效。

// 判斷攝像頭是否在線
let cameraIsOnline = false
  
const loadWebCamera = () => {
    
  let mediaDevices = navigator.mediaDevices || null
  
  if( mediaDevices === null ) {
  
    console.warn(`請(qǐng)確定是否處于https協(xié)議環(huán)境下`)
    return 
  }
  
  mediaDevices.getUserMedia({ audio: false, video: true }).then(async (stream) => {
  
    let video = document.getElementById('#video')
  
    video.srcObject = stream
      
    // 兼容性處理
    if( stream.oninactive === null ) {
      // 監(jiān)聽(tīng)流中斷,流中斷后將重新進(jìn)行調(diào)用自身進(jìn)行狀態(tài)監(jiān)測(cè)
      stream.oninactive = () => loadWebCamera()
    }
  
    await video.play()

    cameraIsOnline = true
  
  }).catch((error) => {
  
    let message = error.message || error,
      response = {
        'permission denied': '瀏覽器禁止本頁(yè)面使用攝像頭,請(qǐng)開(kāi)啟相關(guān)的權(quán)限',
        'requested device not found': '未檢測(cè)到攝像頭',
        'could not start video source': '無(wú)法訪問(wèn)到攝像頭,請(qǐng)重新插拔后重試'
      }
   
    cameraIsOnline = false
    alert(response[ message.toLowerCase() ] || '未知錯(cuò)誤')
  })
}

不過(guò),兼容性也非常地捉急,也有很多字段都是提案階段,開(kāi)發(fā)階段建議做好兼容性處理,防止生產(chǎn)環(huán)境出現(xiàn)問(wèn)題。

到此這篇關(guān)于js實(shí)現(xiàn)調(diào)用網(wǎng)絡(luò)攝像頭及常見(jiàn)錯(cuò)誤處理的文章就介紹到這了,更多相關(guān)js 調(diào)用網(wǎng)絡(luò)攝像頭內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

  • JavaScript實(shí)現(xiàn)梯形乘法表的方法

    JavaScript實(shí)現(xiàn)梯形乘法表的方法

    這篇文章主要介紹了JavaScript實(shí)現(xiàn)梯形乘法表的方法,涉及基本javascript結(jié)合表格操作的技巧,需要的朋友可以參考下
    2015-04-04
  • js replace() 文本替換你所不知的

    js replace() 文本替換你所不知的

    今天看了一個(gè)函數(shù),功能是把形如word-word的字符串轉(zhuǎn)化為wordWord
    2010-03-03
  • JavaScript知識(shí)點(diǎn)總結(jié)(六)之JavaScript判斷變量數(shù)據(jù)類型

    JavaScript知識(shí)點(diǎn)總結(jié)(六)之JavaScript判斷變量數(shù)據(jù)類型

    這篇文章主要介紹了JavaScript知識(shí)點(diǎn)總結(jié)(六)之JavaScript判斷變量數(shù)據(jù)類型的相關(guān)資料,非常不錯(cuò)具有參考借鑒價(jià)值,需要的朋友可以參考下
    2016-05-05
  • JavaScript 一行代碼,輕松搞定浮動(dòng)快捷留言-V2升級(jí)版

    JavaScript 一行代碼,輕松搞定浮動(dòng)快捷留言-V2升級(jí)版

    前天熬了大半宿發(fā)了一篇[一行代碼輕松搞定快捷留言功能],同時(shí)發(fā)布了V1.0beta版的快捷留言功能和源代碼,之所以是beta版,就是當(dāng)時(shí)感覺(jué)雖然基本功能有了,但是還不夠完善,特性也不一定合理
    2010-04-04
  • 微信小程序wxss如何引用外部CSS文件以及iconfont

    微信小程序wxss如何引用外部CSS文件以及iconfont

    這篇文章主要給大家介紹了關(guān)于微信小程序wxss如何引用外部CSS文件以及iconfont的相關(guān)資料,文中通過(guò)圖文介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2021-03-03
  • js和C# 時(shí)間日期格式轉(zhuǎn)換的簡(jiǎn)單實(shí)例

    js和C# 時(shí)間日期格式轉(zhuǎn)換的簡(jiǎn)單實(shí)例

    下面小編就為大家?guī)?lái)一篇js和C# 時(shí)間日期格式轉(zhuǎn)換的簡(jiǎn)單實(shí)例。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2016-05-05
  • JS實(shí)現(xiàn)簡(jiǎn)單的選擇題測(cè)評(píng)系統(tǒng)代碼思路詳解(demo)

    JS實(shí)現(xiàn)簡(jiǎn)單的選擇題測(cè)評(píng)系統(tǒng)代碼思路詳解(demo)

    本文給大家分享js實(shí)現(xiàn)簡(jiǎn)單的選擇題測(cè)評(píng)系統(tǒng)實(shí)例代碼,非常不錯(cuò),具有參考借鑒價(jià)值,需要的朋友參考下吧
    2017-09-09
  • Moment.js 不容錯(cuò)過(guò)的超棒Javascript日期處理類庫(kù)

    Moment.js 不容錯(cuò)過(guò)的超棒Javascript日期處理類庫(kù)

    moment.js是一個(gè)輕量級(jí)并且健壯的js日期處理類庫(kù),相信大家在javascript開(kāi)發(fā)過(guò)程中,都自己動(dòng)手寫過(guò),或者使用google和百度搜索過(guò)相關(guān)的實(shí)現(xiàn)函數(shù)
    2012-04-04
  • 用Golang運(yùn)行JavaScript的實(shí)現(xiàn)示例

    用Golang運(yùn)行JavaScript的實(shí)現(xiàn)示例

    這篇文章主要介紹了用Golang運(yùn)行JavaScript的實(shí)現(xiàn)示例,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2019-11-11
  • 最新評(píng)論