我想根据窗口宽度动态更改vimeo播放器的宽度。您可以在问题的末尾看到该组件的完整代码,也许已经有了一种更简单的方法来动态更改播放器的宽度,因此我根本不必处理这些问题(提供了响应选项通过vimeo不适用于我)
我当前解决方案的问题:如果播放器进入全屏模式或在全屏模式下旋转手机,我不想触发更改,因为vimeo已经自动处理了这些更改,但是我很难检测播放器处于全屏状态。
const isFullscreen = (document.fullscreenElement
|| document.webkitFullscreenElement
|| document.mozFullScreenElement
|| document.msFullscreenElement
|| playerWidth === delayedWidth)
此解决方案不适用于iphone 11 pro以及可能所有的Safari浏览器,因为其中没有完全实现fullScreen。
import React, {
useEffect, useContext, useState, useRef,
} from 'react';
import PropTypes from 'prop-types';
import Player from '@vimeo/player';
import STYLES from '../../enums/styles';
import { BrowserContext } from '../../contexts/BrowserContext';
const TAG = 'player';
/**
* remove event listeners
* @param {object} playerRef
*/
function removeEventListeners(playerRef) {
if (!playerRef.current) return;
playerRef.current.off('ended');
playerRef.current.off('pause');
playerRef.current.off('play');
}
/**
* remove interval
* @param {object} intervalRef
*/
function removeInterval(intervalRef) {
if (!intervalRef.current) return;
window.clearInterval(intervalRef.current);
}
/**
* 640×480, 800×600, 960×720, 1024×768, 1280×960,
* 1400×1050, 1440×1080 , 1600×1200, 1856×1392, 1920×1440, and 2048×1536
* @param {} width
*/
function computeRatio(delayedWidth) {
const height = window.innerHeight;
const width = delayedWidth - delayedWidth * 0.1;
if (height <= 480) {
return width > 640 ? 640 : width;
}
if (height <= 600) {
return width > 800 ? 800 : width;
}
if (height <= 720) {
return width > 960 ? 960 : width;
}
if (height <= 768) {
return width > 1024 ? 1024 : width;
}
if (height <= 960) {
return width > 1280 ? 1280 : width;
}
if (height <= 1050) {
return width > 1400 ? 1400 : width;
}
if (height <= 1080) {
return width > 1440 ? 1440 : width;
}
if (height <= 1200) {
return width > 1600 ? 1600 : width;
}
if (height <= 1392) {
return width > 1856 ? 1856 : width;
}
if (height <= 1440) {
return width > 1920 ? 1920 : width;
}
if (height <= 1536) {
return width > 2048 ? 2048 : width;
}
return width;
}
const VideoPlayer = ({
index, title, description, link, onProgress, latestProgress,
}) => {
const { delayedWidth } = useContext(BrowserContext);
const [time, setTime] = useState(latestProgress < 1 ? latestProgress : 0);
const playerRef = useRef(null);
const intervalRef = useRef(null);
useEffect(() => {
console.tag(TAG).debug('changing delayed width', delayedWidth);
const asyncEffect = async () => {
const player = playerRef.current;
if (player) {
const playerWidth = await player.getVideoWidth();
const isFullscreen = document.fullscreenElement
|| document.webkitFullscreenElement
|| document.mozFullScreenElement
|| document.msFullscreenElement
|| playerWidth === delayedWidth;
console.tag(TAG).debug('fullscreen detected', isFullscreen);
const isMobile = window.innerWidth <= STYLES.breakpoints.phoneWidth;
const isLandscape = window.innerWidth > window.innerHeight;
if (isFullscreen || (isLandscape && isMobile)) {
console.tag(TAG).debug('isLandscape, isMobile', isLandscape, isMobile);
return;
}
removeEventListeners(playerRef);
playerRef.current = null;
player.pause();
player.destroy();
}
if (intervalRef.current) {
removeInterval(intervalRef);
intervalRef.current = null;
}
const options = { id: link, width: computeRatio(delayedWidth) };
const newPlayer = new Player(`frame-${title}-${index}`, options);
playerRef.current = newPlayer;
if (time) {
newPlayer.getDuration().then((duration) => {
const seconds = duration * time;
newPlayer.setCurrentTime(seconds);
});
}
const keepTrackProgress = async () => {
// gets duration of video in seconds
const duration = await newPlayer.getDuration();
intervalRef.current = window.setInterval(() => {
newPlayer.getCurrentTime().then((seconds) => {
// `seconds` indicates the current playback position of the video
const progress = seconds / duration;
console.tag(TAG).debug(`progress: ${progress}, duration ${duration}, seconds ${seconds}`);
onProgress(progress);
setTime(progress);
});
// track every next 10 seconds of progress
}, 10000);
};
newPlayer.on('ended', () => {
removeInterval(intervalRef);
intervalRef.current = null;
onProgress(1);
setTime(1);
});
newPlayer.on('pause', ({ duration, seconds }) => {
removeInterval(intervalRef);
intervalRef.current = null;
const progress = seconds / duration;
console.tag(TAG).debug(`progress at paused: ${progress}, duration ${duration}, seconds ${seconds}`);
onProgress(progress);
setTime(progress);
});
newPlayer.on('play', () => {
keepTrackProgress();
});
};
asyncEffect();
return () => {
removeInterval(intervalRef);
removeEventListeners(playerRef);
};
}, [delayedWidth]);
return (
<div className="video-player">
<div id={`frame-${title}-${index}`} className="frame-wrapper" />
<div className="details">
<h1>{title}</h1>
<p>{description}</p>
</div>
</div>
);
};
VideoPlayer.propTypes = {
index: PropTypes.number.isRequired,
title: PropTypes.string.isRequired,
description: PropTypes.string.isRequired,
link: PropTypes.string.isRequired,
onProgress: PropTypes.func.isRequired,
latestProgress: PropTypes.number.isRequired,
};
export default VideoPlayer;
我正在使用u-wave vimeo播放器,其中的响应已得到照顾。
import Vimeo from '@u-wave/react-vimeo';`
<Vimeo
video={videoURL}
autoplay={false}
controls={true}
responsive={true}
onEnd={() => { onVideoEnd() }}
style={{ justifyContent: 'center'}}
start={0}
onTimeUpdate={(duration) => { console.log(duration }} />