javascript - 视频无法在移动设备上自动播放

标签 javascript html css reactjs video

我正在使用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/

相关文章:

javascript - 验证 html 下拉列表中的日期

html - 垂直偏移嵌套 Div

jquery - 如何显示悬停的子菜单?

javascript - 为什么声明 xmlhttp.onreadystatechange 导致这个程序只工作一次?

javascript - 使用 CSS 缩放 HTML 中的图像

javascript - TypeScript 类 .drawImage

html - 如何将 2 个 div 放置在一个更大的 div 中?

javascript - jQuery 鼠标悬停,当 true 时向左或向右动画

javascript - jQuery Mobile 动态改变按钮颜色

html - 在 CSS 中,如何获得左侧固定宽度的列,右侧表格使用其余宽度?