天天看點

前端:3分鐘實作一個共享桌面,還能聽見麥克風聲音哦

點選上方 前端瓶子君,關注公衆号

回複算法,加入前端程式設計面試算法每日一題群

原文: https://juejin.cn/post/6993133406565449736 

作者: 雲的世界 

專欄: 前端SSD系列

前言

前端一些有意思的内容,旨在3-10分鐘裡, 500-1000字,有所獲,又不為所累。

共享桌面程式,哇,高大尚耶!其實不然,讓我帶你3分鐘實作桌面共享程式,還能聽到對面說話哦。

效果示範和源碼

兩個Tab标簽,一個是分享者,一個是觀衆。 順便問一下,怎麼把聲音儲存到gif圖裡面去?

前端:3分鐘實作一個共享桌面,還能聽見麥克風聲音哦

思路

使用者1 ==> Screen Capture API  ===>  Web RTC  ===>  User2 Video 标簽播放
           

其核心 Screen Capture API[1] + WebRTC API[2], 我們一起來了解一波。

Screen Capture API[3] - 螢幕捕捉API

MDN解釋:

螢幕捕獲API,對現有的媒體捕獲和流API進行了補充,讓使用者選擇一個螢幕或螢幕的一部分(如一個視窗)作為媒體流進行捕獲。然後,該流可以被記錄或通過網絡與他人共享。

先看動态,再看代碼:

前端:3分鐘實作一個共享桌面,還能聽見麥克風聲音哦

僅僅隻需 

10

 餘行代碼,就可以把桌面展示在網頁面裡面是不是很酷。

<video id="deskVideo" autoplay controls></video>
    <script>
        (async function captureDesk() {
            deskVideo.srcObject = await navigator.mediaDevices.getDisplayMedia({
                video: {
                    cursor: "always"
                },
                audio: false
            });
        })();
    </script>

           

Web RTC[4]

MDN

WebRTC (Web Real-Time Communications) 是一項實時通訊技術,它允許網絡應用或者站點,在不借助中間媒介的情況下,建立浏覽器之間點對點(Peer-to-Peer)的連接配接,實作視訊流和(或)音頻流或者其他任意資料的傳輸。

我們明白其是點對點傳輸技術,解決傳輸問題就行。

實作

遵循SSD系列的準則:3-10分鐘裡, 500-1000字,有所獲,又不為所累。我自行實作,字數會超,而且還要有中轉伺服器。罷了,借助聲網吧。

聲網 agora[5], 為什麼是他,因為他一個月免費 10000 分鐘, 做測試和個人使用是完全夠了的。其底層的基本原理上面已經說過了,核心就是 Screen Capture API[6] + Web RTC[7]。

當然聲網還支援攝像頭,麥克風等等其他流的推送,攝像頭和麥克風是 MediaDevices[8]相關的内容不做過多的解釋。

新增賬號

聲網管理台登入或者注冊[9],連結位址已給,自行操作即可。

建立應用

詳情參見 跑通示例項目[10], 裡面有詳細的步驟教你建立應用,以及獲得AppID和Token

SDK下載下傳

去這裡下載下傳 Agora SDK下載下傳[11]

分享者代碼編寫

這裡有一個參數了解一下:

  1. appId:應用ID
  2. channel: 管道,你可以了解為房間
  3. token:票證
  4. uid: 使用者ID
  5. role: 使用者角色,有主播和觀衆兩種

核心代碼:

async function startBasicLive() {
    rtc.client = AgoraRTC.createClient({ mode: "live", codec: "vp8" }); // 初始化用戶端
    rtc.client.setClientRole(options.role);  // 設定角色

    const uid = await rtc.client.join(options.appId, options.channel, options.token, options.uid);       
    rtc.localAudioTrack = await AgoraRTC.createMicrophoneAudioTrack(); // 麥克風
    rtc.localVideoTrack = await AgoraRTC.createScreenVideoTrack();  // 桌面

    // 将這些音視訊軌道對象釋出到頻道中。
    await rtc.client.publish([rtc.localAudioTrack, rtc.localVideoTrack]);
    console.log("publish success!");
}
btnShareDesk.onclick = startBasicLive; // 注冊點選事件


           

觀衆端代碼編寫

核心代碼

async function startBasicLive() {
    rtc.client = AgoraRTC.createClient({ mode: "live", codec: "vp8" });
    rtc.client.setClientRole(options.role);

    rtc.client.on("user-published", async (user, mediaType) => {
         // 開始訂閱遠端使用者。
        await rtc.client.subscribe(user, mediaType);
        console.log("subscribe success", mediaType);

        // 表示本次訂閱的是視訊。
        if (mediaType === "video") {
            // 訂閱完成後,從 `user` 中擷取遠端視訊軌道對象。
            const remoteVideoTrack = user.videoTrack;
            // 動态插入一個 DIV 節點作為播放遠端視訊軌道的容器。
            const playerContainer = document.createElement("div");
            // 給這個 DIV 節點指定一個 ID,這裡指定的是遠端使用者的 UID。
            playerContainer.id = user.uid.toString();
            playerContainer.style.width = "640px";
            playerContainer.style.height = "480px";
            document.body.append(playerContainer);

            // 訂閱完成,播放遠端音視訊。
            // 傳入 DIV 節點,讓 SDK 在這個節點下建立相應的播放器播放遠端視訊。
            remoteVideoTrack.play(playerContainer);
        }

        // 表示本次訂閱的是音頻。
        if (mediaType === "audio") {
            // 訂閱完成後,從 `user` 中擷取遠端音頻軌道對象。
            const remoteAudioTrack = user.audioTrack;
            // 播放音頻因為不會有畫面,不需要提供 DOM 元素的資訊。
            remoteAudioTrack.play();
        }
    });   
    const uid = await rtc.client.join(options.appId, options.channel, options.token, null);
    console.log("uid", uid);
}

           

demo完整的代碼

源碼位址: https://github.com/xiangwenhu/juejinBlogsCodes/tree/master/shareYourDesktop

小結

是不是很簡單,一切都看起來沒那麼難,這樣,你才容易入坑啊。

寫在最後

寫作不易,你的一贊一評就是我前行的最大動力。

最後

歡迎關注【前端瓶子君】✿✿ヽ(°▽°)ノ✿

回複「算法」,加入前端程式設計源碼算法群,每日一道面試題(工作日),第二天瓶子君都會很認真的解答喲!

回複「交流」,吹吹水、聊聊技術、吐吐槽!

回複「閱讀」,每日刷刷高品質好文!

如果這篇文章對你有幫助,「在看」是最大的支援

 》》面試官也在看的算法資料《《

“在看和轉發”就是最大的支援

繼續閱讀