add video clarity, fix the black border bug of the video

master
lgf 3 years ago
parent 4d81bc138e
commit 6a8566374d
  1. 35
      example/src/app.tsx
  2. 2
      package.json
  3. 15
      src/core/config/index.ts
  4. 16
      src/core/context/index.ts
  5. 10
      src/core/controller/index.tsx
  6. 11
      src/core/controls/index.scss
  7. 36
      src/core/controls/index.tsx
  8. 1
      src/core/controls/monitor.tsx
  9. 3
      src/core/controls/multiple.tsx
  10. 102
      src/core/controls/quality.tsx
  11. 3
      src/core/index.scss
  12. 10
      src/core/index.tsx
  13. 28
      src/core/useVideo.ts
  14. 9
      src/core/useVideoCallback.ts
  15. 30
      src/index.d.ts
  16. 30
      src/interface/index.ts

@ -1,4 +1,4 @@
import { callBackType, JoLPlayerRef } from '@/interface'; import { callBackType, JoLPlayerRef, qualityKey } from '@/interface';
import React, { useRef, useEffect, useState } from 'react'; import React, { useRef, useEffect, useState } from 'react';
import ReactDOM from 'react-dom'; import ReactDOM from 'react-dom';
import JoLPlayer from '../../src/index'; import JoLPlayer from '../../src/index';
@ -22,7 +22,7 @@ const AppCompent = () => {
console.log(`onPlay`, val); console.log(`onPlay`, val);
}; };
const onTimeChange: callBackType = (val) => { const onTimeChange: callBackType = (val) => {
console.log(`onTimeChange`, val); // console.log(`onTimeChange`, val);
}; };
const onvolumechange: callBackType = (val) => { const onvolumechange: callBackType = (val) => {
console.log(`onvolumechange`, val); console.log(`onvolumechange`, val);
@ -30,9 +30,10 @@ const AppCompent = () => {
const onError = () => { const onError = () => {
console.log(`onError`); console.log(`onError`);
}; };
useEffect(() => { const onQualityChange: callBackType<qualityKey> = (val) => {
console.log(`videoRef.current`, videoRef.current); console.log(`onQualityChange`, val);
}, [videoRef.current]); };
useEffect(() => {}, [videoRef.current]);
const videoMethod = (status: string) => { const videoMethod = (status: string) => {
if (status === 'play') { if (status === 'play') {
@ -64,14 +65,33 @@ const AppCompent = () => {
onTimeChange={onTimeChange} onTimeChange={onTimeChange}
onvolumechange={onvolumechange} onvolumechange={onvolumechange}
onError={onError} onError={onError}
onQualityChange={onQualityChange}
option={{ option={{
videoSrc: 'https://qiniu.qyhever.com/162962488432086ba29652658echrome.mp4', videoSrc:
'https://gs-files.oss-cn-hongkong.aliyuncs.com/okr/prod/file/2021/08/31/540p.mp4',
width: 750, width: 750,
height: 420, height: 420,
theme, theme,
poster: 'https://cdn.gudsen.com/2021/06/28/f81356b08b4842d7a3719499f557c8e4.JPG', poster:
'https://gs-files.oss-cn-hongkong.aliyuncs.com/okr/prod/file/2021/08/31/1080pp.png',
language: 'en', language: 'en',
isShowMultiple, isShowMultiple,
pausePlacement: 'center',
isShowPauseButton: false,
quality: [
{
name: 'FHD',
url: 'https://gs-files.oss-cn-hongkong.aliyuncs.com/okr/prod/file/2021/08/31/720p.mp4',
},
{
name: 'HD',
url: 'https://gs-files.oss-cn-hongkong.aliyuncs.com/okr/prod/file/2021/08/31/540p.mp4',
},
{
name: 'SD',
url: 'https://gs-files.oss-accelerate.aliyuncs.com/okr/prod/file/2021/08/31/1630377480138360p.mp4',
},
],
}} }}
/> />
<JoLPlayer <JoLPlayer
@ -80,6 +100,7 @@ const AppCompent = () => {
width: 750, width: 750,
height: 420, height: 420,
poster: 'https://cdn.gudsen.com/2021/06/28/f81356b08b4842d7a3719499f557c8e4.JPG', poster: 'https://cdn.gudsen.com/2021/06/28/f81356b08b4842d7a3719499f557c8e4.JPG',
quality: [],
}} }}
/> />
<button onClick={() => videoMethod('play')}>play</button> <button onClick={() => videoMethod('play')}>play</button>

@ -1,6 +1,6 @@
{ {
"name": "jol-player", "name": "jol-player",
"version": "2.1.2", "version": "2.2.0",
"description": "简洁,美观,功能强大的react播放器,simple and beautiful, powerful react player", "description": "简洁,美观,功能强大的react播放器,simple and beautiful, powerful react player",
"main": "index.js", "main": "index.js",
"scripts": { "scripts": {

@ -1,3 +1,5 @@
import { qualityName, qualityKey } from '@/interface';
export const multipleList = [ export const multipleList = [
{ id: 0.5, name: '0.5x' }, { id: 0.5, name: '0.5x' },
{ id: 0.75, name: '0.75x' }, { id: 0.75, name: '0.75x' },
@ -12,3 +14,16 @@ export const defaultTheme: string = '#ffb821';
export const defaultVolume: number = 60; export const defaultVolume: number = 60;
export const defaultLanguage = 'zh'; export const defaultLanguage = 'zh';
export interface qualityListType {
key: qualityKey;
enName: qualityName;
name: string;
id: number;
}
export const qualityList: qualityListType[] = [
{ name: '标清', key: '360P', enName: 'SD', id: 1 },
{ name: '高清', key: '540P', enName: 'HD', id: 2 },
{ name: '超清', key: '720P', enName: 'FHD', id: 3 },
{ name: '蓝光', key: '1080P', enName: 'BD', id: 4 },
];

@ -1,5 +1,5 @@
import React, { useReducer } from 'react'; import React, { useReducer } from 'react';
import { videoOption } from '@/interface'; import { videoOption, qualityKey } from '@/interface';
export interface VideoStateType<K = boolean, T = number> { export interface VideoStateType<K = boolean, T = number> {
/** /**
* @description * @description
@ -13,6 +13,10 @@ export interface VideoStateType<K = boolean, T = number> {
* @description onProgressMouseUp事件的变化数据onProgressMouseUp事件触发的 * @description onProgressMouseUp事件的变化数据onProgressMouseUp事件触发的
*/ */
progressMouseUpChangeVal: T; progressMouseUpChangeVal: T;
/**
* @description
*/
quality: qualityKey | undefined;
} }
/** /**
* @description * @description
@ -32,6 +36,7 @@ export const initialState = {
isControl: false, isControl: false,
progressSliderChangeVal: 0, progressSliderChangeVal: 0,
progressMouseUpChangeVal: 0, progressMouseUpChangeVal: 0,
quality: undefined,
}; };
export const defaultValue = { export const defaultValue = {
@ -54,10 +59,15 @@ export interface progressMouseUpChangeValValActionType {
type: 'progressMouseUpChangeVal'; type: 'progressMouseUpChangeVal';
data: VideoStateType['progressMouseUpChangeVal']; data: VideoStateType['progressMouseUpChangeVal'];
} }
export interface qualityActionType {
type: 'quality';
data: VideoStateType['quality'];
}
export type mergeAction = export type mergeAction =
| isControlActionType | isControlActionType
| progressSliderChangeValActionType | progressSliderChangeValActionType
| progressMouseUpChangeValValActionType; | progressMouseUpChangeValValActionType
| qualityActionType;
export const useVideoFlow = () => { export const useVideoFlow = () => {
const reducer = (state: VideoStateType, action: mergeAction) => { const reducer = (state: VideoStateType, action: mergeAction) => {
@ -68,6 +78,8 @@ export const useVideoFlow = () => {
return { ...state, progressSliderChangeVal: action.data }; return { ...state, progressSliderChangeVal: action.data };
case 'progressMouseUpChangeVal': case 'progressMouseUpChangeVal':
return { ...state, progressMouseUpChangeVal: action.data }; return { ...state, progressMouseUpChangeVal: action.data };
case 'quality':
return { ...state, quality: action.data };
default: default:
return state; return state;
} }

@ -6,6 +6,7 @@ import { FlowContext } from '@/core/context';
import { useVideo } from '@/core/useVideo'; import { useVideo } from '@/core/useVideo';
import EndComponent from '@/components/end'; import EndComponent from '@/components/end';
import Screenshot from '@/components/screenshot'; import Screenshot from '@/components/screenshot';
import { filterDefaults } from '@/utils';
import './index.scss'; import './index.scss';
const Index = memo(function Index() { const Index = memo(function Index() {
@ -126,15 +127,18 @@ const Index = memo(function Index() {
onMouseMove={mouseMove} onMouseMove={mouseMove}
onClick={handlePlay} onClick={handlePlay}
></div> ></div>
{!isPlay && !isEndEd && ( {filterDefaults(propsAttributes!.isShowPauseButton)
? !isPlay &&
!isEndEd && (
<Broadcast <Broadcast
iconClass="player" iconClass="player"
fill="#fff" fill="#fff"
fontSize={'47px'} fontSize={'55px'}
className="iconfont play-icon" className="iconfont play-icon"
style={pausePosition} style={pausePosition}
/> />
)} )
: null}
<div <div
className="JoL-progress-and-controls-wrap" className="JoL-progress-and-controls-wrap"
onMouseMove={(e) => [controlsContainerMove('move')]} onMouseMove={(e) => [controlsContainerMove('move')]}

@ -28,6 +28,9 @@
.play-pause-timeline { .play-pause-timeline {
display: flex; display: flex;
align-items: center; align-items: center;
.icon {
cursor: pointer;
}
.time-wrap { .time-wrap {
font-size: 13px; font-size: 13px;
vertical-align: middle; vertical-align: middle;
@ -62,8 +65,14 @@
border-radius: 3px; border-radius: 3px;
background-color: rgba(0, 0, 0, 0.7); background-color: rgba(0, 0, 0, 0.7);
li { li {
padding: 12px 15px; padding: 10px 22px;
cursor: pointer; cursor: pointer;
font-size: 14px;
white-space: nowrap;
display: flex;
p {
padding: 0 3px;
}
&:hover { &:hover {
background: rgba(255, 255, 255, 0.2); background: rgba(255, 255, 255, 0.2);
} }

@ -7,11 +7,12 @@ import { secondsToMinutesAndSecondes, capture, filterDefaults } from '@/utils';
import { useControls } from './variable'; import { useControls } from './variable';
import useWindowClient from '@/utils/useWindowClient'; import useWindowClient from '@/utils/useWindowClient';
import screenfull, { Screenfull } from 'screenfull'; import screenfull, { Screenfull } from 'screenfull';
import { multipleList, defaultVolume, defaultLanguage } from '@/core/config'; import { multipleList, defaultLanguage } from '@/core/config';
import SetComponent from './set'; import SetComponent from './set';
import MultipleComponent from './multiple'; import MultipleComponent from './multiple';
import VolumeComponent from './volume'; import VolumeComponent from './volume';
import MonitorComponent from './monitor'; import MonitorComponent from './monitor';
import QualityComponent, { qualityToggleType } from './quality';
import { il8n } from '@/language'; import { il8n } from '@/language';
import './index.scss'; import './index.scss';
@ -28,12 +29,19 @@ const Index: FC<{ setIsscreenshot: Function; setScreenshotLoading: Function }> =
const reviceProps = useContext(FlowContext); const reviceProps = useContext(FlowContext);
const { propsAttributes } = reviceProps!; const { propsAttributes, dispatch: contentDispatch } = reviceProps!;
const revicePropsData = useRef<contextType>(null!); const revicePropsData = useRef<contextType>(null!);
const { isPlay, handleChangePlayState, currentTime, duration, isPictureinpicture, volume } = const {
useVideo( isPlay,
handleChangePlayState,
currentTime,
duration,
isPictureinpicture,
volume,
videoMethod,
} = useVideo(
{ {
videoElement: reviceProps.videoRef, videoElement: reviceProps.videoRef,
}, },
@ -229,6 +237,15 @@ const Index: FC<{ setIsscreenshot: Function; setScreenshotLoading: Function }> =
return controlsState.isScreentFull || controlsState.isWebPageFullScreen ? '13px' : '8px'; return controlsState.isScreentFull || controlsState.isWebPageFullScreen ? '13px' : '8px';
}, [controlsState.isWebPageFullScreen, controlsState.isScreentFull]); }, [controlsState.isWebPageFullScreen, controlsState.isScreentFull]);
/**
* @description
*/
const qualityToggle: qualityToggleType = (url, key) => {
contentDispatch!({ type: 'quality', data: key });
videoMethod.setVideoSrc(url);
videoMethod.seek(currentTime);
videoMethod.play();
};
return ( return (
<div <div
className="JoL-controls-container" className="JoL-controls-container"
@ -241,6 +258,16 @@ const Index: FC<{ setIsscreenshot: Function; setScreenshotLoading: Function }> =
totalTime={secondsToMinutesAndSecondes(duration)} totalTime={secondsToMinutesAndSecondes(duration)}
/> />
<div className="JoL-multifunction"> <div className="JoL-multifunction">
{propsAttributes!.quality && propsAttributes!.quality.length ? (
<QualityComponent
videoSrc={
revicePropsData.current && revicePropsData.current.videoRef
? revicePropsData.current.videoRef!.src
: undefined
}
qualityToggle={qualityToggle}
/>
) : null}
{filterDefaults(propsAttributes!.isShowMultiple) && ( {filterDefaults(propsAttributes!.isShowMultiple) && (
<MultipleComponent <MultipleComponent
multipleText={multipleText} multipleText={multipleText}
@ -258,7 +285,6 @@ const Index: FC<{ setIsscreenshot: Function; setScreenshotLoading: Function }> =
slideCurrentVolume={slideCurrentVolume} slideCurrentVolume={slideCurrentVolume}
clearVolumeInterval={clearVolumeInterval} clearVolumeInterval={clearVolumeInterval}
isMuted={controlsState.isMuted} isMuted={controlsState.isMuted}
// toggleVolume={toggleVolume}
toggleVolume={() => dispatch({ type: 'isMuted', data: !controlsState.isMuted })} toggleVolume={() => dispatch({ type: 'isMuted', data: !controlsState.isMuted })}
/> />
{filterDefaults(propsAttributes!.isShowSet) && ( {filterDefaults(propsAttributes!.isShowSet) && (

@ -22,6 +22,7 @@ const Monitor: FC<MonitorType> = memo(function Monitor({
fill="#fff" fill="#fff"
fontSize="20px" fontSize="20px"
onClick={handleChangePlayState} onClick={handleChangePlayState}
className="icon"
/> />
<span className="time-wrap"> <span className="time-wrap">
<span className="current-time">{currentTime}</span> <span className="current-time">{currentTime}</span>

@ -1,6 +1,5 @@
import React, { memo, FC, useState, useContext } from 'react'; import React, { memo, FC, useState, useContext } from 'react';
import { multipleList } from '@/core/config'; import { multipleList, defaultTheme } from '@/core/config';
import { defaultTheme } from '@/core/config';
import { FlowContext } from '@/core/context'; import { FlowContext } from '@/core/context';
import './index.scss'; import './index.scss';
export interface MultipleType { export interface MultipleType {

@ -0,0 +1,102 @@
import React, { memo, FC, useState, useContext, useMemo } from 'react';
import { defaultTheme, qualityList, qualityListType } from '@/core/config';
import { FlowContext } from '@/core/context';
import { qualityKey } from '@/interface';
import './index.scss';
export type qualityToggleType = (par: string, key: qualityKey) => void;
export interface QualityType {
style?: React.CSSProperties;
videoSrc?: string;
qualityToggle: qualityToggleType;
}
export type qualityMerge = qualityListType & { url: string };
const Quality: FC<QualityType> = memo(function Quality({ style, videoSrc, qualityToggle }) {
const reviceProps = useContext(FlowContext);
const { theme, quality, language } = reviceProps.propsAttributes!;
const [isShow, setIsShow] = useState<boolean>(false);
const qualitySelectList = useMemo(() => {
if (quality) {
return quality
.map(
(item) =>
qualityList
.map((items) => {
return item.name === items.enName && Object.assign({}, items, { url: item.url });
})
.filter((item) => item)[0],
)
.sort((a, b) => (b && b.id ? b.id : 1) - (a && a.id ? a.id : 1));
}
return [];
}, [quality]);
const qualityText = useMemo<Partial<qualityMerge>>(() => {
let text: qualityMerge[] = [];
if (videoSrc && qualitySelectList) {
text = (qualitySelectList as qualityMerge[]).filter((item) => item.url === videoSrc);
}
return text.length ? text[0] : { key: '360P', enName: 'SD', name: '标清', id: 1 };
}, [videoSrc, qualitySelectList]);
const toggle = (url: string, key: qualityKey) => {
qualityToggle(url, key);
};
return (
<div
className="JoL-multifunction-multiple"
onClick={(e) => setIsShow((pre) => !pre)}
onMouseLeave={(e) => [setIsShow(false)]}
style={style}
>
<p>
{qualityText
? language && language === 'en'
? qualityText.enName
: qualityText.name
: null}
</p>
<div
className="JoL-multifunction-multiple-container"
style={{ display: isShow ? 'block' : 'none' }}
>
{qualitySelectList && qualitySelectList.length ? (
<ul className="JoL-multifunction-multiple-layer">
{qualitySelectList.map((item, index) => (
<li
key={index}
onClick={() =>
toggle(item && item.url ? item.url : '', item && item.key ? item.key : '360P')
}
style={{
color:
qualityText.key === (item && item.key ? item.key : null)
? theme
? theme
: defaultTheme
: '#fff',
}}
>
<p>
{item && item.name
? language && language === 'en'
? item.enName
: item.name
: null}
</p>
<p>{item && item.key ? item.key : null}</p>
</li>
))}
</ul>
) : null}
</div>
</div>
);
});
export default Quality;

@ -8,9 +8,12 @@
box-sizing: border-box; box-sizing: border-box;
position: relative; position: relative;
z-index: 100; z-index: 100;
// background-color: #000;
.JoL-player { .JoL-player {
@include wh(100%, 100%); @include wh(100%, 100%);
background-color: #000; background-color: #000;
// 去除视频黑边
object-fit: cover;
@include position(absolute, 0, auto, auto, 0); @include position(absolute, 0, auto, auto, 0);
z-index: 1; z-index: 1;
} }

@ -30,6 +30,7 @@ const JoLPlayer = function JoLPlayer(props: videoparameter, ref: React.Ref<unkno
onProgressMouseUp, onProgressMouseUp,
onError, onError,
onvolumechange, onvolumechange,
onQualityChange,
} = props; } = props;
const { videoSrc, width, height, theme, poster, setBufferContent } = option; const { videoSrc, width, height, theme, poster, setBufferContent } = option;
/** /**
@ -85,6 +86,7 @@ const JoLPlayer = function JoLPlayer(props: videoparameter, ref: React.Ref<unkno
onEndEd, onEndEd,
onError, onError,
onvolumechange, onvolumechange,
onQualityChange,
}); });
useEffect(() => { useEffect(() => {
@ -152,7 +154,13 @@ const JoLPlayer = function JoLPlayer(props: videoparameter, ref: React.Ref<unkno
return ( return (
<figure className={`JoL-player-container ${className}`} ref={videoContainerRef} style={style}> <figure className={`JoL-player-container ${className}`} ref={videoContainerRef} style={style}>
<div className="JoL-light-off-mask" ref={lightOffMaskRef}></div> <div className="JoL-light-off-mask" ref={lightOffMaskRef}></div>
<video className="JoL-player" ref={videoRef} poster={poster ? poster : undefined}> <video
className="JoL-player"
ref={videoRef}
src={videoSrc}
poster={poster ? poster : undefined}
id="JoL-player"
>
{returnVideoSource} {returnVideoSource}
</video> </video>
{!isVideoUseful && <p className="video-no-useful-tip"> ( ́︿ ̀)</p>} {!isVideoUseful && <p className="video-no-useful-tip"> ( ́︿ ̀)</p>}

@ -1,7 +1,7 @@
import { useRef, useMemo, useEffect, DependencyList } from "react"; import { useRef, useMemo, useEffect, DependencyList } from 'react';
import useMandatoryUpdate from "@/utils/useMandatoryUpdate"; import useMandatoryUpdate from '@/utils/useMandatoryUpdate';
import { videoAttributes, videoMethod, parVoid } from "@/interface"; import { videoAttributes, videoMethod, parVoid } from '@/interface';
import { defaultVolume } from "@/core/config"; import { defaultVolume } from '@/core/config';
export interface useVideoType extends videoAttributes { export interface useVideoType extends videoAttributes {
handleChangePlayState: () => void; handleChangePlayState: () => void;
videoAttributes: videoAttributes; videoAttributes: videoAttributes;
@ -37,13 +37,13 @@ export const useVideo = (props: any, dep: DependencyList = []) => {
/** /**
* @description * @description
*/ */
videoRef.current.addEventListener("canplay", () => { videoRef.current.addEventListener('canplay', () => {
torture({ duration: videoRef.current.duration }); torture({ duration: videoRef.current.duration });
}); });
/** /**
* @description * @description
*/ */
videoRef.current.addEventListener("progress", () => { videoRef.current.addEventListener('progress', () => {
if (videoRef.current.buffered.length >= 1) { if (videoRef.current.buffered.length >= 1) {
torture({ bufferedTime: videoRef.current.buffered.end(0) }); torture({ bufferedTime: videoRef.current.buffered.end(0) });
} }
@ -51,13 +51,13 @@ export const useVideo = (props: any, dep: DependencyList = []) => {
/** /**
* @description * @description
*/ */
videoRef.current.addEventListener("enterpictureinpicture", () => { videoRef.current.addEventListener('enterpictureinpicture', () => {
torture({ isPictureinpicture: true }); torture({ isPictureinpicture: true });
}); });
/** /**
* @description 退 * @description 退
*/ */
videoRef.current.addEventListener("leavepictureinpicture", () => { videoRef.current.addEventListener('leavepictureinpicture', () => {
torture({ isPictureinpicture: false }); torture({ isPictureinpicture: false });
}); });
// 定时器用于更新当前视频时间 // 定时器用于更新当前视频时间
@ -74,11 +74,11 @@ export const useVideo = (props: any, dep: DependencyList = []) => {
isEndEd: videoRef.current.ended ? true : false, isEndEd: videoRef.current.ended ? true : false,
}); });
}, 1); }, 1);
videoRef.current.addEventListener("pause", pauseChange); videoRef.current.addEventListener('pause', pauseChange);
videoRef.current.addEventListener("play", playChange); videoRef.current.addEventListener('play', playChange);
videoRef.current.addEventListener("timeupdate", timeupdate); videoRef.current.addEventListener('timeupdate', timeupdate);
videoRef.current.addEventListener("ended", endedChange); videoRef.current.addEventListener('ended', endedChange);
videoRef.current.addEventListener("error", errorChange); videoRef.current.addEventListener('error', errorChange);
} }
return () => { return () => {
interval.current && clearInterval(interval.current); interval.current && clearInterval(interval.current);
@ -135,6 +135,6 @@ export const useVideo = (props: any, dep: DependencyList = []) => {
videoAttributes: videoParameter.current, videoAttributes: videoParameter.current,
videoMethod, videoMethod,
}), }),
[videoParameter.current] [videoParameter.current],
); );
}; };

@ -8,7 +8,7 @@ const useVideoCallback = (
handle: Partial<videoCallback>, handle: Partial<videoCallback>,
) => { ) => {
const { isPlay, currentTime, isEndEd, error, volume } = videoPr; const { isPlay, currentTime, isEndEd, error, volume } = videoPr;
const { progressSliderChangeVal, progressMouseUpChangeVal } = videoFlow; const { progressSliderChangeVal, progressMouseUpChangeVal, quality } = videoFlow;
const { const {
onProgressMouseDown, onProgressMouseDown,
onPlay, onPlay,
@ -18,6 +18,7 @@ const useVideoCallback = (
onProgressMouseUp, onProgressMouseUp,
onError, onError,
onvolumechange, onvolumechange,
onQualityChange,
} = handle; } = handle;
useEffect(() => { useEffect(() => {
@ -63,6 +64,12 @@ const useVideoCallback = (
onvolumechange && onvolumechange(videoPr); onvolumechange && onvolumechange(videoPr);
} }
}, [volume]); }, [volume]);
useEffect(() => {
if (quality) {
onQualityChange && onQualityChange(quality);
}
}, [quality]);
}; };
export default useVideoCallback; export default useVideoCallback;

30
src/index.d.ts vendored

@ -9,6 +9,20 @@ export type pausePlacement = 'bottomRight' | 'center';
export type languageType = 'zh' | 'en'; export type languageType = 'zh' | 'en';
/**
* 360P SD
* 540P HD
* 720P FHD
* 1080P BD
*/
export type qualityName = 'SD' | 'HD' | 'FHD' | 'BD';
export type qualityKey = '360P' | '540P' | '720P' | '1080P';
export interface qualityAttributes<T = qualityName> {
name: T;
url: string;
}
export interface videoOption<T = string, K = boolean, U = number> { export interface videoOption<T = string, K = boolean, U = number> {
/** /**
* @description width * @description width
@ -70,6 +84,14 @@ export interface videoOption<T = string, K = boolean, U = number> {
* @description , * @description ,
*/ */
language?: languageType; language?: languageType;
/**
* @description
*/
isShowPauseButton?: K;
/**
* @description
*/
quality?: qualityAttributes[];
} }
export interface videoAttributes<T = number, K = boolean> { export interface videoAttributes<T = number, K = boolean> {
/** /**
@ -139,8 +161,8 @@ export interface videoMethod<T = noParVoid> {
*/ */
setVideoSrc: parVoid<string>; setVideoSrc: parVoid<string>;
} }
export type callBackType = (e: videoAttributes) => void; export type callBackType<T = videoAttributes> = (e: T) => void;
export interface videoCallback<T = callBackType> { export interface videoCallback<T = callBackType, U = callBackType<qualityKey>> {
/** /**
* @description * @description
*/ */
@ -173,6 +195,10 @@ export interface videoCallback<T = callBackType> {
* @description * @description
*/ */
onvolumechange: T; onvolumechange: T;
/**
* @description
*/
onQualityChange: U;
} }
export interface videoparameter extends Partial<videoCallback> { export interface videoparameter extends Partial<videoCallback> {
style?: React.CSSProperties; style?: React.CSSProperties;

@ -9,6 +9,20 @@ export interface hoverShowStyleType {
export type pausePlacement = 'bottomRight' | 'center'; export type pausePlacement = 'bottomRight' | 'center';
export type languageType = 'zh' | 'en'; export type languageType = 'zh' | 'en';
/**
* 360P SD
* 540P HD
* 720P FHD
* 1080P BD
*/
export type qualityName = 'SD' | 'HD' | 'FHD' | 'BD';
export type qualityKey = '360P' | '540P' | '720P' | '1080P';
export interface qualityAttributes<T = qualityName> {
name: T;
url: string;
}
export interface videoOption<T = string, K = boolean, U = number> { export interface videoOption<T = string, K = boolean, U = number> {
/** /**
* @description width * @description width
@ -70,6 +84,14 @@ export interface videoOption<T = string, K = boolean, U = number> {
* @description , * @description ,
*/ */
language?: languageType; language?: languageType;
/**
* @description
*/
isShowPauseButton?: K;
/**
* @description
*/
quality?: qualityAttributes[];
} }
export interface videoAttributes<T = number, K = boolean> { export interface videoAttributes<T = number, K = boolean> {
/** /**
@ -139,8 +161,8 @@ export interface videoMethod<T = noParVoid> {
*/ */
setVideoSrc: parVoid<string>; setVideoSrc: parVoid<string>;
} }
export type callBackType = (e: videoAttributes) => void; export type callBackType<T = videoAttributes> = (e: T) => void;
export interface videoCallback<T = callBackType> { export interface videoCallback<T = callBackType, U = callBackType<qualityKey>> {
/** /**
* @description * @description
*/ */
@ -173,6 +195,10 @@ export interface videoCallback<T = callBackType> {
* @description * @description
*/ */
onvolumechange: T; onvolumechange: T;
/**
* @description
*/
onQualityChange: U;
} }
export interface videoparameter extends Partial<videoCallback> { export interface videoparameter extends Partial<videoCallback> {
style?: React.CSSProperties; style?: React.CSSProperties;

Loading…
Cancel
Save