前端播放器使用(含画中画效果)

本文介绍了如何使用React构建一个可定制的视频播放器组件,包含视频源处理、控制选项、事件处理和视频状态管理,如自动播放、静音和显示/隐藏海报。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

使用:
<VideoPlayer src={domainUrl + preViewItem.videoUrl} autoplay={true} controls={true} />



源代码:
import React, {memo, useEffect, useState, forwardRef, useImperativeHandle} from 'react';
import videojs from 'video.js';
import 'video.js/dist/video-js.css';

const VideoPlayer = (props, ref) => {
    const {videoRef, loop, controls, preload, autoplay, muted, onMouseOver, onMouseLeave, poster} = props;
    const [videoPlayerId] = useState(`videoPlayer${_.random(0, 1000000)}`);
    const [src, setSrc] = useState(props.src);
    const [videoPlayer, setVideoPlayer] = useState();

    useImperativeHandle(ref, () => ({
        updateCurrentTime
    }));

    useEffect(() => {
        setSrc(props.src);
        videoPlayer && videoPlayer.src([{src: props.src}, {src: props.src, type: 'application/x-mpegURL'}]);
    }, [props.src]);

    const crateVideoPlayer = () => {
        const options = {
            loop,
            controls,
            preload,
            autoplay,
            muted,
            poster,
            loadingSpinner: {},
            playbackRates: [0.5, 1, 1.5, 2]
        };
        return videojs(videoPlayerId, options);
    };

    useEffect(() => {
        videoPlayer && videoPlayer.poster(poster);
    }, [poster]);

    const destroyVideoPlayer = player => {
        player && player.pause();
        player && player.dispose();
        // 退出画中画模式
        if (document.pictureInPictureElement) {
            document.exitPictureInPicture().catch(error => {
                console.error('Failed to exit picture-in-picture mode:', error);
            });
        } else if (document.webkitPictureInPictureElement) {
            document.webkitExitPictureInPicture().catch(error => {
                console.error('Failed to exit picture-in-picture mode:', error);
            });
        }
    };

    useEffect(() => {
        const player = crateVideoPlayer();
        setVideoPlayer(player);
        return () => {
            destroyVideoPlayer(player);
            player && player.dispose();
        };
    }, []);

    const handleMouseOver = () => {
        onMouseOver && onMouseOver();
    };

    const handleMouseLeave = () => {
        onMouseLeave && onMouseLeave();
        // showPoster();
    };

    const updateCurrentTime = currentTime => {
        if (videoPlayer) {
            videoPlayer.currentTime(0);
            // const currentPoster = videoPlayer.poster();
            // videoPlayer.poster(currentPoster);
            videoPlayer.pause();
        }
    };

    const showPoster = () => {
        const vjsPosters = document.getElementById(videoPlayerId)?.getElementsByClassName('vjs-poster');
        _.forEach(vjsPosters, vjsPoster => {
            vjsPoster.style.display = 'block';
        });
    };

    const hidePoster = () => {
        const vjsPosters = document.getElementById(videoPlayerId)?.getElementsByClassName('vjs-poster');
        _.forEach(vjsPosters, vjsPoster => {
            vjsPoster.style.display = 'none';
        });
    };

    // const handleMouseEnter = () => {
    //  videoPlayer && videoPlayer.userActive(true);
    // };

    return (
        <div ref={ref} onMouseOver={handleMouseOver} onMouseLeave={handleMouseLeave}>
            <video ref={videoRef} id={videoPlayerId} className="video-js vjs-default-skin">
                <source id="source" src={src} />
                <source id="source" src={src} type="application/x-mpegURL" />
            </video>
        </div>
    );
};
export default forwardRef(VideoPlayer);



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值