• 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 : {
                    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();
    }

     

  • 相关阅读:
    uva 10280(欧拉函数)
    uva 11121(-2进制)
    uva 10673(扩展欧几里德)
    uva 106(勾股定理)
    uva 128(简单题)
    Codeforces Round #238 (Div. 1) 解题报告
    2018(1)系统分析/需求分析
    2015(1)进度管理/时间管理
    序列图
    [转贴] 软件测试职业发展的 A 面和 B 面
  • 原文地址:https://www.cnblogs.com/ssyfj/p/14787012.html
Copyright © 2020-2023  润新知