Warning: error_log(/data/www/wwwroot/hmttv.cn/caches/error_log.php): failed to open stream: Permission denied in /data/www/wwwroot/hmttv.cn/phpcms/libs/functions/global.func.php on line 537 Warning: error_log(/data/www/wwwroot/hmttv.cn/caches/error_log.php): failed to open stream: Permission denied in /data/www/wwwroot/hmttv.cn/phpcms/libs/functions/global.func.php on line 537 久久久青草青青亚洲国产免观,久久国内免费视频,欧美激情视频在线

          整合營(yíng)銷服務(wù)商

          電腦端+手機(jī)端+微信端=數(shù)據(jù)同步管理

          免費(fèi)咨詢熱線:

          如何使用 JavaScript 錄制屏幕?

          色字體,選擇“標(biāo)星公眾號(hào)

          優(yōu)質(zhì)文章,第一時(shí)間送達(dá)

          屏幕錄制?截屏?網(wǎng)頁(yè)生成圖片?幀圖?說到錄屏,我一開始想到的是前面這些詞。大致的想法是持續(xù)的生成當(dāng)前頁(yè)面的截圖,然后把這些幀圖再合并成一個(gè)視頻文件。前端頁(yè)面生成圖片我們應(yīng)該比較熟悉的是html2canvas。另外也有一些現(xiàn)成的庫(kù)可以使用來進(jìn)行屏幕的錄制,RecordRTC上就有很多屏幕錄制的實(shí)現(xiàn)。有聲音(Audio)、視頻(Video)、屏幕(Screen)的錄制;有針對(duì)canvas的錄制等等,一共有三十多個(gè)示例。這里主要想簡(jiǎn)單的講一講原生的 Screen Capture API。參見:Using the Screen Capture API

          一、屏幕內(nèi)容的捕獲

          navigator.mediaDevices.getDisplayMedia

          該方法會(huì)返回一個(gè)promise, 該promise會(huì)resolve當(dāng)前屏幕內(nèi)容的實(shí)時(shí)數(shù)據(jù)流。

          使用 async / await 實(shí)現(xiàn)如下:

          async function startCapture(displayMediaOptions) { let captureStream = ;
          try { captureStream = await navigator.mediaDevices.getDisplayMedia(displayMediaOptions); } catch(err) { console.error("Error: " + err); } return captureStream;}

          使用 promise 的方式實(shí)現(xiàn)如下:

          function startCapture(displayMediaOptions) { let captureStream = ;
          return navigator.mediaDevices.getDisplayMedia(displayMediaOptions) .catch(err => { console.error("Error:" + err); return ; });}

          我們?cè)讷@取屏幕數(shù)據(jù)的時(shí)候有可能會(huì)獲取到一些敏感信息,所有在使用getDisplayMedia的時(shí)候,為了安全考慮,會(huì)彈出一個(gè)選擇框,然用戶自己選擇需要共享那一部分的內(nèi)容。可以共享當(dāng)前屏幕,也可以共享其他的應(yīng)用窗口和瀏覽器的其他標(biāo)簽頁(yè)。

          二、參數(shù)配置:

          我們?cè)谏厦娴膶?shí)現(xiàn)中可以看到, 傳遞給startCapture函數(shù)的參數(shù)為displayMediaOptions。這個(gè)參數(shù)是用于配置返回?cái)?shù)據(jù)流的。數(shù)據(jù)形式如下:

          const displayMediaOptions = { video: { cursor: "never" },  audio: false,  logicalSurface: false, };

          開可以針對(duì)音視頻做詳細(xì)的配置:

          const gdmOptions = { video: { cursor: "always" // 始終顯示鼠標(biāo)信息 }, // audio 配置信息是可選的 audio: { echoCancellation: true,  noiseSuppression: true, sampleRate: 44100 } }

          三、示例

          HTML:

          <!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>Screen Record</title> <link rel="stylesheet" href="./css/index.css"></head><body> <p>This example shows you the contents of the selected part of your display. Click the Start Capture button to begin.</p> <p><button id="start">Start Capture</button>&nbsp;<button id="stop">Stop Capture</button></p> <video id="video" autoplay></video> <br> <strong>Log:</strong> <br> <pre id="log"></pre> <script src="./js/index.js"></script></body></html>

          CSS:

          #video { border: 1px solid #999; width: 98%; max-width: 860px; } .error { color: red; } .warn { color: orange; } .info { color: darkgreen; }

          JS:

          const videoElem = document.getElementById("video");const logElem = document.getElementById("log");const startElem = document.getElementById("start");const stopElem = document.getElementById("stop");
          const displayMediaOptions = { video: { cursor: "never" }, audio: false};
          startElem.addEventListener("click", function(evt) { startCapture;}, false);stopElem.addEventListener("click", function(evt) { stopCapture;}, false);console.log = msg => logElem.innerHTML += `${msg}<br>`;console.error = msg => logElem.innerHTML += `<span class="error">${msg}</span><br>`;console.warn = msg => logElem.innerHTML += `<span class="warn">${msg}<span><br>`;console.info = msg => logElem.innerHTML += `<span class="info">${msg}</span><br>`;
          async function startCapture { logElem.innerHTML = "";
          try { videoElem.srcObject = await navigator.mediaDevices.getDisplayMedia(displayMediaOptions); dumpOptionsInfo; } catch(err) { console.error("Error: " + err); }}
          function stopCapture(evt) { let tracks = videoElem.srcObject.getTracks;
          tracks.forEach(track => track.stop); videoElem.srcObject = ;}
          function dumpOptionsInfo { const videoTrack = videoElem.srcObject.getVideoTracks[0]; console.info("Track settings:"); console.info(JSON.stringify(videoTrack.getSettings, , 2)); console.info("Track constraints:"); console.info(JSON.stringify(videoTrack.getConstraints, , 2));}

          效果如下:

          點(diǎn)擊Start Capture 之后選擇需要共享的部分就可以共享如下的內(nèi)容:

          點(diǎn)擊Stop Capture即可˙停止錄制共享。

          這個(gè)例子只是調(diào)取接口獲取到當(dāng)前分享屏幕的數(shù)據(jù)流,并通過video的形式顯示出來。我們?cè)谀玫綌?shù)據(jù)流信息這個(gè),可以把這些信息上傳到服務(wù)器,生成相應(yīng)的視頻文件。也可以結(jié)合websocket之類的處理方式,實(shí)現(xiàn)實(shí)時(shí)的屏幕共享功能。

          作者:飯等米

          鏈接:segmentfault.com/a/1190000020267689

          如果喜歡本篇文章,歡迎。關(guān)注訂閱號(hào)「Web項(xiàng)目聚集地」,回復(fù)「進(jìn)群」即可進(jìn)入無廣告技術(shù)交流。

          1.2. 4. 5.6.

          件傳遞有兩種方式,冒泡和捕獲。事件傳遞定義了元素事件觸發(fā)的順序,在冒泡中,內(nèi)部元素的事件會(huì)先被觸發(fā),然后在觸發(fā)外部元素,如先觸發(fā)p元素然后觸發(fā)div元素。在捕獲事件中,外部元素先被觸發(fā),然后內(nèi)部事件觸發(fā)。addEventListener() 方法可以指定 "useCapture" 參數(shù)來設(shè)置傳遞類型:addEventListener(event, function, useCapture);

          創(chuàng)建新的HTML元素(節(jié)點(diǎn))appendChild()

          HTML Collection與NodeList的區(qū)別:NodeList 與 HTMLCollection 有很多類似的地方。NodeList 與 HTMLCollection 都與數(shù)組對(duì)象有點(diǎn)類似,可以使用索引 (0, 1, 2, 3, 4, ...) 來獲取元素。NodeList 與 HTMLCollection 都有 length 屬性。節(jié)點(diǎn)列表不是一個(gè)數(shù)組!節(jié)點(diǎn)列表無法使用數(shù)組的方法: valueOf(), pop(), push(), 或 join() 。

          件流:

          事件冒泡

          取消冒泡:oEvent.cancelBubble=true

          <html>
          <head>
          <meta charset="utf-8">
          <title>無標(biāo)題文檔</title>
          <style>
          #div1 {width:400px; height:300px; background:#CCC; display:none;}
          </style>
          <script>
          window.onload=function ()
          {
              var oBtn=document.getElementById('btn1');
              var oDiv=document.getElementById('div1');
          
              oBtn.onclick=function (ev)
              {
              var oEvent=ev||event;
          
              oDiv.style.display='block';
              //alert('按鈕被點(diǎn)擊了');
          
              oEvent.cancelBubble=true; //取消事件冒泡,是解決許多問題的方法和手段
              };
          
              document.onclick=function ()
              {
              oDiv.style.display='none';
              //alert('document被點(diǎn)擊了');
              };
          };
          </script>
          </head>
          <body>
          <input id="btn1" type="button" value="顯示" />
          <div id="div1">
          </div>
          </body>
          </html>

          冒泡型事件:

          <html>
          <head>
          <title>冒泡型事件</title>
          <script language="javascript">
          function add(sText){
          var oDiv = document.getElementById("display");
          oDiv.innerHTML += sText; //輸出點(diǎn)擊順序
          }
          </script>
          </head>
          <body onclick="add('body<br>');">
          <div onclick="add('div<br>');">
          <p onclick="add('p<br>');">Click Me</p>
          </div>
          <div id="display"></div>
          </body>
          </html>

          執(zhí)行順序:p對(duì)象 -> div對(duì)象 -> body對(duì)象

          冒泡型事件執(zhí)行順序::由內(nèi)到外(p -> div -> body -> document)

          注意: DOM 0級(jí)只有冒泡, 沒有捕獲

          捕獲型事件

          相對(duì)于IE使用冒泡型事件, Netscape使用了另一種稱為捕獲型事件(eventcapturing)的解決方案;

          addEventListener(事件名稱,函數(shù), bCapture)

          removeEventListener(事件名稱, 函數(shù), bCapture)

          事件監(jiān)聽函數(shù)第三個(gè)參數(shù)bCapture確定是冒泡型還是捕獲型事件(true:捕獲 false:冒泡,默認(rèn)值false)

          <!DOCTYPE html>
          <html>
          <head>
          <style>
          div {
          background-color: coral;
          border: 1px solid;
          padding: 50px;
          }
          </style>
          </head>
          <body>
          <div id="myDiv2">
          <p id="myP2">點(diǎn)擊該段落, 我是捕獲</p>
          </div>
          <script>
          document.getElementById("myP2").addEventListener("click", function() {
          alert("你點(diǎn)擊了 P 元素!");
          }, true);
          document.getElementById("myDiv2").addEventListener("click", function() {
          alert("你點(diǎn)擊了 DIV 元素!");
          }, true);
          </script>
          </body>
          </html>

          執(zhí)行順序: div對(duì)象 -> p對(duì)象

          捕獲型事件執(zhí)行順序:由外到內(nèi)(如:document -> body -> div -> p)

          冒泡型:事件從內(nèi)部往外部依次執(zhí)行。

          捕捉型:事件從外部往內(nèi)部依次執(zhí)行。

          事件監(jiān)聽

          通用監(jiān)聽方法:

          1.直接在HTML標(biāo)簽中分配事件處理函數(shù):

          <script language="javascript">
          function add(sText){
          var oDiv = document.getElementById("display");
          oDiv.innerHTML += sText; //輸出點(diǎn)擊順序
          }
          </script>
          </head>
          <body onclick="add('body<br>');">
          <div onclick="add('div<br>');">
          <p onclick="add('p<br>');">Click Me</p>
          </div>
          <div id="display"></div>
          </body>

          2.結(jié)構(gòu)與行為的分離:

          <html>
          <head>
          <title>監(jiān)聽函數(shù)</title>
          <script language="javascript">
          window.onload = function(){
          var oP = document.getElementById("myP"); //找到對(duì)象
          oP.onclick = function(){ //設(shè)置事件監(jiān)聽函數(shù)
          alert('我被點(diǎn)擊了');
          }
          }
          </script>
          </head>
          <body>
          <div>
          <p id="myP">Click Me</p>
          </div>
          </body>
          </html>

          事件監(jiān)聽的作用:

          <!DOCTYPE HTML>
          <html>
          <head>
          <meta charset="utf-8">
          <title>無標(biāo)題文檔</title>
          <script>
          window.onload=function ()
          {
          alert('a');
          };
          window.onload=function ()
          {
          alert('b');
          };
          </script>
          </head>
          <body>
          </body>
          </html>

          以上程序只彈出alert('b');

          理解:對(duì)同一對(duì)象執(zhí)行兩次事件(同一事件類型)處理函數(shù)時(shí),往往只能只執(zhí)行后一個(gè)

          因此如果要讓腳本在本瀏覽器中正常運(yùn)行的話,就必須使用瀏覽器所支持的事件監(jiān)聽器

          IE中的監(jiān)聽方法:

          attachEvent(事件名稱, 函數(shù)), 綁定事件處理函數(shù) attach: 貼上, 附著

          detachEvent(事件名稱, 函數(shù)), 解除綁定 detach: 分離, 拆開

          注意:IE只支持冒泡型事件監(jiān)聽, 沒有第三個(gè)參數(shù), 事件名稱前要加"on";

          <html>
          <head>
          <title>多個(gè)監(jiān)聽函數(shù)</title>
          <script language="javascript">
          function fnClick1(){
          alert("我被fnClick1點(diǎn)擊了");
          }
          function fnClick2(){
          alert("我被fnClick2點(diǎn)擊了");
          //oP.detachEvent("onclick",fnClick1); //刪除監(jiān)聽函數(shù)1
          }
          var oP;
          window.onload = function(){
          oP = document.getElementById("myP"); //找到對(duì)象
          oP.attachEvent("onclick",fnClick1); //添加監(jiān)聽函數(shù)1
          oP.attachEvent("onclick",fnClick2); //添加監(jiān)聽函數(shù)2
          }
          </script>
          </head>
          <body>
          <div>
          <p id="myP">Click Me</p>
          </div>
          </body>
          </html>

          標(biāo)準(zhǔn)DOM的事件監(jiān)聽:

          addEventListener(事件名稱,函數(shù), 捕獲)

          element.addEventListener(event, function, useCapture)

          removeEventListener(事件名稱, 函數(shù), 捕獲)

          element.removeEventListener(event, function, useCapture)

          bCapture 是用于冒泡階段還是捕獲階段(true:捕獲 false:冒泡,默認(rèn)值false)

          注意:IE9版本已支持

          <html>
          <head>
          <title>標(biāo)準(zhǔn)DOM的事件監(jiān)聽</title>
          <script language="javascript">
          function fnClick1(){
          alert("我被fnClick1點(diǎn)擊了");
          //oP.removeEventListener("click",fnClick2,false); //刪除監(jiān)聽函數(shù)2
          }
          function fnClick2(){
          alert("我被fnClick2點(diǎn)擊了");
          }
          var oP;
          window.onload = function(){
          oP = document.getElementById("myP"); //找到對(duì)象
          oP.addEventListener("click",fnClick1,false); //添加監(jiān)聽函數(shù)1
          oP.addEventListener("click",fnClick2,false); //添加監(jiān)聽函數(shù)2
          }
          </script>
          </head>
          <body>
          <div>
          <p id="myP">Click Me</p>
          </div>
          </body>
          </html>

          編寫兼容性事件監(jiān)聽函數(shù)

          function addEvent(obj, ev, fn){
              if(obj.addEventListener){
              obj.addEventListener(ev, fn, false);
              }else{
              obj.attachEvent('on'+ev, fn);
              }
          }
          function removeEvent(obj, ev, fn){
              if(obj.removeEventListener){
              obj.addEventListener(ev, fn, false);
              }else{
              obj.attachEvent('on'+ev, fn);
              }
          }

          實(shí)例:


          主站蜘蛛池模板: 成人丝袜激情一区二区| 久久高清一区二区三区| 国产一区二区电影在线观看| 中文字幕一区二区三区精彩视频 | 三上悠亚国产精品一区| 日韩精品无码中文字幕一区二区 | 亚洲电影一区二区三区| 高清一区高清二区视频| 风间由美在线亚洲一区| 国产福利一区二区三区| 香蕉久久av一区二区三区| 国产精品亚洲不卡一区二区三区| 亚洲一区AV无码少妇电影| 亚洲综合一区二区国产精品| 香蕉视频一区二区| 亚洲av成人一区二区三区在线观看 | 精品乱码一区二区三区四区| 久久久久国产一区二区| 亚洲欧洲一区二区三区| 精品一区二区三区中文| 国产在线一区二区杨幂| 国产福利日本一区二区三区| 亚洲一区二区三区免费观看| 日韩内射美女人妻一区二区三区 | 亚洲日韩精品一区二区三区| 一区二区三区免费精品视频| 一区国严二区亚洲三区| 美女免费视频一区二区| 欧洲精品码一区二区三区免费看 | 在线精品国产一区二区| 久久99精品一区二区三区| 无码人妻品一区二区三区精99| av无码人妻一区二区三区牛牛| 国产内射999视频一区| 奇米精品一区二区三区在线观看| 波多野结衣免费一区视频 | 人成精品视频三区二区一区| 一区二区视频免费观看| 久久精品一区二区三区中文字幕 | 无码人妻一区二区三区一| 欧美激情国产精品视频一区二区|