javascript - Vimeo,检测全屏以阻止获取新播放器(动态宽度更改)
问题描述
我想动态更改 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 }} />
推荐阅读
- java - 使用 Spring Boot 在运行时以编程方式更改 application.properties 文件
- regex - 比较两个文件而不对 AWK 进行排序
- ios - 如何使用 Xcode 在 Launchscreen.storyboard 中为 UILabel 指定“等宽系统字体”?
- django - 无法在 Django 中将当前用户设置为帖子的作者
- android - 为什么 iOS Safari 浏览器中的 padding 和 margin 看起来不同?
- python - 将csv文件中的两列数据一起添加到python中同一csv文件中的新列中
- python - 将值“附加”到特定键的字典中
- angular - 正则表达式会中断 Angular 延迟加载模块的加载(仅限 Safari)
- java - 当我尝试使用多个查询参数调用端点时得到 404
- sql - 查询在简单选择上花费的时间太长