2.1、列舉媒體設備


文章導讀:在上一章的“1.5、Web服務器”中已經明確了Web服務程序在webrtc中的意義,本節繼續上章的內容,進一步的完善Web服務程序的其他功能:加入內網穿透功能,實現通過公網地址調試程序。並且講解通過enumerateDevices方法列舉本機電腦可用的媒體設備。閱讀建議:理解+實操。

   webrtc對web環境的安全是有要求的,通過http加載的頁面不能正常的調用某些核心的功能,因此我們需要搭建出“安全”的web環境——https。作為學習之用,我們無需租用一台雲主機,而是換用成本更小的內網穿透工具來部署調試環境。內網穿透的原理如下圖2.1.1所示。

 

 

 圖 2.1.1 (內網穿透原理圖)

如上圖所示,虛線部分為“個人電腦”,即我們調試程序的電腦,我們現在搭建好的web服務程序是無法被外部訪問的,為了能打通這個限制,我們需要一個輔助工具——穿透客戶端程序,當然穿透客戶端程序背后是有一個公網服務器來支持,通過穿透客戶端程序和穿透服務器的配合,個人電腦上的web服務就可以被外界訪問到。本書推薦使用echosite來完成這一穿透過程,其官網為:https://www.echosite.cn/  ,詳細的操作方法請參見官網的教程,請讀者自行查閱完成。我的內網穿透環境已經搭建好了,接下來演示下如何啟動。

  首先,啟動我們上一章寫好的web服務程序,在項目根目錄下輸入命令“node index.js ”啟動。如下圖2.1.2所示。

 

圖 2.1.2 (實驗內容的web服務)

接着啟動內網穿透客戶端程序,命令“echosite -config=config.yml start web_a ”。啟動結果如下圖2.1.3所示。

 

圖 2.1.3 (echosite啟動截圖)

 

由圖2.1.3所示,此刻本地的web服務8000端口已經和https://webrtclearn.easy.echosite.cn域名關聯起來,這就意味着,只要上面這兩程序都啟動,我們就能通過https://webrtclearn.easy.echosite.cn來訪問到本機的http://localhost:8000web服務。如果這一步實在搞不定的讀者,建議與我一對一交流吧。

  至此,服務器程序已經搭建完畢,接下來開始考慮如何進行實現音視頻數據的采集(注意:往后所有的網頁均在chrome瀏覽器中運行)。在采集之前,首先得看看本機電腦有哪些支持的媒體設備吧。所以,我們先要來學習一個方法——enumerateDevices,該方法可以列舉出本機可用的媒體輸入和輸出設備,調用的方式為”navigator.mediaDevices.enumerateDevices()“,返回一個Promise 對象,Promise異步結果是一個媒體設備列表數組,每個數組元素的結構為:

{
    deviceID:"",//string,設備唯一標識
    label:"",//string,設備名稱
    kind:"",// string,設備類型
    groupID:"",//string ,設備分組id
} 

 其中,deviceID是設備的唯一標識;label是媒體設備名稱,如“通訊 - 麥克風 (Realtek High Definition Audio)”。kind是設備類型, 分為:音頻輸入設備(audioinput)、音頻輸出設備(audiooutput)、視頻輸入設備(videoinput)。groupID 表示設備分組ID,不同設備,deviceID肯定不同,但groupID可能相同,如果某些設備的groupID相同,說明這些設備是同一個物理設備,例如一個帶麥的音樂播放設備既是音頻輸入設備又是音頻輸出設備,雖然同是一個物理設備,但enumerateDevices方法在列舉設備列表的時候,會把音頻輸入、音頻的輸出看成是兩個設備列舉出來,但groupID相同。這段描述可能比較抽象,接下來實際的寫一段代碼來演示,當然本章的案例有更貼近實戰的運用,這里先來簡單的實現:讀取媒體設備列表,並且打印出來。

  在public目錄中新建一個網頁文件,命名為”demo2.1.html“,如下圖2.1.4。

圖 2.1.4 (demo 2.1.html)

 

打開網頁文件並編輯,代碼如下。 

<html>
    <head>
        <meta http-equiv="Content-Type" content="text/html;charset=UTF-8">
        <title>demo 2.1 設備管理</title>
        <script src="./js/demo2.1.js"></script>
    </head>
    <body>
        <!--UI標簽代碼-->
    </body>
</html>

 在上述的html文件中,我們引入了一個外部JS 文件——“./js/demo 2.1.js”,於是,我們要創建該JS文件,如下圖2.1.5所示。

 

 

圖 2.1.5 (demo2.1.js)

 打開“demo2.1.js”文件,代碼如下。

'use strict'
// 檢測瀏覽器的支持情況
if (!navigator.mediaDevices || !navigator.mediaDevices.enumerateDevices) {
    throw new Error("enumerateDevices is not supported");
}
// 列出電腦支持的設備 navigator.mediaDevices.enumerateDevices().then(devices
=> { console.log("devices", devices); }).catch(error => { throw error; //拋出異常 })

  從上述的代碼可以看出enumerateDevices方法的層級結構——“enumerateDevices方法位於navigator對象下的mediaDevices對象中”,在JS中,調用層級較深的對象時,為了考慮代碼的健壯性,需要做對象的可用判斷,如果目標對象不可用就拋出異常。

  上述代碼運行結果如下圖2.1.6所示。  

 

圖 2.1.6 (設備列表讀取)

如圖2.1.6中,程序把本機中可用的媒體設備列舉並打印出來了, 其中label屬性沒有顯示出來,這是因為瀏覽器出於安全考慮,只對信任的域名開放核心功能的調用。要解決這個問題,先要看看瀏覽器是否信任該域名。打開瀏覽器的”設置“的頁面並搜索”攝像頭“的選項,如下圖2.1.7所示。

 

 

圖 2.1.7 (瀏覽器攝像頭權限設置)

 

從圖2.1.7中可以看出,案例代碼的網址“https://webrtclearn.easy.echosite.cn”並沒有在允許訪問攝像頭的范圍之內,因此權限不足,label屬性不可見。當然,此處也不能手動添加信任網址,怎么辦?

  解決的辦法就是讓程序來“調用”攝像頭,引導瀏覽器彈出詢問框,我們再做允許的操作。如下圖2.1.8所示。

圖 2.1.8 (調用媒體設備詢問)

如何調出上圖的詢問框呢? 很簡單,只要調用媒體設備即可,enumerateDevices方法執行時並未喚起詢問框,說明該方法並未調用媒體設備。調用媒體設備的代碼如下。

if(!navigator.mediaDevices || !navigator.mediaDevices.getUserMedia){
    throw new Error("getUserMedia is not supported");
}
// 調用音頻和視頻設備 navigator.mediaDevices.getUserMedia({audio:
true,video:true});

上面這段代碼是我們“采集”音視頻數據時用到的,但先在這里臨時用着(僅為了“調用”硬件設備),所以我不打算寫到代碼文件中(demo2.1.js),而是在“console”控制台直接執行,需要注意的是“getUserMedia”方法需要傳一個配置對象進去,於是我傳了一個“ {audio:true,video:true}”對象,表示我要調用的硬件設備類型有兩種——音頻、視頻。執行這段代碼后即可彈出 如圖2.1.8的提示框,我們只需點擊“允許”即可。此刻再來看“攝像頭的配置選項”,如下圖2.1.9所示。我們的域名已經被加入“允許”的域名列表中。同理,音頻設備(麥克風)也是如此,這里不在贅述。

 

圖 2.1.6(已授權攝像頭配置)

當我們再刷新demo2.1.html 頁面,控制台打印的效果如下圖2.1.7所示。

 

 

圖 2.1.7  (設備列表)

如上圖 2.1.7 展開的4個設備信息對象中,label屬性已經顯示出來,並且groupID一樣的,說明是同一個物理設備。

  大家也無需擔心每次調用都彈出提示框,根據chrome的規范,某一個域名只要加入“信任”的名單, 往后的調用就無需再彈出確認框。

  至此,webrtc設備管理的內容已經講完。總結,本文的完成了:一、實戰環境下的服務程序的搭建,較復雜的地方的是“內網穿透”環境的搭建。二、並且通過編碼實現了媒體設備的讀取,所用到webrtc API——“enumerateDevices”,更多關於該方法的描述,可以點擊這里查閱。總體來講內容比較簡單(得益於webrtc解決了復雜的底層問題),建議讀者動手實踐。下一節實戰內容:采集並展示流媒體。 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM