WebRTC学习(四)WebRTC音视频录制

一:WebRTC录制基本知识

(一)MediaRecoder类基本格式

(二)options限制选项

mimeType:用来指定要录制的是视频还是音频,即录制的格式是什么,上面的列表中是webm格式的多媒体类型,也可以设置为其他格式,比如mp4。也可以指定编码方式

(三)MediaRecorder常用API 

如果不选择timeslice,则所有的数据会存储到一个大的buffer中,设置了timeslice,则会按timeslice分块存储数据,存为小块的数据
stop不会丢弃最后一块数据,会使得生效存储下来

isTypeSupported:用来检查是否支持对应的格式类型

(四)MediaRecorder事件

对于ondataavailable事件:如果指定了timeslice,则会每隔一段时间触发这个事件,然后对数据进行处理。如果没有指定timeslice,则会在视频录制完成,调用stop结束录制时去出发这个事件

(五)javascript存储方式 

Blob是一块高效的存储区域(无类型的数据缓冲区),可以将整个缓冲区写入文件中。Blob是ArrayBuffer的封装,更加高效的处理ArrayBuffer。ArrayBufferView是带有类型的ArrayBuffer

二:使用MediaRecoder实现录制和播放

(一)代码实现

<html>
    <head>
        <title>    WebRTC get audio and video devices </title>
        <style>
            .none {
                -webkit-filter: none;
            }

            .blue {
                -webkit-filter: blur(3px); 
            }

            .grayscale {
                -webkit-filter: grayscale(1);
            }

            .invert {
                -webkit-filter: invert(1);
            }

            .sepia {
                -webkit-filter: sepia(1);
            }
        </style>
    </head>
    <body>
        <h1>Index5.html</h1>
        <div>
            <table>
                <tr>
                    <td>
                        <video autoplay playsinline id="player"></video>
                    </td>
                    <td>
                        <video playsinline id="recplayer"></video>
                    </td>
                    <td>
                        <div id="constraints"></div>
                    </td>
                </tr>
                <tr>
                    <td>
                        <button id="record">Start Record</button>
                    </td>
                    <td>
                        <button id="recplay" disabled>Start Play</button>
                    </td>
                    <td>
                        <button id="download" disabled>download</button>
                    </td>
                </tr>
            </table>
        </div>
    </body>
    <script type="text/javascript" src="https://webrtc.github.io/adapter/adapter-latest.js"></script>
    <script type="text/javascript" src="./js/client5.js"></script>
    
</html>
index5.html

client5.js实现

'use strict'

//视频录制
var videoplay = document.querySelector("video#player");
//视频播放
var recvideoplay = document.querySelector("video#recplayer");
//约束显示
var divConstraints = document.querySelector("div#constraints");

//--------按钮
var btnRecord = document.querySelector("button#record");
var btnRecplay = document.querySelector("button#recplay");
var btnDownload = document.querySelector("button#download");

var buffer;    //存储录制数据
var mediaRecorder;    //对象

function start(){
    console.log("start......");
    if(!navigator.mediaDevices || 
        !navigator.mediaDevices.getUserMedia){
        console.log("getUserMedia is not supported!");
    }else{
        var constraints = {
            video : {
                width:320,
                height:240,
                frameRate:30,
                facingMode:"user"
            },
            audio : {
                noiseSuppression:true,
                echoCancellation:true
            },
        }

        navigator.mediaDevices.getUserMedia(constraints)
                    .then(getMediaStream)
                    .catch(handleError);
    }
}

function getMediaStream(stream){
    window.stream = stream;            //将stream变量放入全局中

    videoplay.srcObject = stream;    //设置采集到的流进行播放

    //获取视频的track
    var videoTrack = stream.getVideoTracks()[0];        //只有一个,所以只取一个
    var videoConstraints = videoTrack.getSettings();    //获取约束对象

    divConstraints.textContent = JSON.stringify(videoConstraints,null,2);        //转为json
}

function handleError(err){
    console.log(err.name+":"+err.message);
}

start();    //开始执行逻辑

//---------设置事件:录制-----

//设置数据处理函数
function handleDataAvail(e){
    if(e && e.data && e.data.size > 0){
        buffer.push(e.data);    
    }
}


//录制与停止录制
function startRecord(){
    buffer = [];    //定义数据

    var options = {
        mimeType: "video/webm;codecs=vp8"
    }

    if(!MediaRecorder.isTypeSupported(options.mimeType)){    //查看是否支持这个类型
        console.error("${options.mimeType} is not suppported!");
        return;
    }

    try{
        mediaRecorder = new MediaRecorder(window.stream,options);
    }catch(e){
        console.error("Failed to create MediaRecoder!");
        return;
    }

    mediaRecorder.ondataavailable = handleDataAvail;
    mediaRecorder.start(10);    //设置时间片存储数据
}

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

btnRecord.onclick = function(){
    if(btnRecord.textContent === "Start Record"){
        startRecord();
        btnRecord.textContent = "Stop Record";
        btnRecplay.disabled = true;
        btnDownload.disabled = true;
    }else{
        stopRecord();
        btnRecord.textContent = "Start Record";
        btnRecplay.disabled = false;
        btnDownload.disabled = false;    
    }
}

//---------设置事件:播放-----


btnRecplay.onclick = function(){
    var blob = new Blob(buffer,{type: 'video/webm'});        //生成了一个可以处理buffer的对象
    recvideoplay.src = window.URL.createObjectURL(blob);    //获取数据所在位置
    recvideoplay.srcObject = null;    //实时获取数据时才需要
    recvideoplay.controls = true;    //进行播放控制,播放与暂停
    recvideoplay.play();    //进行播放
}

//---------设置事件:下载-----

btnDownload.onclick = function(){
    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 = "video.webm";
    a.click();
}

(二)结果显示

三:WebRTC采集屏幕数据

(一)获取桌面API

(二)对浏览器进行设置(chrome新版本中的功能)

(三)代码实现

'use strict'

//视频录制
var videoplay = document.querySelector("video#player");
//视频播放
var recvideoplay = document.querySelector("video#recplayer");
//约束显示
var divConstraints = document.querySelector("div#constraints");

//--------按钮
var btnRecord = document.querySelector("button#record");
var btnRecplay = document.querySelector("button#recplay");
var btnDownload = document.querySelector("button#download");

var buffer;    //存储录制数据
var mediaRecorder;    //对象

function start(){
    console.log("start......");
    if(!navigator.mediaDevices || 
        !navigator.mediaDevices.getDisplayMedia){
        console.log("getDisplayMedia is not supported!");
    }else{
        var constraints = {
            video : true,
            audio : false
        }

        navigator.mediaDevices.getDisplayMedia(constraints)
                    .then(getMediaStream)
                    .catch(handleError);
    }
}

function getMediaStream(stream){
    window.stream = stream;            //将stream变量放入全局中

    videoplay.srcObject = stream;    //设置采集到的流进行播放

    //获取视频的track
    var videoTrack = stream.getVideoTracks()[0];        //只有一个,所以只取一个
    var videoConstraints = videoTrack.getSettings();    //获取约束对象

    divConstraints.textContent = JSON.stringify(videoConstraints,null,2);        //转为json
}

function handleError(err){
    console.log(err.name+":"+err.message);
}

start();    //开始执行逻辑

//---------设置事件:录制-----

//设置数据处理函数
function handleDataAvail(e){
    if(e && e.data && e.data.size > 0){
        buffer.push(e.data);    
    }
}


//录制与停止录制
function startRecord(){
    buffer = [];    //定义数据

    var options = {
        mimeType: "video/webm;codecs=vp8"
    }

    if(!MediaRecorder.isTypeSupported(options.mimeType)){    //查看是否支持这个类型
        console.error("${options.mimeType} is not suppported!");
        return;
    }

    try{
        mediaRecorder = new MediaRecorder(window.stream,options);
    }catch(e){
        console.error("Failed to create MediaRecoder!");
        return;
    }

    mediaRecorder.ondataavailable = handleDataAvail;
    mediaRecorder.start(10);    //设置时间片存储数据
}

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

btnRecord.onclick = function(){
    if(btnRecord.textContent === "Start Record"){
        startRecord();
        btnRecord.textContent = "Stop Record";
        btnRecplay.disabled = true;
        btnDownload.disabled = true;
    }else{
        stopRecord();
        btnRecord.textContent = "Start Record";
        btnRecplay.disabled = false;
        btnDownload.disabled = false;    
    }
}

//---------设置事件:播放-----


btnRecplay.onclick = function(){
    var blob = new Blob(buffer,{type: 'video/webm'});        //生成了一个可以处理buffer的对象
    recvideoplay.src = window.URL.createObjectURL(blob);    //获取数据所在位置
    recvideoplay.srcObject = null;    //实时获取数据时才需要
    recvideoplay.controls = true;    //进行播放控制,播放与暂停
    recvideoplay.play();    //进行播放
}

//---------设置事件:下载-----

btnDownload.onclick = function(){
    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 = "video.webm";
    a.click();
}

 

posted @ 2021-05-19 21:28  山上有风景  阅读(3411)  评论(0编辑  收藏  举报