国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

EasyRTC官方tutorial [譯文]

pf_miles / 2332人閱讀

摘要:示例當(dāng)用戶從連接或斷開鏈接時(shí),將被調(diào)用,該方法的回調(diào)函數(shù)包含兩個(gè)參數(shù)連接到相同房間名的用戶在我們的示例程序當(dāng)中,該方法的回調(diào)函數(shù)將建立一系列用于撥打給當(dāng)前已連接到房間內(nèi)的其他用戶的按鈕。

EasyRTC 概覽

EasyRTC基于webRTC。WebRTC是W3C/IETF用于瀏覽器間實(shí)時(shí)音視頻溝通以及數(shù)據(jù)傳輸?shù)囊粋€(gè)實(shí)現(xiàn)方案。WebRTC只需要一個(gè)輕量負(fù)荷的服務(wù)器就可以支持點(diǎn)對(duì)點(diǎn)(P2P)間的任何數(shù)據(jù)傳輸。

EasyRTC由客戶端(瀏覽器端)的JS庫與基于node.js的后端服務(wù)器組成。WebRTC已經(jīng)被各個(gè)瀏覽器(google chrome, firefox, opera, etc)所支持,因此無需額外的瀏覽器插件。

Google Chrome對(duì)WebRTC的API有著最廣泛的支持,Opera現(xiàn)在采用與Chrome相同的內(nèi)核引擎,因此所有API行為與chrome基本一致。Firefox對(duì)WebRTC的Data Channel有著十分良好的實(shí)現(xiàn),但僅提供了基礎(chǔ)的視頻功能。

一旦WebRTC被標(biāo)準(zhǔn)化,它將有著巨大的潛能為音視頻會(huì)議,多用戶游戲,以及許多其他的基于音視頻,數(shù)據(jù)傳輸?shù)膽?yīng)用提供支持。

如同其他的軟件,強(qiáng)大的功能往往伴隨著復(fù)雜的內(nèi)部實(shí)現(xiàn)。WebRTC有著十分曲折的學(xué)習(xí)曲線,對(duì)開發(fā)人員不夠友好。為了簡(jiǎn)化具體的開發(fā)流程,我們(Priologic)構(gòu)建了EasyRTC框架。

構(gòu)建一個(gè)基于WebRTC的應(yīng)用通常有如下步驟。

將本地?cái)z像頭、麥克風(fēng)獲取到的數(shù)據(jù)輸出成media stream對(duì)象

與信令服務(wù)器建立連接

通過瀏覽器與目標(biāo)用戶建立p2p通信

將media stream綁定到

通過使用EasyRTC,一些步驟可以被簡(jiǎn)化到一個(gè)簡(jiǎn)單的通信(call)當(dāng)中,
能極大地簡(jiǎn)化開發(fā)流程,尤其是當(dāng)開發(fā)人員需要投入更多的精力于多平臺(tái)支持當(dāng)中。

此文檔是編寫基于WebRTC應(yīng)用的一個(gè)基本教程,但并未包含EasyRTC的所有API。

術(shù)語

callbakck(回調(diào)函數(shù))

Media Stream 瀏覽器音視頻輸出對(duì)象

Peer Connection 點(diǎn)對(duì)點(diǎn)連接

Server

安裝EasyRTC與獲取支持

EasyRTC的安裝十分簡(jiǎn)單,多數(shù)平臺(tái)可在10分鐘內(nèi)完成。我們提供了Windows,Linux,Mac的安裝向?qū)АasyRTC的源碼可在[https://github.com/priologic/...]獲取。在doc目錄下可以獲取到客戶端與服務(wù)端的所有HTML說明文檔

視頻會(huì)議

html 略

頁面載入完成(onload)后調(diào)用初始化函數(shù)(initialization function)。
初始化函數(shù)的最主要作用是調(diào)用EasyRTC.easyApp方法。該方法有如下參數(shù)

applicationName - String 應(yīng)用名,如"Company_Chat_Line"

self-video-id - String video標(biāo)簽id

array-of-caller-video-ids - Array 包含了其他用戶(除當(dāng)前用戶)的video標(biāo)簽id

successCallback - 連接成功時(shí)回調(diào)函數(shù)

初始化函數(shù)可以使用EasyRTC.setRoomOccupantListener來注冊(cè)一個(gè)回調(diào)函數(shù),以用于獲取當(dāng)前已連接到同一房間內(nèi)的其他用戶id,。

示例:

function my_init() {
    easyrtc.setRoomOccupantListener(loggedInListener)
    easyrtc.easyApp("Company_chat_line", "self", ["caller"], id => {
    console.info("My id is " + id)
    })
}

當(dāng)用戶從"Company_chat_line"連接或斷開鏈接時(shí),easyrtc.setRoomOccupantListener將被調(diào)用,該方法的回調(diào)函數(shù)包含兩個(gè)參數(shù):

String room name

Array 連接到相同房間名的用戶id

在我們的示例程序當(dāng)中,該方法的回調(diào)函數(shù)將建立一系列用于“撥打”給當(dāng)前已連接到房間內(nèi)的其他用戶的按鈕。

html 略

多數(shù)情況下可以忽略room_name參數(shù),除非你的應(yīng)用允許用戶同時(shí)連接到多個(gè)房間。

在現(xiàn)實(shí)的應(yīng)用當(dāng)中,我們不會(huì)使用easyrtc的默認(rèn)id當(dāng)作按鈕的label屬性。我們將使用類似姓名,職位等建立起與easyrtc id相關(guān)聯(lián)的內(nèi)容以用作按鈕的label屬性。

初始化一個(gè)call,我們只需要調(diào)用 easyrtc.call 方法,傳入目標(biāo)用戶的id,該方法包含三個(gè)回調(diào)函數(shù):

successCallback(id)

errorCallback(errorCode, errorText)

accepted(wasAccepted, id) 指明該call是否被接受

示例代碼:

function performCall(id) {
    easyrtc.call(id, id => {
        console.info("completed call to  " + id)
    }, errorMessage => {
        console.error("err: " + errorMessage)
    }, (accepted, bywho) => {
        console.info(accepted ? "accepted" : "rejected" + " by " + bywho)
    })
}

html 略

視頻會(huì)議(Advanced)

在上一節(jié),我們大致地描述了構(gòu)建一個(gè)視頻會(huì)議應(yīng)用的最簡(jiǎn)單情形。
在這一節(jié),我們將進(jìn)一步深入。

除了調(diào)用easyrtc.easyApp,你也可以調(diào)用easyrtc.initMediaSource來直接獲取本地設(shè)備的media stream,成功之后可以調(diào)用easyrtc.connect方法來連接到信令服務(wù)器。這也是easyrtc.easyApp的內(nèi)部實(shí)現(xiàn)。

html略

注意: easyrtc.getLocalStream和easyrtc.setVideoObjectSrc,前者用于當(dāng)easyrtc.initMediaSource調(diào)用完成,從本地?cái)z像頭和麥克風(fēng)獲取media stream,后者用于將media stream與video標(biāo)簽綁定。一起使用便可以十分便攜地供用戶實(shí)時(shí)觀察到他們自己的圖像。

我們還需要兩個(gè)其他函數(shù)

一個(gè)用于提供遠(yuǎn)程用戶的media stream

easyrtc.setStreamAcceptor((callerId, stream) => {
    let video = document.getElementById("caller")
    easyrtc.setVideoObjectSrc(video, stream)
})

一個(gè)用于檢測(cè)遠(yuǎn)程用戶是否掛起(離線)。該函數(shù)用于清除對(duì)應(yīng)的video標(biāo)簽

    easyrtc.setOnStreamClosed(callerId => {
        easyrtc.setVideoObjectSrc(document.getElementById("caller"), "")
    })

整個(gè)js文件如下

// 設(shè)置遠(yuǎn)程用戶的media stream 的關(guān)聯(lián)video標(biāo)簽
easyrtc.setStreamAcceptor((callerId, stream) => {
    let video = document.getElementById("caller")
    // 綁定media stream到video標(biāo)簽對(duì)象
    easyrtc.setVideoObjectSrc(video, stream)
})

// 當(dāng)遠(yuǎn)程media strem 關(guān)閉
easyrtc.setOnStreamClosed(callerId => {
// 清除關(guān)聯(lián)的video標(biāo)簽內(nèi)容
easyrtc.setVideoObjectSrc(document.getElementById("caller"), "")
})

// 初始化函數(shù)
function my_init() {
    // 設(shè)置監(jiān)聽器,獲取當(dāng)前在線的用戶
    easyrtc.setRoomOccupantListener(loggedInListener)
    // 連接成功處理函數(shù)
    let connectSuccess = myId => {
        console.info("My easyrtc id is " + myId)
    }
    // 連接失敗 創(chuàng)建本地media stream對(duì)象失敗時(shí)調(diào)用函數(shù)
    let connectFailure = (errorCode, errText) => {
        console.error(errText)
    }
    // 初始化本地media stream
    easyrtc.initMediaSource(() => {
        let selfVideo = document.getElementById("self")
        // 綁定本地media stream 到video tag
        easyrtc.setVideoObjectSrc(selfVideo, easyrtc.getLocalStream())
        // 連接到服務(wù)器
        easyrtc.connect("Company_Chat_line", connectSuccess, connectFailure)
    }, 
    connectFailure)
}

// 當(dāng)獲取到當(dāng)前房間內(nèi)在線用戶
function loggedInListener(roomName, otherPeers) {
    let otherClientDiv = document.getElementById("otherClients")
    while(otherClientDiv.hasChildNodes()) {
    // 移除最后一個(gè) “text ”
otherClientDiv.removeChild(otherClientDiv.lastChild)
    }
    
    for (let i in otherPeers) {
        let button = document.createElement("button")
        // 為每一個(gè)遠(yuǎn)程用戶創(chuàng)建一個(gè)按鈕監(jiān)聽器
        button.onclick = easyrtcId => {
            // 發(fā)起連接
            return (easyrtcId) => performCall(easyrtcId)
        }(i)
        
        let label = document.createTextNode(i)
        button.appendChild(label)
        otherClientDiv.appendChild(button)
    }
}

function performCall(id) {
    easyrtc.call(id, id => {
        console.info("completed call to " + id)
    }, 
    (errorCode, errText) => {
        console.error("err: " + errorText)
    }, 
    (accepted, bywho) => {
        console.info(accepted ? "accepted" : "rejected" + " by " + bywho)
    })
}
使用多個(gè)本地media stream源

使用多個(gè)media stream的基本思想是,你需要為每個(gè)media stream命名。
當(dāng)你調(diào)用initMediaSource,它的第三個(gè)參數(shù)便是media stream的名字,
如:

easyrtc.initMediaStream(success, failure, yourname)

如果你沒有傳入第三個(gè)參數(shù),則該media stream會(huì)得到一個(gè)默認(rèn)的"default"。

使用easyrtc.getLocalMediaIds以獲取所有本地media stream的名字

let ids = easyrtc.getLocalMediaIds()
ids.map(id => console.info(id))

當(dāng)你初始化一個(gè)call,可以傳入一個(gè)stream name的數(shù)組作為第五個(gè)參數(shù),同樣的,當(dāng)你接受call時(shí),你可以傳入一個(gè)stream name的數(shù)組作為accept回調(diào)函數(shù)的第二個(gè)參數(shù)。

easyrtc.call(otherEasyrtcId, successCB, failCB, wasAcceptedCB, ["first_name", "second_name", "etc"])

easyrtc.setAcceptChecker((otherGuy, acceptCallback) => {
    acceptCallback(true, ["first_name", "second_name"])
})

你也可以通過使用easyrtc.addStreamToCall向一個(gè)已存在的call添加meida stream。該方法接受三個(gè)參數(shù),接受stream的id,stream的名字,以及一個(gè)optional的回調(diào)處理函數(shù)。

注意:EasyApp 框架并不是專門為多media stream而設(shè)計(jì)的。它的初衷便是假定只有單個(gè)本地media stream。
如果你想使用media stream,那么你就必須自己將這些media stream綁定到video標(biāo)簽。

屏幕分享 只使用音頻或視頻功能 拒絕遠(yuǎn)程對(duì)話(call)

EasyRTC允許注冊(cè)一個(gè)在用戶每次收到call時(shí)都將被調(diào)用的函數(shù)。該函數(shù)接受遠(yuǎn)程用戶的id,以及一個(gè)報(bào)告函數(shù)(reporting function)作為參數(shù),報(bào)告函數(shù)接受一個(gè)參數(shù),true接受對(duì)話,false拒絕對(duì)話。

easyrtc.setAcceptChecker( function(easyrtcid, acceptor){
          if( easyrtc.idToName(easyrtcid) === "Fred" ){
             acceptor(true);
          }
          else if( easyrtc.idToName(easyrtcid) === "Barney" ){
             setTimeout( function(){
     acceptor(true, ["myOtherCam"]); // myOtherCam presumed to a streamName
     }, 10000);
          }
          else{
             acceptor(false);
          }
     });
加入或離開房間

Room是EasyRTC的一個(gè)隔離(compartmentalize)功能,目的是為用戶建立起一個(gè)個(gè)“chat rooms”。
房間的行為受服務(wù)器安裝的EasyRTC Server的配置所影響(詳見服務(wù)器模塊文檔)。默認(rèn)行為如下:

除非用戶在連接前指定了所要加入的房間名,否則將會(huì)加入默認(rèn)的“default”房間。

一個(gè)用戶可以是多個(gè)房間的成員

每個(gè)用戶所加入的任一個(gè)房間發(fā)生變化時(shí)(用戶的加入,離開),都會(huì)觸發(fā)roomOccupantListener函數(shù)

加入一個(gè)不存在的房間將會(huì)創(chuàng)建它

加入房間

easyrtc.joinRoom(roomName, roomParameters, successCallback, failureCallback)

其中,roomParameters是Application specific(不詳),可以為空。joinRoom可以在任何時(shí)候調(diào)用任意多次,但successCallback, failureCallback只會(huì)在成功與信令服務(wù)器建立連接之后才會(huì)被調(diào)用。

離開房間

easyrtc.leaveRoom(roomName, successCallback, failureCallback)

leaveRoom的性質(zhì)同joinRoom

監(jiān)聽Error

你可以通過easyrtc.setOnError注冊(cè)一個(gè)error callback用以處理錯(cuò)誤。該函數(shù)接受一個(gè)形如{"errorCode": "errorCode", "errorText": "errorText"}的對(duì)象。

easyrtc.setOnError(errEvent => {
    console.error(errEvent.errorText)
})
發(fā)送消息

你可以通過調(diào)用easyrtc.sendDataWS來使用websocket通信,

easyrtc.sendDataWS(destination, messageType, messageData, ackHandler)

easyrtc.sendDataWS("xkxkxkxkxk9c93", "contactInfo", {firstName: "jack", lastName: "smith"}, ackMsg => {
// ackMsg 為來自服務(wù)器的確認(rèn)信息
    if (ackMsg.msgType === "error") {
        console.error(ackMsg.msgData.errorText)
    }
})

注意: 通過websocket通信意味著你指定信息要通過服務(wù)器轉(zhuǎn)發(fā)

destination 可以是peer的id,或者是一個(gè)指定了一個(gè)或多個(gè)目標(biāo)id的js對(duì)象,或者房間(詳見文檔)。
messageType需要自行指定,ackHandler處理來自服務(wù)器的確認(rèn)信息

處理來自其他用戶的信息:
easyrtc.setPeerListener((sender_id, msgType, msgData, targeting) => {

if (msgType === "contactInfo") {
    console.info(sender_id + " is named " + msgData.firstName + " " + msgData.lastName)
}

})

其中,當(dāng)使用WebRTC的data channel發(fā)送數(shù)據(jù)時(shí),targeting為null,否則為{targetEasyrtcid, targetGroup, targetRoom}當(dāng)中的一個(gè)。

你也可以為特定的msgType或sender指定監(jiān)聽器,在這種情況下,每次將只有一個(gè)監(jiān)聽器會(huì)被調(diào)用,指定的監(jiān)聽器將被優(yōu)先調(diào)用。

使用Data Channels

在使用data channel之前,發(fā)送者和接收者都必須啟用data channels。

easyrtc.enableDataChannels(true)

之后便可監(jiān)聽與特定用戶的datachannel的 ready 和 close 事件,

easyrtc.setDataChannelOpenListener(sourceEasyrtcId => 
    console.info("channel is open ")
)

easyrtc.setDataChannelCloseListener(sourceEasyrtcid => 
    console.info("channel is close ")
)

open監(jiān)聽器被調(diào)用之后,便可以通過easyrtc.sendDataP2P來發(fā)送消息:

easyrtc.sendDataP2P(targetEasyrtcid, "contactInfo", {firstName: "jack", lastName: "smith"})

監(jiān)聽data channels消息與websocket消息一致

獲取當(dāng)前連接數(shù)

通過easyrtc.getConnectionCount來獲取當(dāng)前用戶的連接數(shù),該函數(shù)返回一個(gè)number

掛起

通過easyrtc.hangup(peerId)來掛起與特定用戶的連接

easyrtc.hangupAll()來掛起與所有用戶的連接

與服務(wù)器斷開鏈接
easyrtc.disconnect()

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://specialneedsforspecialkids.com/yun/92451.html

相關(guān)文章

  • 譯文】Node.js官方文檔(前言&目錄)

    摘要:畢竟官方文檔才是未經(jīng)提煉的純技術(shù)點(diǎn),讀書不能只讀二手書。目前網(wǎng)上能找到的中文文檔基本都是基于的,但截至此文發(fā)布,最新的穩(wěn)定版都已經(jīng)是了。翻譯過程中主要參考官方英文文檔,以及極客學(xué)院的官方文檔中文翻譯。 前言 相信很多開發(fā)者和我一樣,在學(xué)習(xí)一門技術(shù)的時(shí)候,通過網(wǎng)上的各種教程和視頻入門之后會(huì)發(fā)現(xiàn)自己遇到一個(gè)上升瓶頸。造成這個(gè)瓶頸的很大一部分原因,我認(rèn)為是進(jìn)階教程的知識(shí)點(diǎn)過于分散,同時(shí)高質(zhì)量...

    tinna 評(píng)論0 收藏0
  • 譯文】Node.js官方文檔(Part 1 關(guān)于文檔)

    摘要:關(guān)于本文檔本文檔的目的,是全面地解釋的,即可作為參考文檔,同時(shí)也包含了概念的講解。但有的全新的實(shí)驗(yàn)性的,或者存在危險(xiǎn)性的部分則會(huì)被重新設(shè)計(jì)。穩(wěn)定級(jí)別鎖定只會(huì)有安全性能或相關(guān)的修復(fù)。不接受對(duì)此做修改的建議。 關(guān)于本文檔 本文檔的目的,是全面地解釋Node.js的API,即可作為參考文檔,同時(shí)也包含了概念的講解。每個(gè)章節(jié)都描述了一個(gè)內(nèi)置模塊或一個(gè)高階概念(high-level concep...

    svtter 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

pf_miles

|高級(jí)講師

TA的文章

閱讀更多
最新活動(dòng)
閱讀需要支付1元查看
<