最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

React videojs 實現(xiàn)自定義組件(視頻畫質(zhì)/清晰度切換) 的操作代碼

 更新時間:2023年08月28日 11:44:55   作者:Might°  
最近使用videojs作為視頻處理第三方庫,用來對接m3u8視頻類型,這里總結(jié)一下自定義組件遇到的問題及實現(xiàn),感興趣的朋友跟隨小編一起看看吧

前言

最近使用videojs作為視頻處理第三方庫,用來對接m3u8視頻類型。這里總結(jié)一下自定義組件遇到的問題及實現(xiàn),目前看了許多文章也不全,官方文檔寫的也不是很詳細,自己摸索了一段時間陸陸續(xù)續(xù)完成了,這是實現(xiàn)后的效果.

image.png

樣式啥的自己檢查后覆蓋就行了,沒啥說的,重點看看畫質(zhì)切換這個組件如何實現(xiàn)的。最開始我是采用函數(shù)組件直接嵌入進去,后面發(fā)現(xiàn)是報錯的,原因是hook使用范圍有誤,找了半天也不知道是什么原因。后面采用繼承Videojs內(nèi)的menu組件來實現(xiàn)。

代碼實現(xiàn)

option配置如下

 const options: any = {
    controls: true,
    preload: 'auto',
    language: 'zh-CN',
    width: 854,
    height: 480,
    playbackRates: [0.5, 0.75, 1, 1.5, 2], // 倍速數(shù)組
    controlBar: {
      children: {
        PlayToggle: true,
        CurrentTimeDisplay: true,
        DurationDisplay: true,
        ProgressControl: true,
        Quality: true,
        PlaybackRateMenuButton: true,
        volumePanel: {
          inline: false,
        },
        PictureInPictureToggle: true,
        FullscreenToggle: true,
      },
    },
  }

video組件

import { ForwardedRef, forwardRef, useEffect, useImperativeHandle, useRef } from 'react'
import videojs from 'video.js'
import Quality from './quality'
import './index.less'
interface videoComProps {
  videoOptions: any
  onReady: (player: any) => void
  src?: string
}
const VideoWrapper = (props: videoComProps, ref: ForwardedRef<any>) => {
  const { videoOptions, onReady, src } = props
  const videoRef = useRef<any>(null)
  const playerRef = useRef<any>(null)
  function toggleTv(obj: any) {
    const player = playerRef?.current
    if (!player) return
    player.src(obj.src)
    player.load(obj.load)
    player.play()
  }
  useEffect(() => {
    if (!playerRef?.current && videoRef.current) {
      // 注冊組件  一定要在使用之前注冊哦
      videojs.registerComponent('Quality', Quality as any)
      // 初始化video
      const player = (playerRef.current = videojs(videoRef.current, videoOptions, () => {
        onReady(player)
      }))
    }
  }, [videoRef])
  useEffect(() => {
    const player = playerRef.current
    return () => {
      // 組件銷毀的時候,銷毀視頻播放器的實例
      if (player && !player.isDisposed()) {
        player.dispose()
        playerRef.current = null
      }
    }
  }, [playerRef])
  // ref拋出變量
  useImperativeHandle(ref, () => ({
    toggleTv,
  }))
  return (
    <div className="video-wrapper">
      <video
        ref={videoRef}
        className="video-js vjs-big-play-centered"
      >
        <source src={src} />
        {/* <span>視頻走丟了,請稍后再試</span> */}
      </video>
    </div>
  )
}
export default forwardRef(VideoWrapper)

自定義組件

// 切換視頻清晰度代碼
import videoJs from 'video.js'
import { createRoot } from 'react-dom/client'
// 初始化清晰度按鈕
const TextTrackMenuItem: any = videoJs.getComponent('TextTrackMenuItem')
const TrackButton: any = videoJs.getComponent('TrackButton')
const videoQuality = '超清,高清,自動'
class QualityTrackItem extends TextTrackMenuItem {
  constructor(player: any, options: any) {
    super(player, options)
    this.mount = this.mount.bind(this)
    player.ready(() => {
      this.mount()
    })
    this.on('dispose', () => {
      this.root.unmount()
    })
    if (options.index === 2) {
      this.addClass('vjs-selected')
    }
  }
  // 切換高清播放源,this 指向被點擊QualityTrackItem實例
  handleClick(event: any) {
    // 先將所有選項的選中狀態(tài)設(shè)為未選中
    this.parentComponent_.children_.forEach((c: any) => {
      c.selected(false)
    })
    // 選中當前
    this.selected(true)
    // 選中后修改按鈕文本
    const btn = document.querySelector('.vjs-menu-button .vjs-icon-placeholder')
    if (!btn) return
    btn.innerHTML = this.track.label
    // 其他邏輯 通知修改視頻源地址進行切換
    console.log('切換視頻源')
  }
  mount() {
    this.root = createRoot(this.el()).render(<div>{this.track.label}</div>)
  }
}
// 擴展基類,實現(xiàn)菜單按鈕
class QualityTrackButton extends TrackButton {
  constructor(player: any, options: any) {
    super(player, options)
    this.controlText('畫質(zhì)選擇')
    this.children()[0].el().firstElementChild.innerText = '自動'
    this.addClass('vjs-quality')
  }
  createItems() {
    const qualityKeyArray = videoQuality.split(',')
    if (qualityKeyArray.length > 0) {
      const result: any = []
      qualityKeyArray.forEach((key, index: number) => {
        result.push(
          new QualityTrackItem(this.player_, {
            track: {
              label: key,
              value: key,
            },
            selectable: true,
            index,
          })
        )
      })
      return result
    } else {
      return []
    }
  }
}
export default QualityTrackButton

可能遇到的問題

1.卸載不了對應(yīng)事件

  const handleUpdate = useCallback(() => {
    const player = playerRef.current
    //window.document.fullscreenElement檢測視頻是否正在全屏
    // console.log('播放中,當前時間是', player.currentTime())
    if (player.currentTime() > 10) {
      if (window.document.fullscreenElement) {
        // 如果是全屏 退出全屏
        window.document.exitFullscreen()
      }
      player.currentTime(10)
      setOverlay(true)
      player.pause()
    }
  }, [])
useEffect(() => {
    if (!playerRef?.current && videoRef.current) {
      // 注冊組件  一定要在使用之前注冊哦
      videojs.registerComponent('Quality', Quality as any)
      // 初始化video
      const player = (playerRef.current = videojs(videoRef.current, videoOptions, () => {
        onReady(player)
      }))
      playFlag && player.on('timeupdate', handleUpdate)
    }
  }, [videoRef])
  // 加入學習
  const handelAddLearn = () => {
    const player = playerRef.current
    player.off('timeupdate', handleUpdate)
    setPlayFlag(false)
    setOverlay(false)
    player.play()
  }

把對應(yīng)需要卸載的事件采用useCallback進行處理,這樣的事件的地址就不會變化造成卸載失效的問題。

到此這篇關(guān)于React videojs 實現(xiàn)自定義組件(視頻畫質(zhì)/清晰度切換) 的操作代碼的文章就介紹到這了,更多相關(guān)videojs自定義組件內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • React?Suspense解決競態(tài)條件詳解

    React?Suspense解決競態(tài)條件詳解

    這篇文章主要為大家介紹了React?Suspense解決競態(tài)條件詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2022-11-11
  • React通過hook實現(xiàn)封裝表格常用功能

    React通過hook實現(xiàn)封裝表格常用功能

    這篇文章主要為大家詳細介紹了React通過hook封裝表格常用功能的使用,文中的示例代碼講解詳細,具有一定的借鑒價值,有需要的小伙伴可以參考下
    2023-12-12
  • react?源碼中位運算符的使用詳解

    react?源碼中位運算符的使用詳解

    這篇文章主要為大家詳細介紹了react?位運算符,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下,希望能夠給你帶來幫助
    2022-03-03
  • react之umi配置國際化語言locale的踩坑記錄

    react之umi配置國際化語言locale的踩坑記錄

    這篇文章主要介紹了react之umi配置國際化語言locale的踩坑記錄,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2023-02-02
  • ReactQuery系列之數(shù)據(jù)轉(zhuǎn)換示例詳解

    ReactQuery系列之數(shù)據(jù)轉(zhuǎn)換示例詳解

    這篇文章主要為大家介紹了ReactQuery系列之數(shù)據(jù)轉(zhuǎn)換示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2022-11-11
  • antd?upload上傳如何獲取文件寬高

    antd?upload上傳如何獲取文件寬高

    這篇文章主要介紹了antd?upload上傳如何獲取文件寬高問題,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2023-02-02
  • ReactNative之鍵盤Keyboard的彈出與消失示例

    ReactNative之鍵盤Keyboard的彈出與消失示例

    本篇文章主要介紹了ReactNative之鍵盤Keyboard的彈出與消失示例,具有一定的參考價值,有興趣的可以了解一下
    2017-07-07
  • 一文詳解React Redux設(shè)計思想與工作原理

    一文詳解React Redux設(shè)計思想與工作原理

    最近看項目中使用了?Redux,?便嘗試了解一波?Redux?的設(shè)計思想與工作原理,所以本文詳細的給大家介紹了Redux設(shè)計思想與工作原理,需要的朋友可以參考下
    2023-09-09
  • React項目中使用zustand狀態(tài)管理的實現(xiàn)

    React項目中使用zustand狀態(tài)管理的實現(xiàn)

    zustand是一個用于狀態(tài)管理的小巧而強大的庫,本文主要介紹了React項目中使用zustand狀態(tài)管理的實現(xiàn),具有一定的參考價值,感興趣的可以了解一下
    2023-10-10
  • React頁面刷新數(shù)據(jù)不丟失的五種方案

    React頁面刷新數(shù)據(jù)不丟失的五種方案

    前端開發(fā)中,相信大家都遇到過這樣的痛點:頁面一刷新,辛辛苦苦填的表單數(shù)據(jù)沒了,精心選擇的篩選條件重置了,今天我們就來深入探討React中數(shù)據(jù)持久化的5大核心方案,從簡單到復雜,幫你徹底解決這個難題,需要的朋友可以參考下
    2025-12-12

最新評論

玉龙| 闽侯县| 克山县| 兴国县| 沁源县| 韩城市| 胶南市| 昌吉市| 许昌市| 台前县| 红河县| 德兴市| 曲靖市| 大城县| 中牟县| 洪洞县| 宾阳县| 兴城市| 蚌埠市| 江门市| 洪雅县| 西乡县| 密云县| 抚远县| 德兴市| 武陟县| 潮州市| 晋州市| 酉阳| 运城市| 延吉市| 随州市| 东明县| 二连浩特市| 科技| 云林县| 乌什县| 府谷县| 泸定县| 邓州市| 普兰店市|