自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

如何應(yīng)對(duì)Chrome 112版本中的getDisplayMedia問(wèn)題?

系統(tǒng) 瀏覽器
當(dāng)我在瀏覽器中調(diào)試修復(fù)截圖插件的其他bug時(shí),發(fā)現(xiàn)截取的內(nèi)容出現(xiàn)了滾動(dòng)條,這讓我感到非常詫異。難道是我在解決某個(gè)問(wèn)題的同時(shí)引發(fā)了更多問(wèn)題。

前言

前幾天chrome發(fā)布了112版本,原本可以通過(guò)getDisplayMedia正確的獲取當(dāng)前標(biāo)簽頁(yè)的內(nèi)容,在此版本中卻出現(xiàn)了內(nèi)容擠壓、概率性出現(xiàn)滾動(dòng)條問(wèn)題。

經(jīng)過(guò)一番思考后,我想到了兩個(gè)處理方案,本文就跟大家分享下我的思路,歡迎各位感興趣的開(kāi)發(fā)者閱讀本文。

定位問(wèn)題

當(dāng)我在瀏覽器中調(diào)試修復(fù)截圖插件的其他bug時(shí),發(fā)現(xiàn)截取的內(nèi)容出現(xiàn)了滾動(dòng)條,這讓我感到非常詫異。難道是我在解決某個(gè)問(wèn)題的同時(shí)引發(fā)了更多問(wèn)題。于是,我嘗試回退代碼版本,但問(wèn)題仍然存在,這使我陷入了沉思,開(kāi)始求助別人、在搜索引擎尋找解決方案。

經(jīng)過(guò)一番折騰后,我沒(méi)有得到任何答案。就在這時(shí),有一個(gè)開(kāi)發(fā)者在給我提了issue,他也遇到了同樣的問(wèn)題。

圖片

他提供了瀏覽器版本號(hào),這讓我恍然大悟,不久前我升級(jí)了瀏覽器版本并且版本號(hào)跟他的一樣,同為112版本。

圖片

為了驗(yàn)證是否為瀏覽器升級(jí)所帶來(lái)的bug,我在虛擬機(jī)中安裝了110版本的chrome,發(fā)現(xiàn)這個(gè)問(wèn)題確實(shí)不存在。難不成是Google改了API?我?guī)е@個(gè)疑問(wèn)翻閱了getDisplayMedia的API文檔,并沒(méi)有發(fā)現(xiàn)有什么特殊說(shuō)明。

事情陷入了僵局,我又陷入了沉思。突然間,我想起來(lái)之前有個(gè)網(wǎng)友說(shuō)Google自家也有產(chǎn)品用到了這個(gè)API,找他要來(lái)了網(wǎng)址。

圖片

果然,他們產(chǎn)品也出現(xiàn)了問(wèn)題。

圖片

截取后的內(nèi)容出現(xiàn)了擠壓和滾動(dòng)條

圖片

解決方案

Chrome在下個(gè)版本的更新中可能會(huì)解決此問(wèn)題,也有可能不會(huì)解決。這是個(gè)未知數(shù),我還是得想想其他辦法來(lái)處理處理這個(gè)問(wèn)題。

隱藏滾動(dòng)條并填充擠壓區(qū)域

最簡(jiǎn)單粗暴的辦法就是在調(diào)用getDisplayMedia方法之前將頁(yè)面的寬、高分別設(shè)為100vw、100vh,給html和body元素設(shè)置overflow:hidden。部分代碼如下所示:

// 設(shè)置頁(yè)面寬高并隱藏滾動(dòng)條
document.documentElement.classList.add("hidden-screen-shot-scroll");
document.body.classList.add("hidden-screen-shot-scroll");
.hidden-screen-shot-scroll {
  width: 100vw;
  height: 100vh;
  overflow: hidden;
}

這樣設(shè)置后,又出現(xiàn)了新的問(wèn)題,因?yàn)榻貓D容器的高度為body區(qū)域未擠壓時(shí)的正確高度,webrtc的共享彈窗會(huì)把頁(yè)面內(nèi)容整體擠下去。

圖片

getDisplayMedia的回調(diào)里拿到的屏幕流數(shù)據(jù)是擠壓后的,底部會(huì)缺少一部分,這部分內(nèi)容正好是共享彈窗的高度。當(dāng)用戶(hù)想截取這部分的內(nèi)容時(shí),會(huì)發(fā)現(xiàn)拿到的是透明的。

圖片

為了解決這個(gè)問(wèn)題,我想到了將這一部分用其他顏色填充,告訴用戶(hù)這部分不是截圖內(nèi)容,部分代碼如下所示:

if (
    this.hiddenScrollBar.state &&
    diffHeight > 0 &&
    this.hiddenScrollBar.fillState
) {
    // 填充容器的剩余部分
    imgContext.beginPath();
    let fillWidth = containerWidth;
    let fillHeight = diffHeight;
    if (this.hiddenScrollBar.fillWidth > 0) {
        fillWidth = this.hiddenScrollBar.fillWidth;
    }
    if (this.hiddenScrollBar.fillHeight > 0) {
        fillHeight = this.hiddenScrollBar.fillHeight;
    }
    imgContext.rect(0, fixHeight, fillWidth, fillHeight);
    imgContext.fillStyle = this.hiddenScrollBar.color;
    imgContext.fill();
}

使用窗口截圖模式

通過(guò)上個(gè)章節(jié)的分析,我們發(fā)現(xiàn)使用標(biāo)簽頁(yè)截圖時(shí)出現(xiàn)擠壓的根本原因在于共享彈窗會(huì)出現(xiàn)在頁(yè)面的頂部。那么,有沒(méi)有什么辦法能做到不讓這個(gè)共享彈窗出現(xiàn)在最頂部呢?

帶著這個(gè)疑問(wèn),我在chrome的開(kāi)發(fā)文檔中找到了displaySurface選項(xiàng),將這個(gè)值設(shè)為window,它的共享彈窗就不會(huì)出現(xiàn)了。部分代碼如下所示:

let mediaWidth = window.screen.width * this.dpr;
let mediaHeight = window.screen.height * this.dpr;
navigator.mediaDevices.getDisplayMedia({
    audio: false,
    video: {
        width: mediaWidth,
        height: mediaHeight,
        displaySurface: "window"
    }
});

圖片

網(wǎng)頁(yè)標(biāo)題欄會(huì)出現(xiàn)錄制圖標(biāo)

圖片

但是,這樣子做我們拿到的是整個(gè)瀏覽器窗口的截圖,我們想要的是body區(qū)域的截圖內(nèi)容。 因此,還需要對(duì)截圖內(nèi)容做進(jìn)一步的裁剪處理,我們可以知道瀏覽器窗口的寬高、body區(qū)域的寬高。那么,用瀏覽器窗口的寬高減去body區(qū)域的寬高,我們就拿到了body區(qū)域的裁剪坐標(biāo)。部分代碼如下所示:

/**
   * 從窗口數(shù)據(jù)流中截取頁(yè)面body內(nèi)容
   * @param videoWidth 窗口寬度
   * @param videoHeight 窗口高度
   * @param containerWidth body內(nèi)容寬度
   * @param containerHeight body內(nèi)容高度
   * @private
   */
  private getWindowContentData(
    videoWidth: number,
    videoHeight: number,
    containerWidth: number,
    containerHeight: number
  ) {
    const videoCanvas = document.createElement("canvas");
    videoCanvas.width = videoWidth;
    videoCanvas.height = videoHeight;
    const videoContext = getCanvas2dCtx(videoCanvas, videoWidth, videoHeight);
    if (videoContext) {
      videoContext.drawImage(this.videoController, 0, 0);
      const startX = 0;
      const startY = videoHeight - containerHeight;
      const width = containerWidth;
      const height = videoHeight - startY;
      // 獲取裁剪框區(qū)域圖片信息;
      return videoContext.getImageData(
        startX * this.dpr,
        startY * this.dpr,
        width * this.dpr,
        height * this.dpr
      );
    }
    return null;
  }

思考與分析

使用當(dāng)前標(biāo)簽頁(yè)進(jìn)行截圖相對(duì)而言用戶(hù)體驗(yàn)是最好的,但是因?yàn)閏hrome 112版本的bug會(huì)造成頁(yè)面內(nèi)容擠壓導(dǎo)致截取到的內(nèi)容不完整,因此只能采用其他方案來(lái)解決此問(wèn)題了。窗口截圖模式和隱藏滾動(dòng)條都可以解決這個(gè)問(wèn)題,但是他們都有缺點(diǎn):

  • 窗口截圖模式可以完美的獲取屏幕截圖,但是用戶(hù)授權(quán)時(shí)會(huì)出現(xiàn)其他的應(yīng)用程序選項(xiàng),用戶(hù)體驗(yàn)會(huì)差一些。
  • 隱藏滾動(dòng)條方案還是采用標(biāo)簽頁(yè)截圖,但是會(huì)造成內(nèi)容擠壓,底部出現(xiàn)空白。

這兩種方案都是不完美的,希望Chrome能在后續(xù)的版本更新中修復(fù)此問(wèn)題。窗口模式截圖我有找過(guò)能否讓授權(quán)列表中只包含當(dāng)前窗口選項(xiàng),我在Chrome的開(kāi)發(fā)文檔中找到了Google對(duì)此情況的解釋。

圖片

項(xiàng)目地址

本文所列舉的代碼完整內(nèi)容請(qǐng)移步:

  • hiddenScrollBar-main.ts
  • wrcWindowMode-main.ts
  • getWindowContentData-main.ts
責(zé)任編輯:武曉燕 來(lái)源: 神奇的程序員
相關(guān)推薦

2011-05-18 09:23:00

Chrome OS

2017-03-21 11:42:29

Linux安裝Python 3.6

2023-06-26 07:47:09

2012-11-16 09:50:32

Windbg

2009-12-14 15:36:19

Visual Stud

2009-11-23 09:22:22

Chrome OSlinux內(nèi)核

2009-12-14 13:22:50

VS2008版本

2021-09-23 16:47:12

Chrome谷歌瀏覽器

2015-07-27 16:48:57

PPT文檔

2010-06-08 09:45:27

openSUSE 11

2012-05-07 23:45:54

FantomJavaJVM

2012-03-06 13:45:43

JavaJActor

2010-09-27 12:42:15

JVM1.4.1JVM垃圾收集

2020-07-10 06:40:31

Python 3.9Python開(kāi)發(fā)

2018-12-18 14:15:27

Windows 10語(yǔ)言版本錯(cuò)誤

2022-10-09 12:12:37

配置漂移

2020-12-16 10:42:21

人工智能智能建筑IoT

2010-08-26 17:08:20

vsftpd faq

2009-07-08 16:45:07

Servlet 2.5

2009-06-18 09:14:47

Spring modu
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)