這里給大家分享我在網(wǎng)上總結(jié)出來的一些知識,希望對大家有所幫助
前言
要在 JavaScript 中實現(xiàn)屏幕錄制,可以使用 navigator.mediaDevices.getDisplayMedia()
方法來獲取屏幕的媒體流。然后,可使用 MediaRecorder
對象將媒體流錄制為視頻文件。
但該方法會在瀏覽器彈出一個授權(quán)窗口,讓用戶選擇要分享的內(nèi)容,這不可實現(xiàn)“無感知”。
如果真正做到無感知,那我們就不能借助瀏覽器或者系統(tǒng)系統(tǒng)的能力了。我們能做的就只能是通過js去操作了。
要在頁面內(nèi)直接錄制視頻似乎并不容易,沒有現(xiàn)成的開源庫可以使用,也沒有很好的想法。
那我們換一個思路,視頻是由幀組成的,我們是否可以不斷的截圖,然后組合成一段視頻?好像是可以的
頁面
先寫一個簡單的頁面:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Canvas視頻錄制</title> <link rel="stylesheet" href="styles.css"> </head> <body> <main> <div class="buttons"> <button class="start-btn">開始錄制</button> <button class="pause-btn">暫停錄制</button> <button class="resume-btn">繼續(xù)錄制</button> <button class="stop-btn">結(jié)束錄制</button> </div> <div id="box"> <section class="content"> <h2>TODO LIST</h2> <div class="background-div"> <button class="background-btn">切換背景顏色</button> </div> <div id="todo-form"> <input type="text" class="input-field" placeholder="輸入待辦事項"> <button type="submit" class="submit-btn">提交</button> </div> <div class="list"></div> </section> </div> <img src="" alt="" class="hidden"> </main> <script src="<https://cdn.bootcss.com/html2canvas/0.5.0-beta4/html2canvas.min.js>" defer></script> <script src="canvas.js" defer></script> </body> </html>
截圖
實現(xiàn)網(wǎng)頁的截圖操作,最常用的庫是?html2canvas
用,它可以將網(wǎng)頁中的 HTML 元素轉(zhuǎn)換為 Canvas 元素,并將其導(dǎo)出為圖像文件。在瀏覽器中捕獲整個頁面或特定區(qū)域的截圖,包括 CSS 樣式和渲染效果。
const canvasFunction = () => { html2canvas(box).then(canvas => { const imgStr = canvas.toDataURL("image/png"); img.src = imgStr; img.onload = function () { ctx.drawImage(img, 0, 0, w, h); } }); }
合成視頻
這里我們要使用到一個 API MediaRecorder
,用于在瀏覽器中進行音頻和視頻的錄制。它提供了一種簡單的方式來捕獲來自麥克風(fēng)、攝像頭或屏幕的媒體數(shù)據(jù),并將其保存為文件或進行實時流傳輸。
它有以下幾個常用的方法:
-
isTypeSupported()
返回一個 Boolean 值,來表示設(shè)置的 MIME type 是否被當(dāng)前用戶的設(shè)備支持。 -
start()
開始錄制媒體,這個方法調(diào)用時可以通過給timeslice
參數(shù)設(shè)置一個毫秒值,如果設(shè)置這個毫秒值,那么錄制的媒體會按照你設(shè)置的值進行分割成一個個單獨的區(qū)塊,而不是以默認(rèn)的方式錄制一個非常大的整塊內(nèi)容。 -
pause()
暫停媒體錄制。 -
resume()
繼續(xù)錄制之前被暫停的錄制動作。 -
stop()
停止錄制。同時觸發(fā)?dataavailable
?事件,返回一個存儲Blob
內(nèi)容的錄制數(shù)據(jù)。之后不再記錄。
首先創(chuàng)建一個 canvas
元素,用來保存 html2canvas
的截圖,然后通過 captureStream
方法實時截取媒體流。
const w = boxBoundingClientRect.width; const h = boxBoundingClientRect.height; const canvas = document.createElement('canvas'); canvas.setAttribute('id', 'canvas'); canvas.setAttribute('width', w); canvas.setAttribute('height', h); canvas.style.display = 'none'; box.appendChild(canvas); const img = document.querySelector('img'); const ctx = canvas.getContext("2d"); const allChunks = []; const stream = canvas.captureStream(60); // 60 FPS recording 1秒60幀
MediaRecorder
?實例,并在?ondataavailable
?事件中保存視頻信息:const recorder = new MediaRecorder(stream, { mimeType: 'video/webm;codecs=vp9' }); recorder.ondataavailable = (e) => { allChunks.push(e.data); };
最后,在停止錄制時將幀信息創(chuàng)建 blob 并插入到頁面上:
recorder.stop(); const fullBlob = new Blob(allChunks); const videoUrl = window.URL.createObjectURL(fullBlob); const video = document.createElement('video'); video.controls = true; video.src = videoUrl; video.muted = true; video.autoplay = true; document.body.appendChild(video);
或者可以將視頻下載
recorder.stop(); const fullBlob = new Blob(allChunks); const videoUrl = window.URL.createObjectURL(fullBlob); let link = document.createElement('a'); link.style.display = 'none'; let fullBlob = new Blob(allChunks); let downloadUrl = window.URL.createObjectURL(fullBlob); link.href = downloadUrl; link.download = 'canvas-video.mp4'; document.body.appendChild(link); link.click(); link.remove();
這里,為了節(jié)省資源,只在點擊按鈕、輸入等事件發(fā)生時才調(diào)用?html2canvas
?截圖 DOM。
如果實時記錄屏也可以使用?requestAnimationFrame
?。
最后
雖然實現(xiàn)了無感知錄制屏幕,但也僅限于網(wǎng)頁內(nèi),沒有辦法錄制網(wǎng)頁以外的部分。文章來源:http://www.zghlxwxcb.cn/news/detail-711149.html
本文轉(zhuǎn)載于:
https://juejin.cn/post/7293462197386592283
如果對您有所幫助,歡迎您點個關(guān)注,我會定時更新技術(shù)文檔,大家一起討論學(xué)習(xí),一起進步。
?文章來源地址http://www.zghlxwxcb.cn/news/detail-711149.html
到了這里,關(guān)于記錄--純前端也可以實現(xiàn)「用戶無感知錄屏」的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!