uniapp中使用videojs構(gòu)建H5直播播放器

這兩天在開發(fā)H5直播帶貨功能模塊,使用原生的video播放器播放不了m3u8的流地址鸳碧,于是找了videojs报强,參考了網(wǎng)上的一些資料研究了一下妇穴,感覺還不錯爬虱,videojs播放m3u8流地址還挺穩(wěn)定的,下面就簡單記錄一下uniapp里面使用方式腾它。

效果

一跑筝、使用npm安裝videojs

npm i video.js --save
npm i videojs-flash --save

二、頁面中導(dǎo)入videojs

import videojs from 'video.js'
import 'video.js/dist/video-js.min.css'
import 'videojs-flash'

三瞒滴、定義播放器區(qū)域

<!-- 播放器顯示區(qū)域 -->
<view class="video-display-wrap">
      <!-- 播放器最終在view的子級顯示 -->
      <view
        class="video-js"
        ref="video"
        style="width: 100%; height: 100%"
      ></view>
      <!-- 播放器最終在view的子級顯示 -->

      <!--  自定義播放按鈕(圖片自行替換) -->
      <image
        v-if="!isPlaying"
        :src="resource.playBtnIcon"
        mode="heightFix"
        class="play-btn-icon"
        @click="playVideo"
      ></image>
      <!--  自定義播放按鈕 -->

      <!-- 視頻蒙版用于點擊視頻能夠切換播放狀態(tài) -->
      <view class="video-mask" @click="switchPlayVideo">
      </view>
      <!-- 視頻蒙版用于點擊視頻能夠切換播放狀態(tài) -->
    </view>
<!-- 播放器顯示區(qū)域 -->

四曲梗、onReady中初始化播放器

1.data里面定義變量

data() {
  return {
      ...
      //視頻播放器
      videoPlayer: null,
      //是否正在播放
      isPlaying: false,
  }
}

2.onReady里面

onReady() {
    ...
    //初始化播放器
    this.initVideo()
},

3.初始化播放器以及基礎(chǔ)的操作方法

#示例代碼,部分變量是業(yè)務(wù)中用到的
initVideo() {
      let video = document.createElement('video')
      video.id = 'video'
      //如果需要全屏幕展現(xiàn)播放器需要增加 object-fit: cover;
      video.style = 'width: 100%; height: 100%;'
      video.controls = false
      video.setAttribute('playsinline', true) //IOS微信瀏覽器支持小窗內(nèi)播放
      video.setAttribute('webkit-playsinline', true) //這個bai屬性是ios 10中設(shè)置可以讓視頻在小du窗內(nèi)播放,也就是不是全屏播放的video標(biāo)簽的一個屬性
      video.setAttribute('x5-video-player-type', 'h5') //安卓 聲明啟用同層H5播放器 可以在video上面加?xùn)|西
      let source = document.createElement('source')
      source.src = 'http://xxxx.m3u8'  //設(shè)定的流地址
      //根據(jù)流地址的后綴設(shè)置好播放類型
      if (source.src.indexOf('.mp4') !== -1) {
        //mp4類型
        source.type = 'video/mp4'
      } else if (source.src.indexOf('.m3u8') !== -1) {
        //hls類型
        source.type = 'application/x-mpegURL'
      } else if (source.src.indexOf('.flv') !== -1) {
        //flv類型
        source.type = 'video/flv'
      } else {
        //rtmp類型
        source.type = 'rtmp/hls'
      }
      //將播放源添加到video的子級
      video.appendChild(source)
      //掛載到視頻容器中
      this.$refs.video.$el.appendChild(video)
      //獲取屏幕寬高計算出需要展現(xiàn)的比例
      let aspectRatio = '16:9'   //默認橫屏
      //activityDetail變量是我業(yè)務(wù)中用到的妓忍,請自行根據(jù)實際情況做調(diào)整
      if (this.activityDetail.style.mode == 1) {
        //如果是豎屏模式虏两,動態(tài)計算出設(shè)備寬高,設(shè)定一個比例
        const systemInfo = uni.getSystemInfoSync()
        aspectRatio = systemInfo.windowWidth + ':' + systemInfo.windowHeight
      }
      let that = this
      this.videoPlayer = videojs(
        'video',
        {
          //視頻封面圖(activityDetail變量是我業(yè)務(wù)中用到的世剖,請自行根據(jù)實際情況做調(diào)整)
          poster: getImageUrl(this.activityDetail.indexpic),
          //視頻標(biāo)題(activityDetail變量是我業(yè)務(wù)中用到的定罢,請自行根據(jù)實際情況做調(diào)整)
          title: this.activityDetail.title,
          width: '100%',
          height: '100%',
          playbackRates: [0.7, 1.0, 1.5, 2.0], //播放速度
          autoDisable: true,
          preload: 'none', //auto - 當(dāng)頁面加載后載入整個視頻 meta - 當(dāng)頁面加載后只載入元數(shù)據(jù) none - 當(dāng)頁面加載后不載入視頻
          language: 'zh-CN',
          fluid: true, // 自適應(yīng)寬高
          muted: false, //  是否靜音
          aspectRatio: aspectRatio, // 將播放器置于流暢模式,并在計算播放器的動態(tài)大小時使用該值旁瘫。值應(yīng)該代表一個比例 - 用冒號分隔的兩個數(shù)字(例如"16:9"或"4:3")
          controls: false, //是否擁有控制條 【默認true】,如果設(shè)為false ,那么只能通過api進行控制了祖凫。也就是說界面上不會出現(xiàn)任何控制按鈕
          autoplay: true, //如果true,瀏覽器準(zhǔn)備好時開始回放琼蚯。 autoplay: "muted", // //自動播放屬性,muted:靜音播放
          loop: true, // 導(dǎo)致視頻一結(jié)束就重新開始。 視頻播放結(jié)束后惠况,是否循環(huán)播放
          techOrder: ['html5', 'flash'], //播放順序
          screenshot: true,
          controlBar: {
            volumePanel: {
              //聲音樣式
              inline: false // 不使用水平方式
            },
            timeDivider: true, // 時間分割線
            durationDisplay: true, // 總時間
            progressControl: true, // 進度條
            remainingTimeDisplay: true, //當(dāng)前以播放時間
            fullscreenToggle: true, //全屏按鈕
            pictureInPictureToggle: true //畫中畫
          }
        },
        function () {
          this.on('error', function () {
            //請求數(shù)據(jù)時遇到錯誤
            console.log('請求數(shù)據(jù)時遇到錯誤')
          })
          this.on('stalled', function () {
            //網(wǎng)速失速
            console.log('網(wǎng)速失速')
          })
          this.on('play', function () {
            //開始播放
            console.log('開始播放')
            that.isPlaying = true
          })
          this.on('pause', function () {
            //暫停
            console.log('暫停')
            that.isPlaying = false
          })
          this.on('timeupdate', function () {})
        }
      )
},
//切換播放視頻
switchPlayVideo() {
  if (this.isPlaying) {
    //正在播放就暫停
    this.pauseVideo()
  } else {
    //暫停就播放
    this.playVideo()
  }
},
//播放視頻
playVideo() {
  this.videoPlayer.play()
},
//暫停播放視頻
pauseVideo() {
   this.videoPlayer.pause()
},

五凌停、自定義的樣式

.video-display-wrap {
    position: relative;
    display: flex;
    justify-content: center;
    align-items: center;
    //播放按鈕
    .play-btn-icon {
      position: absolute;
      z-index: 998;
      width: 100rpx;
      height: 100rpx;
    }
    //視頻蒙版
    .video-mask {
      position: absolute;
      z-index: 998;
      width: 100%;
      height: 100%;
    }
}

六、視頻畫中畫控制(通常是頁面中彈窗打開其他頁面售滤,擋住了視頻播放區(qū)域的時候可以用到)

1.進入畫中畫

this.videoPlayer.requestPictureInPicture()

2.退出畫中畫

this.videoPlayer.exitPictureInPicture()

七、注意事項

  • 由于H5在安卓設(shè)備里面限制視頻一進來就播放台诗,必須用戶在頁面中就交互動作的時候完箩,才可以播放視頻,所以可能設(shè)置了播放器自動播放沒有效果拉队,可以在頁面中綁定一個點擊事件弊知,無論用戶點哪,就觸發(fā)播放視頻(如果視頻未播放的時候)粱快,這樣模擬自動播放
  • 好像沒找到視頻本身能點擊的事件秩彤,就算直接在播放器容器中綁定點擊事件也沒有效果,所以如果需要實現(xiàn)點擊視頻能在播放與暫停之間切換的話事哭,可以在視頻上面加一個透明的遮罩蒙版漫雷,層級要高于播放器,這樣在蒙版上綁定點擊事件就能操作起來了
  • 文中的activityDetail和resource變量是本人業(yè)務(wù)中用到的鳍咱,如果您需要使用降盹,請自行替換。
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末谤辜,一起剝皮案震驚了整個濱河市蓄坏,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌丑念,老刑警劉巖涡戳,帶你破解...
    沈念sama閱讀 212,383評論 6 493
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異脯倚,居然都是意外死亡渔彰,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,522評論 3 385
  • 文/潘曉璐 我一進店門推正,熙熙樓的掌柜王于貴愁眉苦臉地迎上來胳岂,“玉大人,你說我怎么就攤上這事舔稀∪榉幔” “怎么了?”我有些...
    開封第一講書人閱讀 157,852評論 0 348
  • 文/不壞的土叔 我叫張陵内贮,是天一觀的道長产园。 經(jīng)常有香客問我汞斧,道長,這世上最難降的妖魔是什么什燕? 我笑而不...
    開封第一講書人閱讀 56,621評論 1 284
  • 正文 為了忘掉前任粘勒,我火速辦了婚禮,結(jié)果婚禮上屎即,老公的妹妹穿的比我還像新娘庙睡。我一直安慰自己,他們只是感情好技俐,可當(dāng)我...
    茶點故事閱讀 65,741評論 6 386
  • 文/花漫 我一把揭開白布乘陪。 她就那樣靜靜地躺著,像睡著了一般雕擂。 火紅的嫁衣襯著肌膚如雪啡邑。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,929評論 1 290
  • 那天井赌,我揣著相機與錄音谤逼,去河邊找鬼。 笑死仇穗,一個胖子當(dāng)著我的面吹牛流部,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播纹坐,決...
    沈念sama閱讀 39,076評論 3 410
  • 文/蒼蘭香墨 我猛地睜開眼贵涵,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了恰画?” 一聲冷哼從身側(cè)響起宾茂,我...
    開封第一講書人閱讀 37,803評論 0 268
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎拴还,沒想到半個月后跨晴,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,265評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡片林,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,582評論 2 327
  • 正文 我和宋清朗相戀三年端盆,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片费封。...
    茶點故事閱讀 38,716評論 1 341
  • 序言:一個原本活蹦亂跳的男人離奇死亡焕妙,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出弓摘,到底是詐尸還是另有隱情焚鹊,我是刑警寧澤,帶...
    沈念sama閱讀 34,395評論 4 333
  • 正文 年R本政府宣布韧献,位于F島的核電站末患,受9級特大地震影響研叫,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜璧针,卻給世界環(huán)境...
    茶點故事閱讀 40,039評論 3 316
  • 文/蒙蒙 一嚷炉、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧探橱,春花似錦申屹、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,798評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至私植,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間车酣,已是汗流浹背曲稼。 一陣腳步聲響...
    開封第一講書人閱讀 32,027評論 1 266
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留湖员,地道東北人贫悄。 一個月前我還...
    沈念sama閱讀 46,488評論 2 361
  • 正文 我出身青樓,卻偏偏與公主長得像娘摔,于是被迫代替她去往敵國和親窄坦。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 43,612評論 2 350

推薦閱讀更多精彩內(nèi)容