基於 Web 端的屏幕共享實踐

屏幕共享的英文叫作 DesktopSharing,通俗點講就是將本身電腦的畫面分享給其餘人, 被分享的能夠是整個電腦屏幕、應用程序或者某一個打開的網頁等等。html

而隨着音視頻領域的深刻發展,完備的功能在用戶需求激增的背景下催生,不論是是在學習、生活或是娛樂場景下,屏幕共享做爲實現互動的一種方式被愈來愈多的用戶應用在平常生活中:前端

一、遠程協做(TeamViewer):控制遠程計算機,完成協做等;git

二、在線會議:參會者只需在本身的電腦屏幕上查看共享的文件材料,並觀看文件演示等;github

三、在線課堂:屏幕共享能夠將老師的課件、筆記、講課內容等畫面展現給學生觀看等;web

......express

因而可知,屏幕共享這個衍生功能已經在愈來愈多的場景上成功使用,那麼該如何實現屏幕共享呢?本篇文章咱們將詳細介紹在 Web 端的屏幕共享實踐。 canvas

Web 端如何實現屏幕捕捉

Web 端瀏覽器能夠實現屏幕共享麼? 在電腦端是能夠作到的。屏幕共享分爲兩個步驟:屏幕捕捉 + 流媒體傳輸segmentfault

屏幕捕捉: 獲取數據, 爲流媒體傳輸提供數據源;promise

流媒體傳輸: 將音視頻數據從一個客戶端傳輸到另外一個客戶端。當前比較成熟的方案是使用WebRTC協議提供的低延遲和抗弱網能力以此來保證體驗;瀏覽器

WebRTC 協議要求提供的流數據必須是 MediaStream 對象,因此屏幕採集的流也必須是 MediaStream 類型。咱們先以電腦端  Chrome 72 爲例 ( 不一樣瀏覽器寫法會有點不同),捕捉屏幕畫面代碼是這樣的:

async function startCapture(displayMediaOptions){
   let captureStream = null;
   try{  
    captureStream = await navigator.mediaDevices.getDisplayMedia(displayMediaOptions);
   }catch(err){  
     console.error("Error: "+ err);
   }
   return captureStream;
}

效果以下:

圖片

 (示例demo地址:https://zegoim.github.io/expr...

 關鍵語法:

//  constraints 參數可參考https://developer.mozilla.org/zhCN/docs/Web/API/MediaDevices/getDisplayMedia
let promise = navigator.mediaDevices.getDisplayMedia(constraints);

屏幕捕捉兼容性問題及應對方案

做爲 Web 前端開發,相信這個問題是你們比較關心的,目前屏幕捕捉接口兼容狀況比較複雜,僅支持在如下桌面端瀏覽器中進行屏幕捕捉:

  • Chrome 58 或以上版本
  • Firefox 56 或以上版本
  • Edge 80 及以上版本
  • macOS 的 Safari  13 及以上版本

其中Chrome瀏覽器還能夠進一步分爲: 有插件和無插件。

  • 有插件: 須要在瀏覽器上額外安裝插件, 利用 Chrome 提供的能力捕捉屏幕,插件方式能夠在較低版本上實現捕捉;
  • 無插件: 不用額外安裝任何插件, 但要求 Chrome 必須是 72 及以上版本。

Chrome 瀏覽器若是要支持音頻分享, 無插件方式必需要是 Chrome 74 及以上版本,Safari 瀏覽器目前則只支持分享整個屏幕,沒法選擇應用程序和瀏覽器頁面。

清楚瀏覽器兼容狀況後,就能夠針對瀏覽器進行判斷了,大體思路是經過 navigator.appVersion 判斷瀏覽器類型/平臺/版本,並對接口作是否存在的判斷,在正式業務開始前,提早感知瀏覽器是否支持該能力。

代碼寫起來是純體力活,若是不想對瀏覽器類型和版本一一處理,ZEGO 即構科技的 zego-express-engine-webrtc.js 幫你們作好了內部兼容, 並提供檢測接口方便快速上手

​​​​​​​點擊查看: https://doc-zh.zego.im/articl...

瀏覽器實現自定義尺寸分享

咱們看瀏覽器提供的接口, 不管是什麼瀏覽器類型或版本,最小粒度只能捕捉到一個頁面,若是要分享的頁面或者程序有比較敏感的信息,不但願所有被分享出去,咱們應該怎麼辦呢? 

只看瀏覽器接口是沒有辦法實現的,不過 MediaStream 對象還能夠從 video 或者 canvas 這類媒體標籤上獲取。若是把捕捉到的流媒體對象渲染到畫布上,再從畫布上截取咱們想要分享的部分畫面,就能夠實現指定尺寸分享了。

實現僞代碼以下:

// 獲取屏幕捕捉流
let screenStream = await navigator.mediaDevices.getDisplayMedia(displayMediaOptions);

// 建立畫布
const ctx = canvas.getContext('2d');

// 滾動渲染視頻
let timer = null;
function videoDrawInCanvas(){
timer = setTimeout(async () => {
videoDrawInCanvas( ctx, source, canvas, videoX, videoY, videoWidth, videoHeight);
}, 60);
}

// 獲取從新繪製的畫布流
const canvasMedidaStream = canvas.captureStream(25);

效果以下:

圖片

能夠看到這種方式的確是可行的,ZEGO WebRTC 團隊也提供了對應的 demo 和源碼, 免費給你們參考和體驗,並封裝了對應的庫 rangeShare.js,幫助你們快速上手直接使用,可點擊連接查看:[ https://zegodev.github.io/zeg...]()。

實踐過程當中咱們發現,還有一些問題也很是值得你們注意:

  • 問題一:canvas 渲染對瀏覽器 cpu 消耗是比較高的, 性能很差的設備可能會致使整個頁面卡頓;
  • 問題二:雖然畫面能夠從新繪製, 可是從新繪製的流是純視頻的,若是捕捉的流是包含音頻,會致使音頻丟失。

對於問題一:ZEGO WebRTC 團隊 通過大量設備測試,在 rangeShare.js 庫中把參數調整到儘量適配更多設備。同時 demo 中提供了估算 cpu 佔用的代碼, 在 cpu 消耗過大狀況下,能夠提示本設備 cpu 佔用太高,開發者可根據提示選擇更換設備,或關閉其餘 cpu 佔用較高的進程。

對於問題二:rangeShare.js 也幫你把這個問題考慮到了,屏幕捕捉到的流傳進來時,若檢測到包含音頻,會自動緩存音軌,並在輸出的時候和畫布流混合。

總結

以上就是關於在 Web 端實現屏幕共享的技術解讀,而隨着 5G 技術的到來和硬件設備性能的提高,瀏覽器上實現流媒體的低延遲傳輸和流媒體數據處理已經有較成熟的方案,好比瀏覽器上實現屏幕捕捉。

音視頻能表達的信息相比文字圖片更豐富,因此音視頻傳輸正變得更普及,同時現代瀏覽器也在不斷的更新音視頻操做相關 API,瀏覽器能作的事情也許比咱們想象中的更多。

ZEGO WebRTC 團隊會持續跟你們分享 Web 端關於音視頻方面有意思的技術問題,若有出入,歡迎你們指正和交流。

相關文章
相關標籤/搜索