前端Web瀏覽器基於Flash如何實時播放監控視頻畫面(四)之使用videoJs‘拉流’

本片文章只是起到拋磚引玉的作用,能從頭到尾走通就行,並不做深入研究。爲了讓文章通俗易懂,儘量使用白話描述。


0x001: 下載videoJs

對於Video.js 5.x及更低版本,Flash技術(videojs-flash.js插件)是Video.js核心存儲庫的一部分,不需要單獨下載。對於Video.js 6.x及更高版本,Flash技術位於單獨的存儲庫中,需要單獨下載。


從V7開始,我們將不再支持IE 11之前的Microsoft Internet Explorer版本,包括IE 8、9和10.


請根據自己的業務場景需求抉擇下載哪一個版本,這裏選擇 video-js-6.13.0 下載。
video-jshttps://github.com/videojs/video.js/releases/download/v6.13.0/video-js-6.13.0.zip
video-js-swfhttps://github.com/videojs/video-js-swf/archive/v5.4.2.zip ,內網用戶必需下載,後面解釋why?

下載完成後解壓,其中examples文件夾爲video-js示例,可以自己運行一下查看效果。



0x002: 引用videoJs

examples文件夾內的示例只是作爲基於HTML5的播放,要想基於Flash播放,在示例html文件引用基礎之上還需 格外 引入以下文件:

1 <script src="項目根路徑/ie8/videojs-ie8.min.js"></script>    (不使用ie8無需引入)
2 <script src="項目根路徑/lang/zh-CN.js"></script>    (video播放界面支持中文)
3 <script src="項目根路徑/videojs-flash.js"></script>    (支持flash)
4 
5 <script>
6     videojs.options.flash.swf = "項目根路徑/video-js.swf";//全局方式覆蓋,SWF文件在Flash技術的位置
7 </script>


0x003: 使用videoJs

初始化videoJs有兩種方式,examples文件夾內的示例是以html屬性初始化,data-setup="{}"
爲了方便編寫事件,下面以JS方式初始化(代碼僅供參考):

  1 <!DOCTYPE html>
  2 <html lang="en" style="height:100%">
  3 <head>
  4     <meta http-equiv="Access-Control-Allow-Origin" content="*">
  5     <meta charset="utf-8">
  6     <meta name="description" content="Opencast Media Player">
  7     <meta name="author" content="Opencast">
  8     <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no">
  9     <title>RTMP播放</title>
 10     
 11     <link href="video-js.min.css" rel="stylesheet">
 12     <script src="ie8/videojs-ie8.min.js"></script>
 13     <script src="video.min.js"></script>
 14     <script src="lang/zh-CN.js"></script>
 15     
 16     <script src="videojs-flash.js"></script>
 17     <script src="jquery-1.11.1.min.js"></script>
 18     
 19     <script>
 20         videojs.options.flash.swf = "video-js.swf";//全局方式覆蓋 SWF文件在Flash技術位置的位置
 21     </script>
 22 
 23     <style type="text/css">
 24         body {height: 100%;margin: 0;padding: 0;}
 25         .videoArea{width: 49.8%;height: 49.8%; float: left;border: 1px solid grey; }
 26         .videoTips{border: 1px solid grey; font: 12px arial,sans-serif; margin: 10px; padding: 5px;
 27             width: 97.5%; height:100px; overflow:auto; float: left;"}
 28     </style>
 29 </head>
 30 <body>
 31 
 32     <div id="video_1_area" class="videoArea">
 33         <video id="example_video_1" class="video-js vjs-default-skin vjs-big-play-centered" controls style="width: 100%;height: 100%;" >
 34               <!-- RTMP直播源地址 截止至發稿前直播源仍然可用-->
 35             <!-- <source src="rtmp://live.hkstv.hk.lxdns.com/live/hks1"> -->
 36             <source src="rtmp://58.200.131.2:1935/livetv/hunantv" type="rtmp/mp4">
 37             <!-- <source src="rtmp://192.168.234.131:1935/mytv/test1" type="rtmp/flv"> -->
 38             <p class="vjs-no-js">To view this video please enable JavaScript, and consider upgrading to a web browser that <a href="" target="_blank">supports HTML5 video</a></p>
 39         </video>
 40     </div>
 41  
 42     <div class="videoTips"></div>
 43 </body>
 44      <script>
 45          var options = {
 46                  poster: 'Logo.png',            //未播放時 的封面
 47                 techOrder: ["flash", "html5"],    //定義Video.js技術首選的順序。這意味着Html5首選技術
 48                 //autoplay: true,                    //播放器準備好之後,是否自動播放 【默認false】
 49                 //controls: false,                 //是否顯示控制欄
 50                 preload: 'auto',                //預加載
 51                 muted: true,                    //靜音
 52                 language: "zh-CN",                //初始化語言
 53                 //fluid: true,
 54                 /*flash: {                        //指定Video.js SWF文件在Flash技術的位置
 55                     swf: '//path/to/videojs.swf'
 56                 },*/
 57                 /*controlBar: {                     // 配置控制欄
 58                     timeDivider: false, // 時間分割線
 59                     durationDisplay: false, // 總時間
 60                     progressControl: true, // 進度條
 61                     customControlSpacer: true, // 未知
 62                     fullscreenToggle: true // 全屏
 63                 },*/
 64             }
 65          
 66         var player = videojs('example_video_1', options, function(){
 67                 fillTips('<span>播放器1初始化成功</span>');
 68                 videojs.log('Your player is ready!');
 69                 setTimeout(function () {
 70                     player.play();
 71                 }, 2000);
 72                 
 73                 player.one("playing", function () {         // 監聽播放
 74                     fillTips('<span>播放器1開始播放</span>');
 75                 });
 76                 player.one("play", function () {         // 監聽播放
 77                     console.log('準備開始播放');
 78                 });
 79                 player.on('pause', function () {
 80                     console.log('暫停播放');
 81                 });
 82                 player.on('ended', function () {
 83                     console.log('結束播放');
 84                 });
 85 
 86                 //------events    綁定事件用on    移除事件用off
 87                 player.on('loadstart',function () {
 88                   console.log('loadstart------------')
 89                 });
 90                 player.on('loadedmetadata',function () {
 91                   console.log('loadedmetadata---視頻源數據加載完成----')
 92                 });
 93                 player.on('loadeddata',function () {
 94                   console.log('loadeddata---渲染播放畫面----');
 95                 });
 96                 player.on('progress',function () {
 97                   console.log('progress-------加載過程----')
 98                 });
 99                 player.on('timeupdate',function () {
100                   const curTime = this.currentTime();
101                   //console.log('timeupdate-------------',curTime);
102                 })
103                 player.off('timeupdate',function () {
104                   console.log('off----------timeupdate')
105                 })
106                 //this.play();
107             });
108     </script>
109 
110     <script>
111         function fillTips (str) {
112             document.getElementsByClassName('videoTips')[0].innerHTML+=str+"<br/>";
113         }
114     </script>
115 
116 </html>

 
以上代碼<source>標籤中的src爲湖南衛視的rtmp地址,如果可以正常播放,說明videoJs已經搭建完畢。
之後將<source>標籤中的src換爲自己RTMP服務器的地址,保存,刷新頁面觀察是否能正常播放監控畫面


0x004: videoJs注意事項

  • VideoJs播放器html頁面如果不丟到服務器環境下可能出現無法播放的情況。

  • 對於Video.js 5.x及更低版本,Flash技術是Video.js核心存儲庫的一部分。video.js 6.x及更高版本(Video.js> = 6.0.0) 雖然官方說:Flash技術位於單獨的存儲庫中,即videojs-flash.js插件。但值得注意的是,videojs-flash.js在引入後會自動通過網絡加載video-js.swf。
    若是內網環境使用videojs-flash.js插件,則必需先將video-js.swf下載到本地,其次再在項目中引用並且使用全局設置覆蓋JS源碼內寫死的video-js.swf。如下:
    videojs.options.flash.swf = "video-js.swf";
    強烈建議使用本地video-js.swf,因爲這樣可以減少一些奇葩的問題出現,爲排錯節省時間。

  • Video.js對於IE8的支持,官網這樣解釋
    Beginning with v7, we will no longer support Microsoft Internet Explorer versions prior to IE 11, including IE 8, 9, and 10.
    從V7開始,我們將不再支持IE 11之前的Microsoft Internet Explorer版本,包括IE 8、9和10.
    強烈建議使用Video.js V7.0之前的6.x的最後一個版本,因爲新版本總是要比老版本優化的BUG多。 即,沒必要非得使用5.x(當然選擇什麼版本是你的權利)

  • 經過多次測試發現,Video.js對於普通標準化的RTMP流可以很好的支持,但若是對於非標準化的RTMP流連接成功的機率是隨機的,
    有時能成功有時不能成功。尤其是對於非標準化的RTSP流使用ffmpeg推的RTMP流。(海康可見光流基本可以在3S內接入,但另一個廠家的熱像設備流基本要看緣分了)

    對於這種現象的解決方案就是,在保證VLC或其他播放器能正常播放的前提下,HTML頁面初始化一段時間內(比如15s,20s等)Video.js若連接不成功,則繼續嘗試重新連接,等待若干時間(比如15s,20s等),若仍連接不成功,則再繼續嘗試重新連接,以此類推,直到連接成功。
    謹記,等待連接的時間要放久一點,否則會出現某個時間點內Video.js一直連接不成功,導致死循環。

  • 嘗試重新連接前,請先將當前Video.js的實例 銷燬 掉。否則會一直報錯。這個錯是一直在累加的。
    videojs-flash.js:610 Uncaught TypeError: this.el_.vjs_getProperty is not a function
    VIDEOJS: ERROR: TypeError: this.el_.vjs_getProperty is not a function(…)

     

  • 嘗試重新連接時,一定要 重新生成 Video.js。HTML裏的<video>標籤塊和<script>裏的videojs(videoId, {}, function(){})都得重新生成!
    因爲第一次執行videojs(videoId, {}, function(){})初始化時,html DOM結構已經被解析成別的樣子了。
    (一開始不瞭解,怎樣重新賦值src,怎樣調load()方法都不好使,在這上面耗費了很長很長時間)
    參考 https://blog.csdn.net/w3624270/article/details/78504877
       https://blog.csdn.net/qq_42842709/article/details/84942207

  • 注意必須用 videojs獲取的實例 才能調用方法,用jquery 或 document.getXXXXXXXX()獲取的對象不行。


0x005: 遺留問題

未曾在官網找到 videoJs 監測視頻源出現異常或斷開的事件
(因爲車間內使用監控的RTSP流並不是很穩定,並不是很標準,有時候會斷流,從而導致ffmpeg轉RTMP時ERROR。那麼如果有此監聽事件就可以To Do Something)

0x006: 使用體驗

對於videoJs初步使用感受並沒有網上文章寫的那麼好用,那麼牛X。對於播放普通Mp4文件的用途來說,網速給力的話可能並沒有什麼感覺(斷點續播有點問題),但對於直播的用途來說,小毛病很多,需要注意的點很多,有些問題可能會需要很長時間才能找到解決方法,甚至無果。只能說現在能基本滿足現需求,如果後期有滿意的替代品會考慮將其更換。

0x007: 完結

至此,前端Web瀏覽器基於Flash如何實時播放監控視頻畫面的文章已經全部完結。
關於文章中遺留的問題或編寫錯誤之處,如果您有什麼更好的見解或解決方案歡迎指出或批評,不吝賜教。


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章