點選上方 前端瓶子君,關注公衆号
回複算法,加入前端程式設計面試算法每日一題群
原文: https://juejin.cn/post/6993133406565449736
作者: 雲的世界
專欄: 前端SSD系列
前言
前端一些有意思的内容,旨在3-10分鐘裡, 500-1000字,有所獲,又不為所累。
共享桌面程式,哇,高大尚耶!其實不然,讓我帶你3分鐘實作桌面共享程式,還能聽到對面說話哦。
效果示範和源碼
兩個Tab标簽,一個是分享者,一個是觀衆。 順便問一下,怎麼把聲音儲存到gif圖裡面去?

思路
使用者1 ==> Screen Capture API ===> Web RTC ===> User2 Video 标簽播放
其核心 Screen Capture API[1] + WebRTC API[2], 我們一起來了解一波。
Screen Capture API[3] - 螢幕捕捉API
MDN解釋:
螢幕捕獲API,對現有的媒體捕獲和流API進行了補充,讓使用者選擇一個螢幕或螢幕的一部分(如一個視窗)作為媒體流進行捕獲。然後,該流可以被記錄或通過網絡與他人共享。
先看動态,再看代碼:
僅僅隻需
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]
分享者代碼編寫
這裡有一個參數了解一下:
- appId:應用ID
- channel: 管道,你可以了解為房間
- token:票證
- uid: 使用者ID
- 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
小結
是不是很簡單,一切都看起來沒那麼難,這樣,你才容易入坑啊。
寫在最後
寫作不易,你的一贊一評就是我前行的最大動力。
最後
歡迎關注【前端瓶子君】✿✿ヽ(°▽°)ノ✿
回複「算法」,加入前端程式設計源碼算法群,每日一道面試題(工作日),第二天瓶子君都會很認真的解答喲!
回複「交流」,吹吹水、聊聊技術、吐吐槽!
回複「閱讀」,每日刷刷高品質好文!
如果這篇文章對你有幫助,「在看」是最大的支援
》》面試官也在看的算法資料《《
“在看和轉發”就是最大的支援