add declaration

master
lgf 3 years ago
parent 38f9458ff3
commit eb5b02f4c2
  1. 26
      src/appComponent.tsx
  2. 2
      src/core/config/index.ts
  3. 41
      src/core/context/index.ts
  4. 11
      src/core/controls/multiple.tsx
  5. 15
      src/core/controls/volume.tsx
  6. 4
      src/core/index.scss
  7. 77
      src/core/index.tsx
  8. 12
      src/core/progress/index.tsx
  9. 22
      src/core/useVideo.ts
  10. 51
      src/core/useVideoCallback.ts
  11. 75
      src/interface/index.ts

@ -6,8 +6,11 @@ import '@/icons/';
const AppComponent = memo(function AppComponent(props) {
const videoRef = useRef<HTMLVideoElement>(null!);
const onProgressSlide = (val: any) => {
console.log(`val`, val);
const onProgressMouseDown = (val: any) => {
// console.log(`val`, val);
};
const onProgressMouseUp = (val: any) => {
console.log(`onProgressMouseUp`, val);
};
const onPlay = (val: any) => {
console.log(`播放`, val);
@ -16,20 +19,35 @@ const AppComponent = memo(function AppComponent(props) {
console.log(`暂停`, val);
};
const onTimeChange = (val: any) => {
console.log(`onTimeChange`, val);
// console.log(`onTimeChange`, val);
};
const onEndEd = (val: any) => {
console.log(`onEndEd`, val);
};
const onError = () => {
console.log(`onError`);
};
const onvolumechange = (val: any) => {
console.log(`onvolumechange`, val);
};
return (
<>
<JoLPlayer
ref={videoRef}
onProgressSlide={onProgressSlide}
option={{
videoSrc:
'https://gs-files.oss-cn-hongkong.aliyuncs.com/okr/test/file/2021/07/01/haiwang.mp4',
width: 750,
height: 420,
}}
onProgressMouseDown={onProgressMouseDown}
onPlay={onPlay}
onPause={onPause}
onTimeChange={onTimeChange}
onEndEd={onEndEd}
onProgressMouseUp={onProgressMouseUp}
onError={onError}
onvolumechange={onvolumechange}
/>
{/* <JoLPlayer /> */}
</>

@ -6,3 +6,5 @@ export const multipleList = [
{ id: 1.5, name: '1.5x' },
{ id: 2, name: '2.0x' },
];
export const defaultTheme: string = 'blue';

@ -1,22 +1,18 @@
import React, { useReducer } from 'react';
import { videoOption } from '@/interface';
export interface VideoStateType<K = boolean, T = number> {
/**
* @description
*/
isControl: K;
/**
* @description
*/
currentTime: T;
/**
* @description
* @description onProgressMouseDown事件的变化数据onProgressMouseDown事件触发的
*/
isPlay: K;
progressSliderChangeVal: T;
/**
* @description onProgressSlider事件的变化数据onProgressSlider事件触发的
* @description onProgressMouseUp事件的变化数据onProgressMouseUp事件触发的
*/
progressSliderChangeVal: T;
progressMouseUpChangeVal: T;
}
/**
* @description
@ -27,15 +23,15 @@ export interface contextType {
lightOffMaskRef: HTMLElement | null;
dispatch?: React.Dispatch<mergeAction>;
videoFlow: VideoStateType;
propsAttributes?: videoOption;
}
/**
* @description
*/
export const initialState = {
isControl: false,
currentTime: 0,
isPlay: false,
progressSliderChangeVal: 0,
progressMouseUpChangeVal: 0,
};
export const defaultValue = {
@ -50,35 +46,28 @@ export interface isControlActionType {
type: 'isControl';
data: VideoStateType['isControl'];
}
export interface currentTimeActionType {
type: 'currentTime';
data: VideoStateType['currentTime'];
}
export interface isPlayActionType {
type: 'isPlay';
data: VideoStateType['isPlay'];
}
export interface progressSliderChangeValActionType {
type: 'progressSliderChangeVal';
data: VideoStateType['progressSliderChangeVal'];
}
export interface progressMouseUpChangeValValActionType {
type: 'progressMouseUpChangeVal';
data: VideoStateType['progressMouseUpChangeVal'];
}
export type mergeAction =
| isControlActionType
| currentTimeActionType
| isPlayActionType
| progressSliderChangeValActionType;
| progressSliderChangeValActionType
| progressMouseUpChangeValValActionType;
export const useVideoFlow = () => {
const reducer = (state: VideoStateType, action: mergeAction) => {
switch (action.type) {
case 'isControl':
return { ...state, isControl: action.data };
case 'currentTime':
return { ...state, currentTime: action.data };
case 'isPlay':
return { ...state, isPlay: action.data };
case 'progressSliderChangeVal':
return { ...state, progressSliderChangeVal: action.data };
case 'progressMouseUpChangeVal':
return { ...state, progressMouseUpChangeVal: action.data };
default:
return state;
}

@ -1,7 +1,8 @@
import React, { memo, FC, useState } from 'react';
import React, { memo, FC, useState, useContext } from 'react';
import { multipleList } from '@/core/config';
import { defaultTheme } from '@/core/config';
import { FlowContext } from '@/core/context';
import './index.scss';
export interface MultipleType {
multipleText: string;
selectPlayRate: Function;
@ -13,6 +14,10 @@ const Multiple: FC<MultipleType> = memo(function Multiple({
selectPlayRate,
multiple,
}) {
const reviceProps = useContext(FlowContext);
const { theme } = reviceProps.propsAttributes!;
const [isShow, setIsShow] = useState<boolean>(false);
return (
@ -31,7 +36,7 @@ const Multiple: FC<MultipleType> = memo(function Multiple({
<li
onClick={() => [selectPlayRate(item.id), setIsShow(false)]}
key={index}
style={{ color: multiple === item.id ? 'red' : '#fff' }}
style={{ color: multiple === item.id ? (theme ? theme : defaultTheme) : '#fff' }}
>
{item.name}
</li>

@ -1,5 +1,7 @@
import React, { useImperativeHandle, useRef, forwardRef, useState } from 'react';
import React, { useImperativeHandle, useRef, forwardRef, useState, useContext } from 'react';
import Broadcast from '@/components/svgIcon';
import { defaultTheme } from '@/core/config';
import { FlowContext } from '@/core/context';
import './index.scss';
export interface VolumeType {
@ -15,6 +17,10 @@ const Volume = function Volume(
) {
const volumeSliderMirror = useRef<HTMLDivElement>(null);
const reviceProps = useContext(FlowContext);
const { theme } = reviceProps.propsAttributes!;
const [isShow, setIsShow] = useState<boolean>(false);
useImperativeHandle(ref, () => ({
@ -49,10 +55,13 @@ const Volume = function Volume(
className="volume-slider-op"
style={{
height: `${volume}%`,
backgroundColor: `red`,
backgroundColor: `${theme ? theme : defaultTheme}`,
}}
>
<div className="volume-slider-op-circle" style={{ backgroundColor: `red` }}></div>
<div
className="volume-slider-op-circle"
style={{ backgroundColor: `${theme ? theme : defaultTheme}` }}
></div>
</div>
</div>
</div>

@ -3,8 +3,8 @@
-khtml-user-select: none;
-webkit-user-select: none;
user-select: none;
width: 740px;
height: 420px;
// width: 740px;
// height: 420px;
margin: 0;
box-sizing: border-box;
position: relative;

@ -13,28 +13,24 @@ import useMandatoryUpdate from '@/utils/useMandatoryUpdate';
import Broadcast from '@/components/svgIcon';
import { useVideo } from '@/core/useVideo';
import useVideoCallback from '@/core/useVideoCallback';
import { defaultTheme } from '@/core/config';
// import videoUrl from '@/assets/haiwang.mp4';
import '@/assets/css/reset.scss';
import './index.scss';
const JoLPlayer = function JoLPlayer(
{
videoSrc = 'https://gs-files.oss-cn-hongkong.aliyuncs.com/okr/test/file/2021/07/01/haiwang.mp4',
onProgressSlide,
const JoLPlayer = function JoLPlayer(props: videoparameter, ref: React.Ref<unknown> | undefined) {
const {
option,
onProgressMouseDown,
onPlay,
onPause,
onTimeChange,
onEndEd,
}: {
videoSrc?: string;
onPause?: Function;
onPlay?: Function;
onTimeChange?: Function;
onEndEd?: Function;
onProgressSlide?: Function;
},
ref: React.Ref<unknown> | undefined,
) {
onProgressMouseUp,
onError,
onvolumechange,
} = props;
const { videoSrc, width, height, theme } = option;
/**
* @description
*/
@ -76,20 +72,22 @@ const JoLPlayer = function JoLPlayer(
video: videoRef.current,
}));
const { isPlay, handleChangePlayState, currentTime, duration, isPictureinpicture, isEndEd } =
useVideo(
const { videoAttributes } = useVideo(
{
videoElement: videoRef.current,
},
[videoRef.current],
);
const callBack = useVideoCallback({ isPlay, currentTime, isEndEd }, videoFlow, {
onProgressSlide,
useVideoCallback(videoAttributes, videoFlow, {
onProgressMouseDown,
onProgressMouseUp,
onPlay,
onPause,
onTimeChange,
onEndEd,
onError,
onvolumechange,
});
useEffect(() => {
@ -101,6 +99,8 @@ const JoLPlayer = function JoLPlayer(
* @description
*/
const videoContainerElem = videoContainerRef.current;
videoContainerElem.style.width = `${width}px`;
videoContainerElem.style.height = `${height}px`;
const videoElem = videoRef.current;
// 设置定时器检测 3 秒后视频是否可用
timerToCheckVideoUseful.current = setTimeout(() => {
@ -120,7 +120,7 @@ const JoLPlayer = function JoLPlayer(
videoElem.removeEventListener('waiting', waitingListener);
videoElem.removeEventListener('playing', playingListener);
};
}, [videoRef.current]);
}, [videoRef.current, option]);
const returnVideoSource = useMemo(() => {
return (
@ -132,32 +132,6 @@ const JoLPlayer = function JoLPlayer(
);
}, [videoSrc]);
// useEffect(() => {
// if (videoFlow.progressSliderChangeVal) {
// onProgressSlide && onProgressSlide(videoFlow.progressSliderChangeVal);
// }
// }, [videoFlow.progressSliderChangeVal]);
// useEffect(() => {
// if (isPlay) {
// onPlay && onPlay(isPlay);
// } else {
// onPause && onPause(isPlay);
// }
// }, [isPlay]);
// useEffect(() => {
// if (currentTime) {
// onTimeChange && onTimeChange(currentTime);
// }
// }, [currentTime]);
// useEffect(() => {
// if (isEndEd) {
// onEndEd && onEndEd(isEndEd);
// }
// }, [isEndEd]);
const contextProps = useMemo(() => {
return Object.assign(
{},
@ -167,9 +141,10 @@ const JoLPlayer = function JoLPlayer(
lightOffMaskRef: lightOffMaskRef.current,
dispatch,
videoFlow,
propsAttributes: option,
},
);
}, [videoRef.current, videoFlow]);
}, [videoRef.current, videoFlow, option]);
return (
<figure className="JoL-player-container" ref={videoContainerRef}>
@ -179,7 +154,12 @@ const JoLPlayer = function JoLPlayer(
</video>
{!isVideoUseful && <p className="video-no-useful-tip"> ( ́︿ ̀)</p>}
{isBufferring && (
<Broadcast iconClass="loading" fill="#ff0000" className="player-loading" fontSize="55px" />
<Broadcast
iconClass="loading"
fill={theme ? theme : defaultTheme}
className="player-loading"
fontSize="55px"
/>
)}
<FlowContext.Provider value={contextProps}>
<Controller />
@ -188,5 +168,6 @@ const JoLPlayer = function JoLPlayer(
);
};
const JoLPlayerComponent = forwardRef<HTMLVideoElement, any>(JoLPlayer);
const JoLPlayerComponent = forwardRef<HTMLVideoElement, videoparameter>(JoLPlayer);
export default JoLPlayerComponent;

@ -5,6 +5,7 @@ import { percentToMinutesAndSeconds, percentToSeconds } from '@/utils';
import useWindowClient from '@/utils/useWindowClient';
import { useProgress } from './variable';
import { hoverShowStyleType } from '@/interface';
import { defaultTheme } from '@/core/config';
import './index.scss';
const Index = memo(function Index(props) {
@ -29,6 +30,8 @@ const Index = memo(function Index(props) {
const reviceProps = useContext(FlowContext);
const { theme } = reviceProps.propsAttributes!;
const { currentTime, duration, bufferedTime } = useVideo({ videoElement: reviceProps.videoRef }, [
reviceProps.videoRef,
]);
@ -138,6 +141,7 @@ const Index = memo(function Index(props) {
*/
const clearIntervalFunc = () => {
whenMouseUpDo();
reviceProps.dispatch!({ type: 'progressMouseUpChangeVal', data: Date.now() });
};
/**
* @description
@ -176,12 +180,12 @@ const Index = memo(function Index(props) {
className="progress-played"
style={{
width: `${calculateProcessPercent}%`,
background: `red`,
background: `${theme ? theme : defaultTheme}`,
}}
>
<i
className="progress-scrubber"
style={{ background: `red` }}
style={{ background: `${theme ? theme : defaultTheme}` }}
ref={progressScrubberRef}
></i>
</div>
@ -200,13 +204,13 @@ const Index = memo(function Index(props) {
<div
className="top-triangle"
style={{
borderTop: `4px solid red`,
borderTop: `4px solid ${theme ? theme : defaultTheme}`,
}}
></div>
<div
className="bottom-triangle"
style={{
borderBottom: `4px solid red`,
borderBottom: `4px solid ${theme ? theme : defaultTheme}`,
}}
></div>
</div>

@ -1,12 +1,18 @@
import { useRef, useMemo, useEffect, DependencyList } from 'react';
import useMandatoryUpdate from '@/utils/useMandatoryUpdate';
import { videoAttributes } from '@/interface';
export interface useVideoType extends videoAttributes {
handleChangePlayState: () => void;
videoAttributes: videoAttributes;
}
export const useVideo = (props: any, dep: DependencyList = []) => {
const { videoElement } = props;
const forceUpdate = useMandatoryUpdate();
const videoParameter = useRef<any>({
const videoParameter = useRef<videoAttributes>({
isPlay: false,
currentTime: 0,
duration: 0,
@ -15,6 +21,7 @@ export const useVideo = (props: any, dep: DependencyList = []) => {
volume: 0,
multiple: 1.0,
isEndEd: false,
error: null,
});
const videoRef = useRef<HTMLVideoElement>(null!);
@ -24,10 +31,6 @@ export const useVideo = (props: any, dep: DependencyList = []) => {
videoRef.current = videoElement;
useEffect(() => {
/**
* @description
*/
// forceUpdate();
if (videoRef.current) {
/**
* @description
@ -73,13 +76,14 @@ export const useVideo = (props: any, dep: DependencyList = []) => {
videoRef.current.addEventListener('play', playChange);
videoRef.current.addEventListener('timeupdate', timeupdate);
videoRef.current.addEventListener('ended', endedChange);
videoRef.current.addEventListener('error', errorChange);
}
return () => {
interval.current && clearInterval(interval.current);
};
}, dep);
const torture = (val: any) => {
const torture = <T extends Partial<videoAttributes>>(val: T) => {
videoParameter.current = { ...videoParameter.current, ...val };
};
const pauseChange = () => {
@ -94,6 +98,9 @@ export const useVideo = (props: any, dep: DependencyList = []) => {
const endedChange = () => {
torture({ isEndEd: videoRef.current.ended ? true : false });
};
const errorChange = () => {
torture({ error: Date.now() });
};
const handleChangePlayState = () => {
if (videoParameter.current.isPlay) {
videoRef.current.pause();
@ -102,10 +109,11 @@ export const useVideo = (props: any, dep: DependencyList = []) => {
}
};
return useMemo(
return useMemo<useVideoType>(
() => ({
handleChangePlayState,
...videoParameter.current,
videoAttributes: videoParameter.current,
}),
[videoParameter.current],
);

@ -1,35 +1,68 @@
import { useEffect } from 'react';
import { videoAttributes, videoCallback } from '@/interface';
import { VideoStateType } from './context';
const useVideoCallback = (videoPr: any, videoFlow: any, handle: any) => {
const { isPlay, currentTime, isEndEd } = videoPr;
const { progressSliderChangeVal } = videoFlow;
const { onProgressSlide, onPlay, onPause, onTimeChange, onEndEd } = handle;
const useVideoCallback = (
videoPr: videoAttributes,
videoFlow: VideoStateType,
handle: Partial<videoCallback>,
) => {
const { isPlay, currentTime, isEndEd, error, volume } = videoPr;
const { progressSliderChangeVal, progressMouseUpChangeVal } = videoFlow;
const {
onProgressMouseDown,
onPlay,
onPause,
onTimeChange,
onEndEd,
onProgressMouseUp,
onError,
onvolumechange,
} = handle;
useEffect(() => {
if (videoFlow.progressSliderChangeVal) {
onProgressSlide && onProgressSlide(progressSliderChangeVal);
onProgressMouseDown && onProgressMouseDown(videoPr);
}
}, [progressSliderChangeVal]);
useEffect(() => {
if (videoFlow.progressMouseUpChangeVal) {
onProgressMouseUp && onProgressMouseUp(videoPr);
}
}, [progressMouseUpChangeVal]);
useEffect(() => {
if (isPlay) {
onPlay && onPlay(isPlay);
onPlay && onPlay(videoPr);
} else {
onPause && onPause(isPlay);
onPause && onPause(videoPr);
}
}, [isPlay]);
useEffect(() => {
if (currentTime) {
onTimeChange && onTimeChange(currentTime);
onTimeChange && onTimeChange(videoPr);
}
}, [currentTime]);
useEffect(() => {
if (isEndEd) {
onEndEd && onEndEd(isEndEd);
onEndEd && onEndEd(videoPr);
}
}, [isEndEd]);
useEffect(() => {
if (error) {
onError && onError();
}
}, [error]);
useEffect(() => {
if (volume) {
onvolumechange && onvolumechange(videoPr);
}
}, [volume]);
};
export default useVideoCallback;

@ -24,7 +24,80 @@ export interface videoOption {
*/
videoSrc: string;
}
export interface videoparameter {
export interface videoAttributes<T = number, K = boolean> {
/**
* @description
*/
isPlay: K;
/**
* @description /s
*/
currentTime: T;
/**
* @description
*/
duration: T;
/**
* @description /s
*/
bufferedTime: T;
/**
* @description
*/
isPictureinpicture: K;
/**
* @description
*/
volume: T;
/**
* @description
*/
multiple: T;
/**
* @description
*/
isEndEd: K;
/**
* @description
*/
error: null | T;
}
export type callBackType = (e: videoAttributes) => void;
export interface videoCallback<T = callBackType> {
/**
* @description
*/
onProgressMouseDown: T;
/**
* @description
*/
onPlay: T;
/**
* @description
*/
onPause: T;
/**
* @description
*/
onTimeChange: T;
/**
* @description
*/
onEndEd: T;
/**
* @description
*/
onProgressMouseUp: T;
/**
* @description
*/
onError: () => void;
/**
* @description
*/
onvolumechange: T;
}
export interface videoparameter extends Partial<videoCallback> {
style?: React.CSSProperties;
/**
* @description

Loading…
Cancel
Save