webRTC学习系列之——WebRTC录制媒体流并下载

WebRTC使用MediaRecoder录制媒体流并下载

MediaRecoder

	var mediaRecorder = new MideaRecoder(stream,options);
参数说明
stream媒体流,可以从getUserMedia、、或者获取
options限制选项
限制选项说明
mimeType( video/webm);(audio/webm);(video/webm);(codecs=vp8);(video/webm;codecs=h264);(audio/webm;codecs=opus)
audioBitsPerSecond音频码率
videoBitsPerSecond视频码率(越多清晰度越高)
bitsPerSecond整体码率

对于mimeType,每个括号是的一种约束,也可以将webm改为mp4,codesc的种类必须要得到webm的支持

API
//开始录制媒体,timeslice是可选的,如果设置了灰暗时间切片存储数据
MediaRecoder.start(timeslice)
//停止录制,此时或出发包括最终Blob数据(数据存储区域)的dataavailable事件
MediaRecoder.stop()
MediaRecoder.pause		//暂停录制
MediaRecoder.resume() 		//恢复录制
MediaRecoder.isTypeSupported() 		//检查是否支持格式
事件
//每次记录一定时间的数据(如果没有指定时间片,则记录整个数据)时会定期触发
MediaRecoder.ondataavailable
//有错误发生时触发
MediaRecoder.onerror
js存储数据的方式
1、字符串
2、Blob(使用这种)
3、ArrayBuffer
4、ArrayBufferView

在学习录制媒体流之前,我们先来认识一个新的API——getDisplayMedia( ),通过这个API,我们可以捕捉桌面并获取视频流(此功能需要较新版本的Chrome)

//contraints与getUserMedia中的contraints一致
var promise = navigator.mediaDevices.getDisplayMedia(contraints);

下面看看这个API的实战效果
代码:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>WebRTC get video devices</title>
</head>
<body>
    <video autoplay playsinline id="player"></video>
	<script>
        var videoplay = document.getElementById("player");
        //调用浏览器的设备,获取摄像头的使用
        navigator.mediaDevices.getUserMedia({video:true})
            .then(stream => {
                videoplay.srcObject = stream;
            }).catch(error => {
            console.log(error);
        })
    </script>
</body>
</html>

效果图
视频参数学习以上知识后,进入录制音视频的实战:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>录制音视频</title>
</head>
<body>
    <table>
        <tr>
            <td><video autoplay playsinline id="player"></video></td>
            <td><video playsinline id="recplayer"></video></td>
        </tr>
        <tr>
            <td><button id="record">Start Record</button></td>
            <td><button id="recplay" disabled>Play</button></td>
            <td><button id="download" disabled>Download</button></td>
        </tr>
    </table>

    <script>
        var videoplay = document.getElementById("player");
        var recvideo = document.getElementById("recplayer");
        var btnRecord = document.getElementById("record");
        var btnPlay = document.getElementById("recplay");
        var btnDownload = document.getElementById("download");

        //二进制数组,存储视频
        var buffer;
        //全局
        var meidaRecoder;

        navigator.mediaDevices.getUserMedia({video: true})
            .then(stream => {
                window.stream = stream;
                videoplay.srcObject = stream;
            }).catch(error => {
                console.log(error);
        });

        function handleDataAvailable(e) {
        	//判断是否有数据
            if(e&& e.data && e.data.size > 0){
                buffer.push(e.data);
            }
        }

        function startRecord(){
            //开始录制,初始化数组
            buffer = [];

            var options = {
                //录制视频,格式为webm
                mimeType: 'video/webm;codecs=vp8'
            };
            //检验是否支持mimeType
            if(!MediaRecorder.isTypeSupported(options.mimeType)){
                console.log(`${options.mimeType} is not supported`);
                return;
            }
            try{
                meidaRecoder = new MediaRecorder(window.stream, options)
            }catch (e) {
                console.log('Filed tp create MideaRecoder',e);
                return;
            }
            //存储数据时触发事件,数据有效时执行handleDataAvailable
            meidaRecoder.ondataavailable = handleDataAvailable;
            //设置时间片,每过一个时间片就会存储数据
            meidaRecoder.start(10);
        }

        function stopRecord(){
            //停止录制
            meidaRecoder.stop();
        }

        //录制视频
        btnRecord.onclick = () => {
            if(btnRecord.textContent === "Start Record"){
                startRecord();
                btnRecord.textContent = 'Stop Record';
                btnPlay.disabled = true;
                btnDownload.disabled = true;
            }else {
                stopRecord();
                btnRecord.textContent = "Start Record";
                btnPlay.disabled = false;
                btnDownload.disabled = false;
            }
        };

        //播放视频
        btnPlay.onclick = () => {
            var blob = new Blob(buffer,{type: 'video/webm'});
            recvideo.src = window.URL.createObjectURL(blob);
            recvideo.srcObject = null;
            recvideo.control = true;
            recvideo.play();
        };

        //下载视频
        btnDownload.onclick = () => {
            var blob = new Blob(buffer,{type: 'video/webm'});
            var url = window.URL.createObjectURL(blob);
            var a = document.createElement('a');
            a.href = url;
            a.style.display = 'none';
            a.download = 'aaa.webm';
            a.click();
        }
    </script>
</body>
</html>
以下是一个使用 Vue3、rrweb 和 WebRTC 技术进行录制下载视频流的示例代码: ```html <template> <div> <video ref="videoRef" autoplay></video> <button @click="startRecording">开始录制</button> <button @click="stopRecording">停止录制</button> <button @click="downloadRecording">下载录制</button> </div> </template> <script> import { ref } from 'vue' import RecordRTC from 'recordrtc' import { createSerializer } from 'rrweb/serializer' import { rrwebPlayer } from 'rrweb-player' import { createPeerConnection } from './webrtc' export default { setup() { const videoRef = ref(null) let recorder = null let mediaStream = null let recordedBlobs = null const startRecording = async () => { recordedBlobs = [] mediaStream = await navigator.mediaDevices.getUserMedia({ audio: true, video: true }) videoRef.value.srcObject = mediaStream recorder = RecordRTC(mediaStream, { type: 'video', mimeType: 'video/webm', bitsPerSecond: 100000 }) recorder.startRecording() } const stopRecording = () => { recorder.stopRecording(() => { recordedBlobs = recorder.getBlob() const serializer = createSerializer() const events = serializer(events) const videoData = { events, width: videoRef.value.videoWidth, height: videoRef.value.videoHeight } createPeerConnection(videoData) }) mediaStream.getTracks().forEach(track => track.stop()) videoRef.value.srcObject = null } const downloadRecording = () => { const blob = new Blob(recordedBlobs, { type: 'video/webm' }) const url = URL.createObjectURL(blob) const a = document.createElement('a') a.style.display = 'none' a.href = url a.download = 'recording.webm' document.body.appendChild(a) a.click() setTimeout(() => { document.body.removeChild(a) URL.revokeObjectURL(url) }, 100) } return { videoRef, startRecording, stopRecording, downloadRecording } } } </script> ``` 其中,`createPeerConnection` 函数用于创建 WebRTC 连接并发送录制的视频数据,其代码如下: ```javascript import { createSignalChannel } from './signal' export const createPeerConnection = async videoData => { const rtcPeerConnection = new RTCPeerConnection() const signalChannel = await createSignalChannel() const offer = await rtcPeerConnection.createOffer() await rtcPeerConnection.setLocalDescription(offer) signalChannel.emit('offer', { offer, videoData }) signalChannel.on('answer', async ({ answer }) => { await rtcPeerConnection.setRemoteDescription(answer) }) } ``` 在这个函数中,我们首先创建了一个 `RTCPeerConnection` 对象,然后使用 `createSignalChannel` 函数创建了一个信令通道,接着创建了一个 offer 并将其设置为本地的 SDP 值,最后通过信令通道将 offer 发送给对方。当对方接收到 offer 并创建了一个 answer 后,将其通过信令通道发送给我们,我们再将其设置为远程的 SDP 值即可建立 WebRTC 连接。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值