基於H5的錄屏工具開發

1. 概述

WebRTC是谷歌於2011年開源的一個音視頻處理引擎,能夠實時的進行視頻數據的採集,也就是說能夠作直播,也能夠作桌面錄屏桌面分享。使用起來仍是比較簡單的。html

2. 錄屏工具開發

這裏開發一個屏幕錄製工具。首先在頁面中建立一個video標籤,用於展現錄屏的內容,再建立四個按鈕,一個屏幕分享,一個開始錄製,一個中止錄製,一個下載視頻web

<button id="start">屏幕分享</button>
<button id="record">開始錄製</button>
<button id="stop">結束錄製</button>
<button id="download">下載視頻</button>
<video autoplay playsinline id="player"></video>
複製代碼

當點擊屏幕分享按鈕的時候,經過getDisplayMedia方法來獲取桌面的媒體流,這裏須要傳入一個對象做爲配置,對象中能夠對videoaudio進行設置,值能夠是布爾類型也能夠是對象類型,這裏先設置布爾值,採集視頻,不採集音頻。api

返回值是一個Promise,而後在Promisethen中將流媒體賦值給video標籤的srcObject屬性就能夠了,很是的簡單。數組

document.querySelector('#start').onclick = function() {
    if (navigator.mediaDevices && navigator.mediaDevices.getDisplayMedia) {
        navigator.mediaDevices.getDisplayMedia({
            video: true,
            audio: false
        }).then((stream) => {
            document.querySelector('#player').srcObject = stream;
        }).catch((err) => {
            console.error(err);
        })
    } else {
        alert('不支持這個特性');
    }
}
複製代碼

當點擊屏幕分享按鈕時,瀏覽器會彈出選項詢問錄製哪部份內容,這裏能夠選擇錄製整個屏幕,或者是某個應用的界面,還能夠是瀏覽器的指定標籤頁。瀏覽器

好比這裏選擇錄製整個屏幕,此時video標籤中就會顯示我電腦屏幕中的內容了。緩存

使用getDisplayMedia是能夠將屏幕內容採集到的,若是想要將內容錄製下來而且下載到本地需求使用WebRTC提供的另一個類MediaRecordermarkdown

他有不少的事件和方法。使用也很是簡單。直接實例化就能夠了。須要傳入兩個參數,第一個是stream,也就是經過getDisplayMedia拿到的媒體流,第二個是可選參數。主要有mimeType指定錄製的是音頻仍是視頻,錄製的格式是什麼。ide

格式有不少好比谷歌的音視頻格式video/webm, audio/webm, 還能夠設置爲mp4, 也能夠指定視頻的編碼video/webm;codecs=vp8, video/webm;codecs=h264, 或者指定音頻編碼audio/webm;codecs=opus工具

new MediaRecorder(stream, [, options]);
複製代碼

MediaRecorderapi也比較多,第一個是MediaRecorder.start(timeslice)意思是開啓錄製,timeslice是一個可選參數,若是不設置會存儲在一個大的buffer中,若是設置了這個參數就會按照時間段存儲數據,好比說10s存儲一塊數據。ui

MediaRecorder.start()是關閉錄製,當中止錄製時會觸發dataavailable事件,獲得最終的blob數據。

MediaRecorder.pause()暫停錄製

MediaRecorder.resume()恢復錄製

MediaRecorder.isTypeSupported()檢查是否支持要錄製的文件格式。好比mp4,webm,mp3等格式。

除了這些方法,還存在不少的事件,通常經常使用事件有兩個,第一個是ondataavailable當收集到的數據有效就會觸發這個事件,因此能夠監聽這個事件,當獲取到數據能夠把這個數據存儲在緩存區中,能夠在e.data中獲得。這個事件的執行實際由timeslice決定,若是沒有指定則記錄整個數據。若是指定了就會定時觸發。

onerror錯誤的時候會觸發這個事件,錄製會自動中止。

這裏改造一下,將getDisplayMedia獲取到的流媒體再也不直接賦值給video標籤,而是經過MediaRecorder存儲起來,再轉換給video,這樣不光能夠賦值給video,並且stream實現了存儲也能夠下載下來。將getDisplayMedia返回的內容存儲到全局的allStream中。

let allStream;
document.querySelector('#start').onclick = function() {
    if (navigator.mediaDevices && navigator.mediaDevices.getDisplayMedia) {
        navigator.mediaDevices.getDisplayMedia({
            video: true,
            audio: false
        }).then((stream) => {
            allStream = stream;
            document.querySelector('#player').srcObject = stream;
        }).catch((err) => {
            console.error(err);
        })
    } else {
        alert('不支持這個特性');
    }
}
複製代碼

當點擊開始錄製按鈕時, 首先須要使用MediaRecorder.isTypeSupported方法判斷瀏覽器是否支持這種視頻格式。

而後開始建立MediaRecorder對象,傳入allStream對象和配置對象,這裏只配置了視頻格式爲webm格式。

接着要綁定ondataavailable事件方法,這個事件會處理採集到的流媒體。其實也就是將數據存儲到外部變量buf中。

最後執行mediaRecorder.start開始錄製。

let buf = [];
let mediaRecorder;

document.querySelector('#record').onclick = function() {
    // 約束視頻格式
    const options = {
        mimeType: 'video/webm;codecs=vp8'
    }
    // 判斷是不是支持的mimeType格式
    if (!MediaRecorder.isTypeSupported(options.mimeType)) {
        console.error('不支持的視頻格式');
        return;
    }
    try {
        mediaRecorder = new MediaRecorder(allStream, options);
        // 處理採集到的事件
        mediaRecorder.ondataavailable = function(e) {
            if (e && e.data && e.data.size > 0) {
                // 存儲到數組中
                buf.push(e.data);
            }
        };
        // 開始錄製
        mediaRecorder.start(10);
    } catch (e) {
        console.error(e);
    }
}
複製代碼

這樣就能夠實現頁面的錄屏了。下載功能須要藉助Blob類型來實現,建立Blob類型支持傳入一個buffer參數和指定buffer內容的類型,。

當點擊下載按鈕的時候,要結束錄製,也就是調用mediaRecorderstop方法,還要判斷buf是否存在內容,萬一有人沒錄製直接點擊下載呢,得防範....

使用new方法建立Blol實例,傳入錄製的buf媒體類型,注意這裏的類型要和以前錄製的一導致用webm

接着使用URLcreateObjectURL方法將blob轉換爲地址連接。下載就比較簡單了,建立一個a標籤,而後將視頻連接賦值到a標籤的href中,文件名稱就是a標籤的download屬性。最後自動觸發a標籤的click事件就能夠了。

document.querySelector('#download').onclick = function() {
    mediaRecorder.stop();
    if (buf.length) {
        const blob = new Blob(buf, { type: 'video/webm'});
        const url = window.URL.createObjectURL(blob);
        const a = document.createElement('a');
        a.href = url;
        a.style.display = 'none';
        a.download = 'aaa.webm';
        a.click();
    } else {
        alert('尚未錄製任何內容');
    }
}
複製代碼

一樣點擊屏幕分享會彈出選擇窗口的頁面。

而後點擊開始錄製按鈕,桌面上就會出現一個正在錄屏的標記。

最後點擊下載按鈕,錄製的視頻就被下載下來啦。由於我以前已經下載過了,因此這裏瀏覽器自動給我加了一個(1)

打開這個視頻看一下。

結束錄製就是調用一下mediaRecorder對象的stop方法。

document.querySelector('#stop').onclick = function() {
    if (mediaRecorder) {
        mediaRecorder.stop();
    }
}
複製代碼

至此屏幕錄製就說完了。對了,這個功能只能在https環境中運行,本地開發能夠支持127.0.0.1或者localhost。若是部署正式別忘記使用https

WebRTC也是能夠從攝像頭中獲取視頻流的,只須要將getDisplayMedia替換成getUserMedia就能夠了。

document.querySelector('#start').onclick = function() {
    if (navigator.mediaDevices && navigator.mediaDevices.getUserMedia) {
        navigator.mediaDevices.getUserMedia({
            video: true,
            audio: false
        }).then((stream) => {
            document.querySelector('#player').srcObject = stream;
        }).catch((err) => {
            console.error(err);
        })
    } else {
        alert('不支持這個特性');
    }
}
複製代碼

WebRTC比較高級的功能是音視頻直播,共享遠程桌面,即時通訊等,谷歌但願將WebRTC用做瀏覽器之間實現音視頻通話這種快速的開發使用的。不過這些功能開發起來比較複雜,有時間再來介紹。

相關文章
相關標籤/搜索