带你读《2022技术人的百宝黑皮书》——短视频无尽流前端开发指南(1) https://developer.aliyun.com/article/1243503?groupCode=taobaotech
视频播放器状态按钮
常规来讲播放器需要展示出两种状态:暂停中、缓冲中,播放中有进度条在推进一般不需要做额外展示。状态按钮组件实现如下:
tips:将按钮状态内置在组件中,暴露修改状态的方法给父元素,可以避免在改变按钮状态时触发父元素的re-render。
// ... const StatusButton = forwardRef<IStatusButtonRef>((_, ref) => { const [status, setStatus] = useState<EStatus>(EStatus.PLAY); useImperativeHandle(ref, () => ({ setStatus, })); return ( <div className={styles.statusButton}> {(() => { switch (status) { case EStatus.PAUSE: return <div>{/* 暂停Icon */}</div>; case EStatus.WAITING: return <div>{/* 缓冲Icon */}</div>; default: return null; } })()} </div> ); }); export default memo(StatusButton);
// ... const VideoPlayer: FC<IVideoPlayer> = (props) => { const { source } = props; const videoPlayerRef = useRef<HTMLVideoElement | null>(null); const statusButtonRef = useRef<IStatusButtonRef | null>(null); const onPlay = () => { statusButtonRef.current?.setStatus(EPlayerStatus.PLAY); }; useEffect(() => { videoPlayerRef.current?.addEventListener('play', onPlay); // 暂停(pause)和缓冲(waiting)监听方法类似 // ... return () => { videoPlayerRef.current?.removeEventListener('play', onPlay); }; }, []); return ( <div className={styles.videoPlayerContainer}> {/* 播放器 */} <video ref={videoPlayerRef} className={styles.item} src={source} playsInline autoPlay /> {/* 播放器状态按钮 */} <StatusButton ref={statusButtonRef} /> </div> ); }; export default memo(VideoPlayer);
视频播放器进度条
带你读《2022技术人的百宝黑皮书》——短视频无尽流前端开发指南(3) https://developer.aliyun.com/article/1243499?groupCode=taobaotech