react中使用video.js的踩坑記錄
pnpm add video.js
1、設置中文包
初始化的時候引入video.js/dist/lang/zh-CN.json
videojs.addLanguage(‘zh-CN', zhCN)
即可~
2、樣式錯亂,不在規(guī)定的元素內(nèi)
在video標簽中添加
className='video-js'
3、報錯The element or ID supplied is not valid.
video標簽需要添加id,
在react中,在初始化的時候使用videoRef.current
可以生效,但是在后續(xù)點擊按鈕,切換視頻源的時候報錯了
我這邊是給組件傳進來了一個id值,這樣每次組件使用可以根據(jù)傳入的id值來進行綁定。
4、切換視頻源有時候報錯
he play() request was interrupted by a new load request
每次在palyer.play()的前,先暫停正在播放的視頻palyer.pause()
但是這個問題有時候還是存在,但是不影響,具體原因還未排查到。
5、初始化報錯
The media could not be loaded, either because the server or network failed or because the format is not supported.
原來我是在videoJsOptions 中設置了 sources,但是由于初始化的時候playSrc,為空,所以報錯了。
[ { // 視頻文件的路徑,可以是一個前端相對路徑、后臺視頻文件URL、直播源等 src: playSrc // 視頻源類型 // type: 'application/x-mpegURL' } ]
6、在source中可以添加上
src={playSrc || window.location.href}
否則,初始化會由于src為空報錯
7、參考官方demo
video.js官方demo,將video.js封裝為組件,使用
問題描述
提示:這里描述項目中遇到的問題:
例如
數(shù)據(jù)傳輸過程中數(shù)據(jù)不時出現(xiàn)丟失的情況,偶爾會丟失一部分數(shù)據(jù)
APP 中接收數(shù)據(jù)代碼:
import React, { useState, useRef, useEffect } from 'react' import videojs from 'video.js' import AsideItem from '@/components/AsideItem' import EquipmentSelect from '../Components/EquipmentSelect' import 'video.js/dist/video-js.css' import zhCN from 'video.js/dist/lang/zh-CN.json' import styles from './index.module.scss' export default function index({ id = 'my-video' }) { const videoRef = useRef(null) const playerRef = useRef(null) const [playSrc, setPlaySrc] = useState('') const [option, setOptopm] = useState({}) const vedioSelect = (r) => { if (r['url']) { setPlaySrc(r['url']) const myPlayer = videojs(id) myPlayer.pause() myPlayer.src([{ type: 'application/x-mpegURL', src: r['url'] }]) const playPromise = myPlayer.play(r['url']) if (playPromise !== undefined) { playPromise .then(() => { myPlayer.play(url) }) .catch((e) => { // 音頻加載失敗 }) } } } useEffect(() => { videojs.addLanguage('zh-CN', zhCN) const videoElement = document.getElementById(id) const videoJsOptions = { language: 'zh-CN', // 設置語言為中文 muted: true, poster: 'https://t7.baidu.com/it/u=1819248061,230866778&fm=193&f=GIF', //視頻封面 notSupportedMessage: '此視頻暫無法播放,請稍后再試' } const player = videojs(videoElement, videoJsOptions, () => {}) // 銷毀組件時,銷毀播放器實例 return () => { if (player) { player.dispose() playerRef.current = null } } }, []) return ( <AsideItem title='視頻監(jiān)控'> <div className={styles.monitor} style={{ display: 'flex', flexDirection: 'column', height: '100%' }} > <EquipmentSelect onChange={vedioSelect} /> <div style={{ flex: '1' }}> <video data-setup='{}' style={{ width: '100%', height: '100%' }} ref={videoRef} id={id} controls preload='auto' autoPlay muted className='video-js' > <source id='source' src={playSrc || window.location.href} type='application/x-mpegURL' /> </video> </div> </div> </AsideItem> ) }
封裝demo
import React, { useEffect, useState, useRef } from "react"; import styles from "./index.scss"; import videojs from "video.js"; import "video.js/dist/video-js.css"; import zhCN from "video.js/dist/lang/zh-CN.json"; const PlayBox = ({ videoList = [], type = "iframe", videoStyle,getCurrent }) => { const videoRef = useRef(null); const [playSrc, setPlaySrc] = useState(""); const [currentIndex, setCurrentIndex] = useState(0); const [loading, setLoading] = useState(true); useEffect(() => { videojs.addLanguage("zh-CN", zhCN); const player = videojs(videoRef.current, { language: "zh-CN", // 設置語言為中文 }); // 銷毀組件時,銷毀播放器實例 return () => { if (player) { player.dispose(); } }; }, []); useEffect(() => { if (Array.isArray(videoList) && videoList.length) { setPlaySrc(videoList[0]); setLoading(false); } }, [videoList]); useEffect(() => { setLoading(true); if (type === "video") { const monitorVideo = document.getElementById("monitor"); if (monitorVideo) { monitorVideo.setAttribute("autoplay", "true"); monitorVideo.muted = true; videojs(monitorVideo); } playSrc && playVideo(playSrc); } }, [playSrc, type]); const leftClick = () => { if (videoList.length <= 1) return; let index = currentIndex; if (currentIndex === 0) { index = videoList.length - 1; } else index = currentIndex - 1; setCurrentIndex(index); setPlaySrc(videoList[index]); getCurrent&&getCurrent(index) }; const rightClick = () => { if (videoList.length === 1) return; let index = currentIndex; if (currentIndex === videoList.length - 1) { index = 0; } else index = currentIndex + 1; setCurrentIndex(index); setPlaySrc(videoList[index]); getCurrent&&getCurrent(index) }; const playVideo = (url) => { const myPlayer = videojs("monitor"); myPlayer.pause(); myPlayer.src([{ type: "application/x-mpegURL", src: url }]); let playPromise = myPlayer.play(url); if (playPromise !== undefined) { playPromise .then(() => { myPlayer.play(url); }) .catch((e) => { // 音頻加載失敗 }); } const playButton = document?.querySelector(".vjs-play-control"); if (playButton) { myPlayer.on("play", () => { playButton.classList.remove("vjs-paused"); playButton.classList.add("vjs-playing"); }); myPlayer.on("pause", () => { playButton.classList.remove("vjs-playing"); playButton.classList.add("vjs-paused"); }); } setLoading(false); }; return ( <div className="playBox"> <div className="loading" style={{ display: loading || !playSrc ? "block" : "none" }} > 加載中... </div> {type === "iframe" && playSrc ? ( <div className="video_box"> <iframe src={playSrc} allowFullScreen={true} allowTransparency={true} allow="autoplay" style={{ width: "100%", height: "100%", border: 0 }} onLoad={() => { setLoading(false); }} /> </div> ) : null} {type === "video" ? ( <video ref={videoRef} id="monitor" className="video-js" controls preload="auto" autoPlay muted width={videoStyle?.width || 440} height={videoStyle?.height || 250} data-setup="{}" > <source id="source" src={playSrc || window.location.href} type="application/x-mpegURL" /> </video> ) : null} {Array.isArray(videoList) && videoList.length ? ( <> <div className="left" onClick={leftClick}></div> <div className="right" onClick={rightClick}></div> </> ) : null} </div> ); }; export default PlayBox;
總結
以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。
相關文章
React性能優(yōu)化系列之減少props改變的實現(xiàn)方法
這篇文章主要介紹了React性能優(yōu)化系列之減少props改變的實現(xiàn)方法,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2019-01-01React如何利用Antd的Form組件實現(xiàn)表單功能詳解
這篇文章主要給大家介紹了關于React如何利用Antd的Form組件實現(xiàn)表單功能的相關資料,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧2021-04-04React項目中使用zustand狀態(tài)管理的實現(xiàn)
zustand是一個用于狀態(tài)管理的小巧而強大的庫,本文主要介紹了React項目中使用zustand狀態(tài)管理的實現(xiàn),具有一定的參考價值,感興趣的可以了解一下2023-10-10在react-antd中彈出層form內(nèi)容傳遞給父組件的操作
這篇文章主要介紹了在react-antd中彈出層form內(nèi)容傳遞給父組件的操作,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2020-10-10字節(jié)封裝React組件手機號自動校驗格式FormItem
這篇文章主要為大家介紹了字節(jié)封裝React組件手機號自動校驗格式FormItem,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪2022-08-08