前端屏幕录制示例

 

示例一:只有画面,没有声音

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <meta http-equiv="X-UA-Compatible" content="ie=edge" />
    <title>rrweb demo web site</title>
    <script crossorigin="anonymous" src="https://cdn.jsdelivr.net/npm/rrweb@latest/dist/rrweb.min.js"></script>
    <script crossorigin="anonymous" src="https://cdn.jsdelivr.net/npm/rrweb@latest/dist/record/rrweb-record.min.js"></script>
    <link rel="stylesheet" crossorigin="anonymous"
          href="https://cdn.jsdelivr.net/npm/rrweb-player@latest/dist/style.css" />
    <script crossorigin="anonymous" src="https://cdn.jsdelivr.net/npm/rrweb-player@latest/dist/index.js"></script>
</head>

<body>
<h1 class="some-title">this is some title for test</h1>
<input type="button" value="开始录制" onclick="record()" />
<br />
<input type="button" value="结束录制" onclick="replay()" />
<div id="replaycontent">

</div>
<script>
    window.events = [];

    function record() {
        rrweb.record({
            emit(event) {
// 将 event 存入 events 数组中
                events.push(event);
                console.log(event);
            },
        });
    }

    function replay() {
        new rrwebPlayer({
            target: document.getElementById("replaycontent"), // 可以自定义 DOM 元素
            data: {
                events,
            },
        });
    }
    // save 函数用于将 events 发送至后端存入,并重置 events 数组
    function save() {
        const body = JSON.stringify(window.events);
        console.log(body)
        events = [];
        // fetch("http://localhost:8080/api", {
        fetch("D://", {

            method: "POST",
            headers: {
                "Content-Type": "application/json",
            },
            body,
        });
    }
    // 每 10 秒调用一次 save 方法,避免请求过多
    // setInterval(save, 10 * 1000);
</script>
</body>

</html>

示例二:基于分享页面来实现

<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="utf-8">
    <title>在线屏幕录制</title>
    <style>
        body{
            font-family: Arial;
            margin: 4vh auto;
            width: 90vw;
            max-width: 600px;
            text-align: center;
        }
        #controls{
            text-align: center;
        }
        .btn{
            margin: 10px 5px;
            padding: 15px;
            background-color: #2bcbba;
            border: none;
            color: white;
            font-weight: bold;
            border-radius: 6px;
            outline: none;
            font-size: 1.2em;
            width: 120px;
            height: 50px;
        }
        .btn:hover{
            background-color: #26de81;
            cursor: hand;
        }
        .btn:disabled{
            background-color: #2bcbba80;
        }
        #stop{
            background-color: #fc5c65;
        }
        #video{
            margin-top: 10px;
            margin-bottom: 20px;
            border: 12px solid #a5adb0 ;
            border-radius: 15px;
            outline: none;
            width: 100%;
            height: 400px;
            background-color: black;
        }
        h1{
            color: #2bcbba;
            letter-spacing:-2.5px;
            line-height: 30px;
        }
        .created{
            color: lightgrey;
            letter-spacing: -0.7px;
            font-size: 1em;
            margin-top: 40px;
        }
        .created > a{
            color: #4b7bec;
            text-decoration: none;
        }
    </style>
</head>

<body>
<h1><u style='color:#fc5c65'>在线屏幕录制</u><br>支持 :新版本 Chrome,Edge,Firefox 桌面浏览器  <br></h1>
<video autoplay='true' id='video' controls='true' controlsList='nodownload'></video>
<button class='btn' id='record' onclick='record()'>录制</button>
<button style='display: none' class='btn' id='stop' onclick='stop()'>停止</button>
<button disabled='true' class='btn' id='download' onclick='download()'>下载</button>
<div class='created'>  </div>
</body>
<script>
    const video = document.getElementById('video')
    const downloadBtn = document.getElementById('download')
    const recordBtn = document.getElementById('record')
    const stopBtn = document.getElementById('stop')
    let recorder

    async function record() {
        // 开始录屏
        let captureStream

        try{
            captureStream = await navigator.mediaDevices.getDisplayMedia({
                video: true,
                // audio: true,   not support
                cursor: 'always'
            })
        }catch(e){
            // 取消录屏或者报错
            alert("Could not get stream")
            return
        }

        downloadBtn.disabled = true
        recordBtn.style = 'display: none'
        stopBtn.style = 'display: inline'

        // 删除之前的 Blob
        window.URL.revokeObjectURL(video.src)

        video.autoplay = true

        // 实时的播放录屏
        video.srcObject = captureStream

        // new 一个媒体记录
        recorder = new MediaRecorder(captureStream)
        recorder.start()

        captureStream.getVideoTracks()[0].onended = () => {
            // 录屏结束完成
            recorder.stop()
        }

        recorder.addEventListener("dataavailable", event => {
            // 录屏结束,并且数据可用
            console.log("dataavailable------------")
            let videoUrl = URL.createObjectURL(event.data, {type: 'video/ogg'})

            video.srcObject = null
            video.src = videoUrl
            video.autoplay = false

            downloadBtn.disabled = false
            recordBtn.style = 'display: inline'
            stopBtn.style = 'display: none'
        })
    }

    function download(){
        // 下载
        const url = video.src
        const name = new Date().toISOString().slice(0, 19).replace('T',' ').replace(" ","_").replace(/:/g,"-")
        const a = document.createElement('a')

        a.style = 'display: none'
        a.download = `${name}.ogg`
        a.href = url

        document.body.appendChild(a)

        a.click()
    }

    function stop(){
        let tracks = video.srcObject.getTracks()
        tracks.forEach(track => track.stop())
        recorder.stop()
    }
</script>
</html>

示例三:单独录制声音

<!DOCTYPE html>

<html>

<head>

    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />

    <title>小猿圈</title>

</head>

<body>

<div>

    <audio autoplay></audio>

    <input onclick="startRecording()" type="button" value="录音" />

    <input onclick="stopRecording()" type="button" value="停止" />

    <input onclick="playRecording()" type="button" value="播放" />

    <input onclick="uploadAudio()" type="button" value="提交" />

    <br />

    <div id="recordingslist"></div>

</div>

<script type="text/javascript" src="./HZRecorder.js"></script>

<script>

    var recorder;

    var audio = document.querySelector('audio');

    function startRecording() {

        HZRecorder.get(function(rec) {

            recorder = rec;

            recorder.start();

        }, {

            sampleBits: 16,

            sampleRate: 16000

        });

    }

    function stopRecording() {

        recorder.stop();

        var blob = recorder.getBlob();

        var url = URL.createObjectURL(blob);

        var div = document.createElement('div');

        var au = document.createElement('audio');

        var hf = document.createElement('a');

        au.controls = true;

        au.src = url;

        hf.href = url;

        hf.download = new Date().toISOString() + '.wav';

        hf.innerHTML = hf.download;

        div.appendChild(au);

        div.appendChild(hf);

        recordingslist.appendChild(div);

    }

    function playRecording() {

        recorder.play(audio);

    }

    function uploadAudio() {

        recorder.upload("Handler1.ashx", function(state, e) {

            switch(state) {

                case 'uploading':

//var percentComplete = Math.round(e.loaded * 100 / e.total) + '%';

                    break;

                case 'ok':

//alert(e.target.responseText);

                    alert("上传成功");

                    break;

                case 'error':

                    alert("上传失败");

                    break;

                case 'cancel':

                    alert("上传被取消");

                    break;

            }

        });

    }

</script>

</body>

</html>

示例四:可以录制视频和声音可以截图和下载,但是只能录制一条流

<!doctype html>
<html lang="en">
<head>
    <meta charset="utf-8" />
    <title></title>
    <style>
        video {
            border: 1px solid #ccc;
            display: block;
            margin: 0 0 20px 0;
            float:left;
        }
        canvas {
            margin-top: 20px;
            border: 1px solid #ccc;
            display: block;
        }
    </style>
</head>
<body>
<video width="640" height="480" id="myVideo"></video>
<canvas width="640" height="480" id="myCanvas"></canvas>

<button id="startVideo">开始录制</button>
<button id="endVideo">结束录制</button>
<button id="myButton">截图</button>
<button id="myButton3">
    <a download="video.png">另存为</a>
</button>
</body>
<script>
    window.addEventListener('DOMContentLoaded',function(){
        var cobj=document.getElementById('myCanvas').getContext('2d');
        var vobj=document.getElementById('myVideo');
        getUserMedia({video:true,audio:true},function(stream){
            console.log(stream)
            // vobj.src=stream;
            try {
                vobj.srcObject = stream;
            } catch (e) {
                try {
                    vobj.src = URL.createObjectURL(stream);
                } catch (e) {
                    console.error("Error attaching stream to element");
                }
            }

            vobj.play();

            let options = {
                audioBitsPerSecond : 128000,  // 音频码率
                videoBitsPerSecond : 100000,  // 视频码率
                mimeType:'video/webm;codecs=h264'
            }
            let localMediaRecorder = new MediaRecorder(stream, options)

            document.getElementById("startVideo").addEventListener("click",function(){
                // 开始采集
                localMediaRecorder.start()
                console.log('开始采集')
            })

            document.getElementById("endVideo").addEventListener("click",function(){
                // 停止采集
                localMediaRecorder.stop()
                console.log('停止采集')
            })
            // 事件
            localMediaRecorder.ondataavailable = function (e) {
                console.log(e)
                // 下载视频
                var blob = new Blob([e.data], { 'type' : 'video/mp4' })
                let a = document.createElement('a')
                a.href = URL.createObjectURL(blob)
                alert(URL.createObjectURL(blob))
                a.download = `test.mp4`
                a.click()
            }
        },function(){});

        document.getElementById('myButton').addEventListener('click',function(){
            cobj.drawImage(vobj,0,0,640,480);
            document.getElementById('myButton3').children[0].href=cobj.canvas.toDataURL("image/png");
        },false);

    },false);



    function getUserMedia(obj,success,error){
        // if(navigator.getUserMedia){
        //     alert("1"+navigator.getUserMedia)
            getUserMedia=function(obj,success,error){
                navigator.getUserMedia(obj,function(stream){
                    success(stream);
                },error);
            }
        // }else if(navigator.webkitGetUserMedia){
        //     alert("2"+navigator.webkitGetUserMedia)
        //     getUserMedia=function(obj,success,error){
        //         navigator.webkitGetUserMedia(obj,function(stream){
        //             var _URL=window.URL || window.webkitURL;
        //             success(_URL.createObjectURL(stream));
        //         },error);
        //     }
        // }else if(navigator.mozGetUserMedia){
        //     alert("3"+navigator.mozGetUserMedia)
        //     getUserMedia=function(obj,success,error){
        //         navigator.mozGetUserMedia(obj,function(stream){
        //             success(window.URL.createObjectURL(stream));
        //         },error);
        //     }
        // }else{
        //     return false;
        // }
        return getUserMedia(obj,success,error);
    }
</script>
</html>

 

posted @ 2021-03-04 15:03  皮军旗  阅读(458)  评论(0)    收藏  举报