我正在使用reactjs,由于某种原因,视频无法在移动设备上自动播放。 我使用的是 iOS 17、Safari 这是我的代码:
<div className="video" ref={videoRef} dangerouslySetInnerHTML={{
__html: `
<video
loop
muted
autoplay
playsinline
muted
defaultMuted
loop
>
<source src=${video} type="video/mp4" />
</video>
`}}>
在移动设备上,只有一个播放按钮。
我还尝试使用 javascript 播放视频:
const videoRef = useRef(null)
useEffect(() => {
if (videoRef.current) {
const videoElement = videoRef.current.children[0];
videoElement.play();
}
})
但是,我收到错误:`当前上下文中的用户代理或平台不允许该请求,可能是因为用户拒绝了权限=。```
编辑:我如何解决这个问题:
错误原因:在低功耗模式下,Safari 上的自动播放视频默认处于关闭状态
我如何解决这个问题:如果视频没有显示,我们只需向视频添加一个 postor 属性,这将带来一个播放按钮以开始播放,但是,我使用了img 标签,如果视频没有自动播放,因为有一个播放按钮。这是我的代码:
const [videoPlayed, setVideoPlayed] = useState(false)
useEffect(() => {
if (videoRef.current) {
const videoElement = videoRef.current.children[0];
videoElement.play().then(() => {
setVideoPlayed(true)
}).catch(err => { })
document.addEventListener("click", () => {
videoElement.play().then(() => setVideoPlayed(true)).catch(() => {})
document.removeEventListener("click", () => {})
})
}
return (
<>
{/* If video isn't played */}
<div className="image">
{!videoPlayed && <img src={thumbnail} alt="Alt" />}
</div>
<div className="video" ref={videoRef} style={{
display: videoPlayed ? "block" : "none"
}} dangerouslySetInnerHTML={{
__html: `
<video
loop
muted
autoplay
playsinline
muted
defaultMuted
loop
poster="${thumbnail}"
>
<source src=${video} type="video/mp4" alt="content" />
</video>
`}}>
</div>
)
在上面的代码中,会有一个占位符图像。如果视频能够自动播放,则视频将开始播放。在某些情况下,视频仍然无法播放,也没有错误,因此为了解决这个问题,我为 click
添加了一个事件监听器,它将播放视频。
感谢@DarshShah、@JaromandaX、@MohamdImran 帮助我解决这个问题!
最佳答案
出于用户体验和数据消耗方面的考虑,移动浏览器(尤其是 iOS 上的 Safari)上的自动播放策略可能非常具有挑战性。为了解决这个问题,浏览器通常需要用户交互才能允许自动播放。
您之所以遇到此问题,是因为移动设备上没有用户交互时不允许自动播放。除非触发用户交互事件,否则尝试使用 JavaScript 播放视频将无法工作。因此应该触发 play
方法来响应用户交互,例如单击按钮等,例如
const handlePlay = () => {
const videoElement = videoRef.current.children[0];
videoElement.play();
};
<button onClick={handlePlay}>Play My Video</button>
另一个解决方案是使用 playsinline
属性,因为 iOS 上的 Safari 要求视频必须内联播放。确保您已将此属性包含在视频标记中
<video
loop
muted
autoPlay
playsInline
defaultMuted
loop>
<source src={video} type="video/mp4" />
</video>
如果上述方法对任何人都不起作用,我们可以尝试通过传递空依赖项数组来播放通过 useEffect 挂载的视频组件,以确保它在挂载时仅运行一次已经结合了超时函数来解决浏览器限制,特别是在移动设备上,我现在将解释通过延迟 play()
方法与超时,您喜欢在初始渲染后创建一个小窗口在此期间调用 play()
方法。这本质上是模拟用户交互,允许视频开始播放。
import React, { useRef, useEffect } from 'react';
const VideoPlayer = ({ video }) => {
const videoRef = useRef(null);
useEffect(() => {
const playVideo = () => {
if (videoRef.current) {
setTimeout(() => {
videoRef.current.play().catch(error => console.error('Autoplay error:', error));
}, 500); // Adjust the delay as needed
}
};
// Play the video on page load
playVideo();
}, []); // Empty dependency array ensures the effect runs only once on mount
return (
<div>
<video ref={videoRef} loop muted playsInline defaultMuted>
<source src={video} type="video/mp4" />
</video>
</div>
);
};
export default VideoPlayer;
关于javascript - 视频无法在移动设备上自动播放,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/77546809/