仅在可见时才反应自动播放 <video /> (mp4)

Posted

技术标签:

【中文标题】仅在可见时才反应自动播放 <video /> (mp4)【英文标题】:React autoplay <video /> (mp4) only when visible 【发布时间】:2020-10-20 05:35:35 【问题描述】:

我正在编写一个组件,它从 Giphy 中提取 gif 并将它们呈现在 React Infinite Scroll 组件中。无限滚动按预期工作,但后来我遇到了问题。我希望 gif 能够自动播放,所以我添加了 autoplay 属性。然后我意识到,所有的 gif 图像同时播放,性能就消失了。 我尝试了许多不同的解决方案,包括为每个视频组件附加一个 ref 并使用 react-visibility-sensor 尝试在可见时播放,但我无法找到一种可行的方法。 这是当前与每个 mp4 自动播放一起存在的组件。我移除了 VisibilitySensor,因为我无法让它工作。

  const videoRefs = useRef(
    [...new Array(gifArray.length)].map(() => createRef()),
  );

  return (
    <div>
      gifArray && (
        <InfiniteScroll
          dataLength=gifArray
          next=getMore
          hasMore=true
          loader=<div>Loading...</div>
        >
          gifArray.map((gif, i) => 
            return (
              <video
                width='320'
                height='240'
                loop
                autoPlay
                key=gif.id
                ref=videoRefs.current[i]
              >
                <source src=gif.images.downsized_small.mp4 type='video/mp4' />
              </video>
            );
          )
        </InfiniteScroll>
      )
    </div>
  );
;

数据在单独的组件中检索并作为道具传递。

export const HomePage = () => 
  const [gifObject, setGifObject] = useState([]);
  const [searchValue, setSearchValue] = useState('');
  const [pageNumber, setPageNumber] = useState(0);

  const handleSearch = (value) => 
    setSearchValue(value);
    fetch(
      `http://api.giphy.com/v1/gifs/search?q=$value&api_key=$API_KEY&limit=20`,
    )
      .then((data) => data.json())
      .then((result) => 
        setGifObject(result);
      );
  ;
  return (
    <div>
      <SearchForm handleSearchValue=handleSearch />
      gifObject?.data?.length > 1 ? (
        <GifDisplay gifArray=gifObject.data getMore=getData />
      ) : null
    </div>
  );

【问题讨论】:

嘿,你找到解决办法了吗? @DiegoFortes 我在下面给出了我的答案 【参考方案1】:

我最终解决了这个问题。 我为每个 gif 创建了一个组件,并使用了一个名为 react-visibility-sensor 的包来检查它是否可见。GifDisplay 组件几乎保持不变:

// GifDisplay.tsx
export const GifDisplay = ( gifArray, getMore, handleSearch ) => 
  return (
    <GifDisplayWrapper>
      gifArray && (
        <InfiniteScroll
          dataLength=gifArray
          next=getMore
          hasMore=true
          loader=<div>Loading...</div>
        >
          <ArrayWrapper>
            gifArray.map((gif) => 
              return (
                <div key=gif.id>
                  <SingleGif gif=gif />
                </div>
              );
            )
          </ArrayWrapper>
        </InfiniteScroll>
      )
    </GifDisplayWrapper>
  );
;

SingleGif 组件使用了react-visibility-sensor 并更新了每个组件的状态。

// SingleGif.tsx
import VisibilitySensor from 'react-visibility-sensor';

export const SingleGif = ( gif ) => 
  const videoRef = useRef(null);
  const [isVisible, setIsVisible] = useState(false);

  useEffect(() => 
    if (isVisible) 
      videoRef.current.play();
     else 
      if (videoRef.current.play) 
        videoRef.current.pause();
      
    
  , [isVisible]);

  return (
    <VisibilitySensor onChange=(isVisible) => setIsVisible(isVisible)>
      <video width='320' height='240' loop ref=videoRef>
        <source src=gif.images.downsized_small.mp4 type='video/mp4' />
      </video>
    </VisibilitySensor>
  );
;

【讨论】:

react-visibility-sensor 项目已死。现在改用react-intersection-observer【参考方案2】:

使用react-intersection-observer 而不是react-visibility-sensor 如上面有人评论的那样。 react-visibility-sensor 不再可用。

【讨论】:

以上是关于仅在可见时才反应自动播放 <video /> (mp4)的主要内容,如果未能解决你的问题,请参考以下文章

当浏览器缩放超过75%时自动播放不起作用

我希望我的 iframe 弹出窗口仅在单击图像/链接时才可见,而不是默认情况下

不显示视频,只有在 react-native-video 中播放真正的 android 设备时才会发出声音

仅在可见时才需要 Woocommerce 结帐字段

Chrome html-video不可见开始播放,直到我滚动页面[关闭]

仅在重新渲染组件时才反应状态更新