vps做电影网站,产品宣传片公司,凡客家具质量怎么样,wordpress 美化 插件大全前言
最近使用videojs作为视频处理第三方库#xff0c;用来对接m3u8视频类型。这里总结一下自定义组件遇到的问题及实现#xff0c;目前看了许多文章也不全#xff0c;官方文档写的也不是很详细#xff0c;自己摸索了一段时间陆陆续续完成了#xff0c;这是实现后的效果.…前言
最近使用videojs作为视频处理第三方库用来对接m3u8视频类型。这里总结一下自定义组件遇到的问题及实现目前看了许多文章也不全官方文档写的也不是很详细自己摸索了一段时间陆陆续续完成了这是实现后的效果. 样式啥的自己检查后覆盖就行了没啥说的重点看看画质切换这个组件如何实现的。最开始我是采用函数组件直接嵌入进去后面发现是报错的原因是hook使用范围有误找了半天也不知道是什么原因。后面采用继承Videojs内的menu组件来实现。
代码实现
option配置如下 const options: any {controls: true,preload: auto,language: zh-CN,width: 854,height: 480,playbackRates: [0.5, 0.75, 1, 1.5, 2], // 倍速数组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 ./qualityimport ./index.lessinterface videoComProps {videoOptions: anyonReady: (player: any) voidsrc?: string
}const VideoWrapper (props: videoComProps, ref: ForwardedRefany) {const { videoOptions, onReady, src } propsconst videoRef useRefany(null)const playerRef useRefany(null)function toggleTv(obj: any) {const player playerRef?.currentif (!player) returnplayer.src(obj.src)player.load(obj.load)player.play()}useEffect(() {if (!playerRef?.current videoRef.current) {// 注册组件 一定要在使用之前注册哦videojs.registerComponent(Quality, Quality as any)// 初始化videoconst player (playerRef.current videojs(videoRef.current, videoOptions, () {onReady(player)}))}}, [videoRef])useEffect(() {const player playerRef.currentreturn () {// 组件销毁的时候销毁视频播放器的实例if (player !player.isDisposed()) {player.dispose()playerRef.current null}}}, [playerRef])// ref抛出变量useImperativeHandle(ref, () ({toggleTv,}))return (div classNamevideo-wrappervideoref{videoRef}classNamevideo-js vjs-big-play-centeredsource 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) {// 先将所有选项的选中状态设为未选中this.parentComponent_.children_.forEach((c: any) {c.selected(false)})// 选中当前this.selected(true)// 选中后修改按钮文本const btn document.querySelector(.vjs-menu-button .vjs-icon-placeholder)if (!btn) returnbtn.innerHTML this.track.label// 其他逻辑 通知修改视频源地址进行切换console.log(切换视频源)}mount() {this.root createRoot(this.el()).render(div{this.track.label}/div)}
}
// 扩展基类实现菜单按钮
class QualityTrackButton extends TrackButton {constructor(player: any, options: any) {super(player, options)this.controlText(画质选择)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.卸载不了对应事件 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)// 初始化videoconst player (playerRef.current videojs(videoRef.current, videoOptions, () {onReady(player)}))playFlag player.on(timeupdate, handleUpdate)}}, [videoRef])// 加入学习const handelAddLearn () {const player playerRef.currentplayer.off(timeupdate, handleUpdate)setPlayFlag(false)setOverlay(false)player.play()}把对应需要卸载的事件采用useCallback进行处理这样的事件的地址就不会变化造成卸载失效的问题
END
希望能帮到正在开发的伙伴们