RecordRTC的基本使用

2023-09-18 14:50 姚铭强 1716

什么是recordRTC

recordRTC非常强大,适用用于音频+视频+屏幕+画布(2D + 3D动画)录制,可以调用js在chrome和火狐下录制麦克风、摄像头、屏幕的视频,并且支持暂停继续录制、可选比特率、分辨率、编码方式等

recordRTC能做什么

通过使用RecordRTC,您可以轻松地在Web应用程序中添加音频和视频录制功能,例如视频聊天、在线教育、在线会议等。它还提供了许多高级功能,例如屏幕录制、音频混合、视频剪辑等。RecordRTC是一个开源项目,可以在GitHub上找到它的源代码和文档。

recordRTC支持的浏览器

RecordRTC支持的码率

RecordRTC的使用方式

安装

npm install recordrtc

引入模块

import RecordRTC from "recordrtc";

屏幕录制

1.判断浏览器是否支持屏幕录制

 if (!navigator.getDisplayMedia && !navigator.mediaDevices.getDisplayMedia) {
        return this.{message.error("您的浏览器不支持屏幕录制")
    }

2.提示用户去选择和授权捕获展示的内容或部分内容(如一个窗口),此段代码需要考虑浏览器的兼容性问题,因此写出了两段代码

displaymediastreamconstraints的参数有

video 一个布尔值,表示是否获取视频流。默认为true。
audio 一个布尔值,表示是否获取音频流。默认为false。
cursor 一个字符串,表示是否捕获鼠标光标。可选值为"always"、"motion"和"never"。默认为"always"。
displaySurface 一个字符串,表示捕获的屏幕表面类型。可选为"monitor"、"window"和"application"。默认为"monitor"。
frameRate 一个数字,表示捕获的视频帧率。默认为10
aspectRatio 一个数字,表示捕获的视频宽高比。默认为屏幕宽高比。
......

let displaymediastreamconstraints = {
    video: true
};
//浏览器兼容
if (navigator.mediaDevices.getDisplayMedia) {
    let stream = await navigator
        .mediaDevices
        .getDisplayMedia(displaymediastreamconstraints)
    this.video.srcObject = stream;

} else {
    let stream = await navigator
        .getDisplayMedia(displaymediastreamconstraints);
    this.video.srcObject = stream;
}

注意:getDisplayMedia API需要用户授权才能获取屏幕、窗口或标签页的媒体流。在调用getDisplayMedia API时,会弹出一个权限请求框,用户需要选择允许或拒绝。

3.将视频流放在video标签中(可以放入也可以不放,根据自己的需求自行选择)

<video autoplay playsinline id="video1" width="400" height="300"></video>
this.video = document.getElementById('video1');
this.video.srcObject = stream;

注意:如果不定义宽和高则会出现以下效果

4.使用RecordRTC录制屏幕

RecordRTC的两个参数第一个是stream流

type为录制类型可选类型有接受 video、audio 、canvas 、gif代表可以录制音频、视频、画布或GIF

mimeType代表媒体类型

this.recorder = RecordRTC(this.video.srcObject, {
    type: 'video',
    mimeType: 'video/webm;codecs=vp9',
});

另外RecordRTC的所有配置见下方代码

const recorder = RecordRTC(stream, {
     // audio, video, canvas, gif
    type: 'video',

    // audio/webm
    // video/webm;codecs=vp9
    // video/webm;codecs=vp8
    // video/webm;codecs=h264
    // video/x-matroska;codecs=avc1
    // video/mpeg -- NOT supported by any browser, yet
    // video/mp4  -- NOT supported by any browser, yet
    // audio/wav
    // audio/ogg  -- ONLY Firefox
    // demo: simple-demos/isTypeSupported.html
    mimeType: 'video/webm',

    // MediaStreamRecorder, StereoAudioRecorder, WebAssemblyRecorder
    // CanvasRecorder, GifRecorder, WhammyRecorder
    recorderType: MediaStreamRecorder,

    // disable logs
    disableLogs: true,

    // get intervals based blobs
    // value in milliseconds
    timeSlice: 1000,

    // requires timeSlice above
    // returns blob via callback function
    ondataavailable: function(blob) {},

    // auto stop recording if camera stops
    checkForInactiveTracks: false,

    // requires timeSlice above
    onTimeStamp: function(timestamp) {},

    // both for audio and video tracks
    bitsPerSecond: 128000,

    // only for audio track
    audioBitsPerSecond: 128000,

    // only for video track
    videoBitsPerSecond: 128000,

    // used by CanvasRecorder and WhammyRecorder
    // it is kind of a "frameRate"
    frameInterval: 90,

    // if you are recording multiple streams into single file
    // this helps you see what is being recorded
    previewStream: function(stream) {},

    // used by CanvasRecorder and WhammyRecorder
    // you can pass {width:640, height: 480} as well
    video: HTMLVideoElement,

    // used by CanvasRecorder and WhammyRecorder
    canvas: {
        width: 640,
        height: 480
    },

    // used by StereoAudioRecorder
    // the range 22050 to 96000.
    sampleRate: 96000,

    // used by StereoAudioRecorder
    // the range 22050 to 96000.
    // let us force 16khz recording:
    desiredSampRate: 16000,

    // used by StereoAudioRecorder
    // Legal values are (256, 512, 1024, 2048, 4096, 8192, 16384).
    bufferSize: 16384,

    // used by StereoAudioRecorder
    // 1 or 2
    numberOfAudioChannels: 2,

    // used by WebAssemblyRecorder
    frameRate: 30,

    // used by WebAssemblyRecorder
    bitrate: 128000,

    // used by MultiStreamRecorder - to access HTMLCanvasElement
    elementClass: 'multi-streams-mixer'
});

4.开始屏幕录制

this.recorder.startRecording();

当执行上述代码时会执行屏幕的录制

5.结束屏幕录制

this.recorder.stopRecording(() => {
    // 获取录制的视频数据并将其显示在video标签中
    var blob = this.recorder.getBlob();
    var url = URL.createObjectURL(blob, { type: 'video/webm' });
    //若希望将数据回放则使用下列代码
    this.video.src = url
    console.log(url);
    // video.src = url;
});

当结束屏幕录制时会生成一个回调函数,里面含有blob文件,我们可以获取到,获取到之后可以使用formData封装后传输到服务器,也可以生成url进行视频的回显,回显到video标签中,也可以进行本地的直接下载,下载的代码如下

downloadMP4(url) {
    const a = document.createElement("a");
    document.body.appendChild(a);
    a.style.display = "none";
    a.href = url;
    a.download = new Date() + ".mp4";
    a.click();
    window.URL.revokeObjectURL(url);
}

6.销毁录制

当我们离开页面或者想直接销毁时可以直接销毁录制,以免出现内存泄漏的问题 具体代码如下

destroy() {
    //视频录制销毁
    if (this.recorder)
        this.recorder.destroy();
    //video销毁
    if (this.video) {
        var tracks = this.video.srcObject.getTracks();
        tracks.forEach(function (track) {
            track.stop();
        });
        this.video.srcObject = null;
    }
},

视频录制

视频录制与屏幕录制的方式基本相同,唯一不同的地方就是获取摄像头和麦克风

获取摄像头及麦克风并的视频流和音频流将其显示到video标签中

// 获取摄像头流并将其显示在video标签中
navigator.mediaDevices
    .getUserMedia({ video: true, audio: false })
    .then(stream => {
        this.video.srcObject = stream;
    })
    .catch(function (error) {
        console.error('无法获取摄像头流:', error);
    });

使用RecordRTC进行视频的录制

// 创建一个RecordRTC实例,录制来自摄像头的视频
this.recorder = RecordRTC(this.video.srcObject, {
    type: 'video',
    mimeType: 'video/webm;codecs=vp9',
});
this.recorder.startRecording();

销毁的地方与上面基本一致

//视频录制销毁
if (this.recorder)
    this.recorder.destroy();
//video销毁
if (this.video) {
    var tracks = this.video.srcObject.getTracks();
    tracks.forEach(function (track) {
        track.stop();
    });
    this.video.srcObject = null;
}

总结:RecordRTC是一款强大的插件,兼容多种浏览器,而且不光只能录制屏幕和视频,还可以进行canvas、音频、和gif等,具体的方式与上述案例基本相同,如需要进行处视频和屏幕之外的录制请去以下网址进行案例的学习

[RecordRTC官网]https://recordrtc.org/index.html

视频录制完整代码

<template>
    <div>
        <video id="video" autoplay style="background: pink"></video>
        <el-button @click="start">开始</el-button>
        <el-button @click="end">结束</el-button>
        <el-button @click="destroy">销毁</el-button>
    </div>
</template>

<script>
import RecordRTC from 'recordrtc';
export default {
    data() {
        return {
            video: null,
            recorder: null,
        };
    },
    mounted() {
        this.init();
    },
    methods: {
        init() {
            this.video = document.getElementById('video');
            // 获取摄像头流并将其显示在video标签中
            navigator.mediaDevices
                .getUserMedia({ video: true, audio: false })
                .then(stream => {
                    this.video.srcObject = stream;
                })
                .catch(function (error) {
                    console.error('无法获取摄像头流:', error);
                });
        },
        start() {
            // 创建一个RecordRTC实例,录制来自摄像头的视频
            this.recorder = RecordRTC(this.video.srcObject, {
                type: 'video',
                mimeType: 'video/webm;codecs=vp9',
            });
            this.recorder.startRecording();
        },
        end() {
            this.recorder.stopRecording(() => {
                // 获取录制的视频数据并将其显示在video标签中
                var blob = this.recorder.getBlob();
                var url = URL.createObjectURL(blob, { type: 'video/webm' });
                console.log(url);
                // video.src = url;
            });
        },
        destroy() {
            //视频录制销毁
            if (this.recorder)
                this.recorder.destroy();
            //video销毁
            if (this.video) {
                var tracks = this.video.srcObject.getTracks();
                tracks.forEach(function (track) {
                    track.stop();
                });
                this.video.srcObject = null;
            }
        },
    },
};
</script>

<style></style>

屏幕录制完整代码

<template>
    <div>
        <!-- 这个代码将视频文件video.mp4嵌入到网页中,并使用playsinline属性来指示视频在页面内播放。 -->
        <video autoplay playsinline id="video1" width="400" height="300"></video>
        <el-button @click="start">开始录制</el-button>
        <el-button @click="end">结束录制</el-button>
        <el-button @click="destroy">销毁</el-button>
    </div>
</template>

<script>
import RecordRTC from "recordrtc";
export default {
    name: 'ApplicationRTC',
    data() {
        return {
            video: null,
            recorder: null,
        }
    },
    mounted() {
        this.video = document.getElementById('video1');
    },
    methods: {
        async start() {
            //判断浏览器是否支持屏幕录制
            if (!navigator.getDisplayMedia && !navigator.mediaDevices.getDisplayMedia) {
                return this.{message.error("您的浏览器不支持屏幕录制")
            }
            let displaymediastreamconstraints = {
                video: {
                    displaySurface: "application",
                    logicalSurface: true,
                    cursor: "always",
                },
            };
            try {
                //浏览器兼容
                if (navigator.mediaDevices.getDisplayMedia) {
                    let stream = await navigator
                        .mediaDevices
                        .getDisplayMedia(displaymediastreamconstraints)
                    this.video.srcObject = stream;

                } else {
                    let stream = await navigator
                        .getDisplayMedia(displaymediastreamconstraints);
                    this.video.srcObject = stream;
                }
                this.recorder = RecordRTC(this.video.srcObject, {
                    type: 'video',
                    mimeType: 'video/webm;codecs=vp9',
                });
                this.recorder.startRecording();
            } catch (error) {
                this.{message.error(error)
            }
        },
        end() {
            this.recorder.stopRecording(() => {
                // 获取录制的视频数据并将其显示在video标签中
                var blob = this.recorder.getBlob();
                var url = URL.createObjectURL(blob, { type: 'video/webm' });
                //若希望将数据回放则使用下列代码
                this.video.src = url
                console.log(url);
                // video.src = url;
            });
        },
        destroy() {
            //视频录制销毁
            if (this.recorder)
                this.recorder.destroy();
            //video销毁
            if (this.video) {
                var tracks = this.video.srcObject.getTracks();
                tracks.forEach(function (track) {
                    track.stop();
                });
                this.video.srcObject = null;
            }
        },
        downloadMP4(url) {
            const a = document.createElement("a");
            document.body.appendChild(a);
            a.style.display = "none";
            a.href = url;
            a.download = new Date() + ".mp4";
            a.click();
            window.URL.revokeObjectURL(url);
        }
    }
}
</script>