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

快速入門 WebRTC:屏幕和攝像頭的錄制、回放、下載

開發(fā) 前端
今天我們就來實(shí)現(xiàn)下采集的部分,來快速入下門,直觀感受下 WebRTC 能做什么吧。我們會(huì)實(shí)現(xiàn)屏幕的錄制、攝像頭的錄制,并且能夠回放錄制的內(nèi)容,還支持下載。

[[441095]]

不知你是否用過 web 版的視頻面試,或者 web 版在線會(huì)議,它們都支持分享屏幕、也能開啟攝像頭。這些都是瀏覽器上實(shí)現(xiàn)的,作為前端開發(fā),是否好奇過這些功能的實(shí)現(xiàn)原理呢?

瀏覽器上的音視頻通信相關(guān)的能力叫做 WebRTC(real time communication),是隨著網(wǎng)速越來越快、音視頻需求越來越多,而被瀏覽器所實(shí)現(xiàn)的音視頻的標(biāo)準(zhǔn) API。

音視頻通信的流程有五步:采集、編碼、通信、解碼、渲染。

這五步比較好理解,但是每一步都有挺多內(nèi)容的。

今天我們就來實(shí)現(xiàn)下采集的部分,來快速入下門,直觀感受下 WebRTC 能做什么吧。

我們會(huì)實(shí)現(xiàn)屏幕的錄制、攝像頭的錄制,并且能夠回放錄制的內(nèi)容,還支持下載。

那我們開始吧。

思路分析

瀏覽器提供了 navigator.mediaDevices.getDisplayMedia 和 navigator.mediaDevices.getUserMedia 的 api,分別可以用來獲取屏幕的流、麥克風(fēng)和攝像頭的流。

從名字就可以看出來 getDisplayMedia 獲取的是屏幕的流,getUserMedia 獲取的是和用戶相關(guān)的,也就是麥克風(fēng)、攝像頭這些的流。

獲取流之后設(shè)置到 video 的 srcObject 屬性上就可以實(shí)現(xiàn)播放。

如果想要錄制視頻,需要用 MediaRecorder 的 api,它可以監(jiān)聽流中的數(shù)據(jù),我們可以把獲取到的數(shù)據(jù)保存到數(shù)組中。然后回放的時(shí)候設(shè)置到另一個(gè)視頻的 srcObject 屬性就可以了。

下載也是基于 MediaRecorder 錄制的數(shù)據(jù),轉(zhuǎn)成 blob 后通過 a 標(biāo)簽觸發(fā)下載。

大概理清了思路,我們來寫下代碼。

代碼實(shí)現(xiàn)

我們在頁面放兩個(gè) video 標(biāo)簽,一個(gè)用于實(shí)時(shí)的看錄制的視頻,一個(gè)用于回放。

然后放幾個(gè)按鈕。

  1. <selection> 
  2.     <video autoplay id = "player"></video> 
  3.     <video id = "recordPlayer"></video> 
  4. </selection> 
  5. <section>  
  6.     <button id = "startScreen">開啟錄屏</button> 
  7.     <button id = "startCamera">開啟攝像頭</button> 
  8.     <button id = "stop">結(jié)束</button> 
  9.     <button id = "reply">回放</button> 
  10.     <button id = "download">下載</button> 
  11. </selection> 

 

“開始錄屏” 和 “開啟攝像頭” 按鈕點(diǎn)擊的時(shí)候都開啟錄制,但是方式不同。

  1. startScreenBtn.addEventListener('click', () => { 
  2.     record('screen'); 
  3. }); 
  4. startCameraBtn.addEventListener('click', () => { 
  5.     record('camera'); 
  6. }); 

一個(gè)是用 getUserMedia 的 api 來獲取麥克風(fēng)、攝像頭數(shù)據(jù),一個(gè)是用 getDisplayMedia 的 api 獲取屏幕數(shù)據(jù)。

  1. async function record(recordType) { 
  2.     const getMediaMethod = recordType === 'screen' ? 'getDisplayMedia' : 'getUserMedia'
  3.     const stream = await navigator.mediaDevices[getMediaMethod]({ 
  4.         video: { 
  5.             width: 500, 
  6.             height: 300, 
  7.             frameRate: 20 
  8.         } 
  9.     }); 
  10.  
  11.     player.srcObject = stream; 

指定下寬高和幀率等參數(shù),把返回的流設(shè)置到 video 的 srcObject 屬性上,就可以實(shí)時(shí)看到對(duì)應(yīng)的音視頻。

然后,還要做錄制,需要用 MediaRecorder 的 api,傳入 stream,然后調(diào)用 start 方法,開啟錄制。

  1. let blobs = [], mediaRecorder; 
  2.  
  3. mediaRecorder = new MediaRecorder(stream, { 
  4.     mimeType: 'video/webm' 
  5. }); 
  6. mediaRecorder.ondataavailable = (e) => { 
  7.     blobs.push(e.data); 
  8. }; 
  9. mediaRecorder.start(100); 

start 的參數(shù)是分割的大小,傳入 100 代表每 100ms 保存一次數(shù)據(jù)。

監(jiān)聽 dataavailable 事件,在其中把獲取到的數(shù)據(jù)保存到 blobs 數(shù)組中。

之后根據(jù) blobs 數(shù)組生成 blob,就可以分別做回放和下載了:

回放:

  1. replyBtn.addEventListener('click', () => { 
  2.     const blob = new Blob(blobs, {type : 'video/webm'}); 
  3.     recordPlayer.src = URL.createObjectURL(blob); 
  4.     recordPlayer.play(); 
  5. }); 

blob 要經(jīng)過 URL.createObjectURL 的處理,才能作為 object url 來被播放。

下載:

  1. download.addEventListener('click', () => { 
  2.     var blob = new Blob(blobs, {type: 'video/webm'}); 
  3.     var url = URL.createObjectURL(blob); 
  4.  
  5.     var a = document.createElement('a'); 
  6.     a.href = url; 
  7.     a.style.display = 'none'
  8.     a.download = 'record.webm'
  9.     a.click(); 
  10. }); 

生成一個(gè)隱藏的 a 標(biāo)簽,設(shè)置 download 屬性就可以支持下載。然后觸發(fā) click 事件。

目前為止,我們已經(jīng)實(shí)現(xiàn)了麥克風(fēng)、攝像頭、屏幕的錄制,支持了回放和下載。

這里也貼一份:

  1. <html> 
  2. <head> 
  3.         <title>錄屏并下載</title> 
  4. </head> 
  5. <body> 
  6.         <selection> 
  7.                 <video autoplay id = "player"></video> 
  8.                 <video id = "recordPlayer"></video> 
  9.         </selection> 
  10. <section>  
  11.     <button id = "startScreen">開啟錄屏</button> 
  12.     <button id = "startCamera">開啟攝像頭</button> 
  13.     <button id = "stop">結(jié)束</button> 
  14.     <button id = "reply">回放</button> 
  15.     <button id = "download">下載</button> 
  16.         </selection> 
  17.  
  18. <script> 
  19.     const player = document.querySelector('#player'); 
  20.     const recordPlayer = document.querySelector('#recordPlayer'); 
  21.     let blobs = [], mediaRecorder; 
  22.  
  23.     async function record(recordType) { 
  24.         const getMediaMethod = recordType === 'screen' ? 'getDisplayMedia' : 'getUserMedia'
  25.         const stream = await navigator.mediaDevices[getMediaMethod]({ 
  26.             video: { 
  27.                 width: 500, 
  28.                 height: 300, 
  29.                 frameRate: 20 
  30.             } 
  31.         }); 
  32.         player.srcObject = stream; 
  33.  
  34.         mediaRecorder = new MediaRecorder(stream, { 
  35.             mimeType: 'video/webm' 
  36.         }); 
  37.         mediaRecorder.ondataavailable = (e) => { 
  38.             blobs.push(e.data); 
  39.         }; 
  40.         mediaRecorder.start(100); 
  41.     } 
  42.  
  43.     const downloadBtn = document.querySelector('#download'); 
  44.     const startScreenBtn = document.querySelector('#startScreen'); 
  45.     const startCameraBtn = document.querySelector('#startCamera'); 
  46.     const stopBtn = document.querySelector('#stop'); 
  47.     const replyBtn = document.querySelector('#reply'); 
  48.  
  49.     startScreenBtn.addEventListener('click', () => { 
  50.         record('screen'); 
  51.     }); 
  52.     startCameraBtn.addEventListener('click', () => { 
  53.         record('camera'); 
  54.     }); 
  55.  
  56.     stopBtn.addEventListener('click', () => { 
  57.         mediaRecorder && mediaRecorder.stop(); 
  58.     }); 
  59.  
  60.     replyBtn.addEventListener('click', () => { 
  61.         const blob = new Blob(blobs, {type : 'video/webm'}); 
  62.         recordPlayer.src = URL.createObjectURL(blob); 
  63.         recordPlayer.play(); 
  64.     }); 
  65.  
  66.     download.addEventListener('click', () => { 
  67.         var blob = new Blob(blobs, {type: 'video/webm'}); 
  68.         var url = URL.createObjectURL(blob); 
  69.  
  70.         var a = document.createElement('a'); 
  71.         a.href = url; 
  72.         a.style.display = 'none'
  73.         a.download = 'record.webm'
  74.         a.click(); 
  75.     }); 
  76. </script> 
  77. </body> 
  78. </html> 

總結(jié)

音視頻通信分為 采集、編碼、通信、解碼、渲染 這五步,瀏覽器的音視頻通信相關(guān)的 API 叫做 WebRTC。

我們實(shí)現(xiàn)了下采集的部分來入門了下 WebRTC,還支持了回放和下載。

涉及到的 api 有 3 個(gè):

  • navigator.mediaDevices.getUserMedia:獲取麥克風(fēng)、攝像頭的流
  • navigator.mediaDevices.getDisplayMedia:獲取屏幕的流
  • MediaRecorder:監(jiān)聽流的變化,實(shí)現(xiàn)錄制

我們分別用前兩個(gè) api 獲取到了屏幕、麥克風(fēng)、攝像頭的流,然后用 MediaRecorder 做了錄制,把數(shù)據(jù)保存到數(shù)組中,之后生成了 Blob。

video 可以設(shè)置 srcObject 屬性為一個(gè)流,這樣能直接播放,如果設(shè)置 Blob 的話需要用 URL.createObjectURL 處理下。

下載的實(shí)現(xiàn)是通過 a 標(biāo)簽指向 Blob 對(duì)象的 object url,通過 download 屬性指定下載行為,然后手動(dòng)觸發(fā) click 來下載。

我們學(xué)會(huì)了如何用 WebRTC 來采集數(shù)據(jù),這是音視頻通信的數(shù)據(jù)來源,之后還要實(shí)現(xiàn)編解碼和通信才能是完整 RTC 流程,這些后續(xù)再深入。

我們直觀的感受了下 WebRTC 能做什么,是不是感覺這個(gè)領(lǐng)域也挺有趣的呢?

 

責(zé)任編輯:姜華 來源: 神光的編程秘籍
相關(guān)推薦

2009-10-22 09:00:10

Windows 7攝像工具

2017-06-20 11:45:52

2021-03-11 10:21:55

特斯拉黑客網(wǎng)絡(luò)攻擊

2013-03-21 09:56:09

2024-11-29 16:51:18

2011-04-25 09:16:10

Windows 8

2012-06-23 20:13:44

HTML5

2023-01-13 08:00:00

人工智能攝像頭人臉識(shí)別

2022-05-12 09:25:19

Python播放視頻攝像頭

2009-06-17 11:52:01

Linux

2009-08-21 17:24:18

C#控制攝像頭

2023-05-26 16:42:28

2011-09-08 13:53:20

Linux攝像頭

2025-01-13 00:00:30

WinForm應(yīng)用開發(fā)

2022-04-15 11:30:59

代碼,Python保存視頻

2014-07-16 13:36:30

MotionLinux監(jiān)控

2018-06-20 11:54:54

2011-09-13 15:51:11

PhoneGap AP

2020-06-04 10:59:10

JavaScript開發(fā)技術(shù)

2014-05-12 10:57:41

TermRecord終端會(huì)話
點(diǎn)贊
收藏

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