Video.js 影片播放

      在〈Video.js 影片播放〉中尚無留言

影片的播放,可以使用 Video.js,完整 html 如下。

簡易影片播放

todo

data-setup 屬性

Video.js 官網教學中,常把 data-setup 屬性列於 html 中,這會導致在 Javascript 程式碼中失效。

官網教學如下

<video id="video1" class="video-js vjs-default-skin vjs-big-play-centered" controls
          crossorigin="use-credentials"
          data-setup='{ "autoplay": true, "controls": true , "poster": "", "preload": "auto" }'>

實際上需寫在 Javascript 中,如下所示

<body>
<video id="video1" class="videobox video-js vjs-default-skin vjs-big-play-centered"></video>
<script>
videojs(
  "video1",
      {
          controls:true,
          muted: true,
          autoplay: true,
          fluid: true,
          aspectRatio: "16:9",
          requestFullScreen: true,
          notSupportedMessage: "no connection",
          sources: [{src:url,type:"application/x-mpegURL"}]
      }
    );
</script>
</body>

m3u8播放

m3u8 是直播系統的播放列表,開始直播時才會產生 index.m3u8檔。所以觀看者若在還沒開始直播前就進入網頁,會讓網頁一直轉圈圈。就算轉到開始直播時,還是無法進入直播狀態。

底下使用 ajax 每 1 秒就檢查伺服器是否有 /data/video/live/channel_xx/index.m3u8,如果有的話就開始播放,沒有就停止。完整 html 如下

{% extends 'base.html' %}
{% block content1 %}
<style>
  table{
      border: 1px solid #0000ff;
      border-collapse:collapse;
      margin:0px;
  }
  tr{
      border:1px solid #000000;
      margin:0px;
  }
    td{
      border:1px solid #00a0ff;
      padding:0px;
      width:750px;
      height: 420;
      position:relative;
  }
  .videobox{
          position:absolute;
          width: 100%;
          height: 100%;
          top:0px;
          left:0px;
          z-index:0;
  }
  #showbox1{
      background-color: #000000;
      opaity: 0.5;
      font-size: 16px;
      color:#FFFFFF;
      font-weight:bold;      
      position:absolute;
      top:5px;
      left:5px;
      z-index:0;
  }
  #showbox2{
      background-color: #000000;
      opacity: 0.5;        
      font-size: 16px;
      color:#FFFFFF;
      font-weight:bold;      
      position:absolute;
      top:5px;
      left:5px;
      z-index:0;
  }    
  #refresh{
      position:absolute;
      right:5px;
      top:5px;
      height:25px;
      z-index:0;
      overflow:hidden;
      background: rgba(255, 255, 255, 0.3)
  }
  .divshell{
      position: relative;
      background-color: #ffffff;
      width: 100%;
      height: 100%;
      margin:0px;
  }
  .vjs-default-skin { color: #fdfdfd; }
  .vjs-default-skin .vjs-play-progress,
  .vjs-default-skin .vjs-volume-level { background-color: #1880b8 }
  .vjs-default-skin .vjs-control-bar { font-size: 100% }    
</style>
<p></p>
<table>
  <tr>
      <td>
            <div id="div1" class="divshell">
              <div id="div_video1" class="divshell" style="position: absolute;z-index: 0">
                  <video id="video1" class="videobox video-js vjs-default-skin vjs-big-play-centered"></video>                
                  <div id="showbox1"></div>                    
              </div>
              <div id="conn_video1" class="divshell" style="position:absolute;z-index: 1;">
                  <table width="100%" height="100%" align="center" valign="center">
                      <tr>
                          <td align="center">
                              <font color="#000088">
                                  Video 1 直播系統<br>
                                  Supported for all browsers<br><br>
                              </font>
                              <font color="#008800">
                                  Camera Connecting...
                              </font>
                          </td>
                      </tr>
                  </table>                
              </div>
          </div>          
      </td>
      <td>
          <div id="div2" class="divshell">
              <div id="div_video2" class="divshell" style="position: absolute;z-index: 0">
                  <video id="video2" class="videobox video-js vjs-default-skin vjs-big-play-centered"></video>                
                  <div id="showbox2"></div>
              </div>
              <div id="conn_video2" class="divshell" style="position:absolute;z-index: 1;">
                  <table width="100%" height="100%" align="center" valign="center">
                      <tr>
                          <td align="center">
                              <font color="#000088">
                                  Video 2 直播系統<br>
                                  Supported for all browsers<br><br>
                              </font>
                              <font color="#008800">
                                  Camera Connecting...
                              </font>
                          </td>
                      </tr>
                  </table>                
              </div>
          </div>
      </td>
  </tr>
</table> <script> function check_url(index){ video=videos[index]; url=urls[index]; if (window.XMLHttpRequest) conn=new XMLHttpRequest(); else conn=new ActiveXObject("Microsoft.XMLHTTP"); conn.open("GET", url, false); conn.send(); if (conn.readyState==4 && conn.status==200){ document.getElementById(`div_video${index+1}`).style.zIndex=1; document.getElementById(`conn_video${index+1}`).style.zIndex=0; if (video.techGet_("paused")){ video.load(); video.play(); } } else{ document.getElementById(`div_video${index+1}`).style.zIndex=0; document.getElementById(`conn_video${index+1}`).style.zIndex=1; } } function videoStuck(video, index){ var currentTime = video.currentTime(); if(currentTime == lastTimes[index]){ video.load(); video.play(); }else{ lastTimes[index] = currentTime; } } lastTimes=[0,0,0,0,0,0] urls=[]; videos=[]; for (i=0;i<6;i++){ urls[i]=`/live/channel_${i+1}/index.m3u8` videos[i]=videojs( `video${i+1}`, { controls:true,muted: true,autoplay: true,fluid: true,aspectRatio: "16:9", requestFullScreen: true,notSupportedMessage: "no connection" }); videos[i].src([{src:urls[i],type:"application/x-mpegURL"}]); check_url(i); setInterval(check_url,1000, i); setInterval(videoStuck,3000,videos[i],i); } //t3=setInterval(showTime,1000); /* function showTime(){ var NowDate = new Date(); var year = NowDate.getFullYear(); var month = NowDate.getMonth()+1; var day = NowDate.getDate(); var h = NowDate.getHours(); var m = NowDate.getMinutes(); var s = NowDate.getSeconds(); if (month<10)month = "0"+month; if (day<10)day = "0"+day; if (h<10)h = "0"+h; if (m<10)m = "0"+m; if (s<10)s = "0"+s; var t=`${year}/${month}/${day} ${h}:${m}:${s}`; document.getElementById('showbox1').innerHTML = t; document.getElementById('showbox2').innerHTML = t; } */ </script> {% endblock %}

純 video.js

底下代碼為進化版本,完全使用 video.js,不依靠伺服器的檢查程式。當播放的 currentTime == 0 表示沒有播放,currentTime >0 表示開始播放。

<script>
function startVideo(video, index) { var currentTime = video.currentTime(); //document.getElementById("showbox1").innerHTML=currentTime+":"+lastTimes[1]; if (currentTime==0){ document.getElementById(`div_video${index+1}`).style.zIndex=0; document.getElementById(`conn_video${index+1}`).style.zIndex=1; } else{ document.getElementById(`div_video${index+1}`).style.zIndex=1; document.getElementById(`conn_video${index+1}`).style.zIndex=0; } if(currentTime == lastTimes[index]){ video.load(); video.play(); } else{ lastTimes[index] = currentTime; } } urls=[]; var videos=[]; var lastTimes=[0,0,0,0,0,0]; for (i=0;i<6;i++){ urls[i]=`/live/channel_${i+1}/index.m3u8` videos[i]=videojs( `video${i+1}`, { controls:true,muted: true,autoplay: true,fluid: true,aspectRatio: "16:9", requestFullScreen: true,notSupportedMessage: "no connection" }); videos[i].src([{src:urls[i],type:"application/x-mpegURL"}]); startVideo(videos[i], i); setInterval(startVideo,1000,videos[i],i); }
</script>

發佈留言

發佈留言必須填寫的電子郵件地址不會公開。 必填欄位標示為 *