You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在React视频播放器中实现视频播放时自动随机弹出人机验证弹窗

刚巧我之前做过类似的React视频播放器验证需求,给你整理了一套完整的实现方案,涵盖随机触发、模态框控制和视频状态同步这些核心点,直接就能上手用。

整体实现思路

核心逻辑就是:监听视频播放事件→在播放过程中生成随机时间点→到点后暂停视频并弹出验证码模态框→验证通过后恢复视频播放,同时做好定时器清理避免内存泄漏。

核心实现步骤&代码示例

1. 基础组件结构

我们用React函数组件来实现,用到useRef获取视频元素引用,useState控制模态框显示,useEffect处理事件监听和定时器清理。

import { useState, useRef, useEffect } from 'react';

const VideoPlayerWithCaptcha = () => {
  // 控制验证码模态框显示/隐藏
  const [showCaptchaModal, setShowCaptchaModal] = useState(false);
  // 视频元素引用
  const videoRef = useRef(null);
  // 存储定时器ID,用于后续清理
  const timerRef = useRef(null);

  // 生成随机触发时间:取视频时长的10%~80%区间,避免开头或结尾弹出
  const getRandomTriggerTime = (videoDuration) => {
    const min = videoDuration * 0.1;
    const max = videoDuration * 0.8;
    return Math.floor(Math.random() * (max - min + 1)) + min;
  };

  // 启动随机验证定时器:视频加载完成后获取时长,设置定时触发
  const startCaptchaTimer = () => {
    const video = videoRef.current;
    if (!video) return;

    // 等待视频元数据加载完成,确保能拿到正确时长
    video.onloadedmetadata = () => {
      const triggerTime = getRandomTriggerTime(video.duration);
      timerRef.current = setTimeout(() => {
        video.pause(); // 暂停视频
        setShowCaptchaModal(true); // 弹出验证码模态框
      }, triggerTime * 1000); // 转成毫秒单位
    };
  };

  // 处理验证码验证通过逻辑
  const handleCaptchaVerify = () => {
    setShowCaptchaModal(false);
    videoRef.current?.play(); // 恢复视频播放
    // 可选:如果不想同一播放周期内重复弹出,可以添加状态标记
    // setIsVerified(true);
  };

  // 监听视频播放事件,启动定时器;组件卸载时清理监听和定时器
  useEffect(() => {
    const video = videoRef.current;
    if (!video) return;

    video.addEventListener('play', startCaptchaTimer);

    return () => {
      video.removeEventListener('play', startCaptchaTimer);
      if (timerRef.current) clearTimeout(timerRef.current);
    };
  }, []);

  return (
    <div className="video-player-container">
      {/* 视频播放器 */}
      <video
        ref={videoRef}
        src="your-video-url.mp4" // 替换成你的视频地址
        controls
        style={{ width: '100%', maxWidth: '800px' }}
      />

      {/* 验证码模态框 */}
      {showCaptchaModal && (
        <div className="captcha-modal-overlay">
          <div className="captcha-modal">
            <h3>请完成人机验证</h3>
            <p>点击下方按钮确认您不是机器人</p>
            <button onClick={handleCaptchaVerify} className="verify-btn">
              我不是机器人
            </button>
          </div>
        </div>
      )}

      {/* 内置样式,也可以提取到外部CSS文件 */}
      <style jsx>{`
        .video-player-container {
          position: relative;
          max-width: 800px;
          margin: 0 auto;
        }
        .captcha-modal-overlay {
          position: fixed;
          top: 0;
          left: 0;
          width: 100%;
          height: 100%;
          background: rgba(0, 0, 0, 0.7);
          display: flex;
          justify-content: center;
          align-items: center;
          z-index: 1000;
        }
        .captcha-modal {
          background: #fff;
          padding: 2.5rem;
          border-radius: 10px;
          box-shadow: 0 0 20px rgba(0,0,0,0.3);
          text-align: center;
        }
        .verify-btn {
          margin-top: 1.5rem;
          padding: 1rem 2rem;
          background-color: #2563eb;
          color: #fff;
          border: none;
          border-radius: 6px;
          font-size: 1rem;
          cursor: pointer;
          transition: background-color 0.2s;
        }
        .verify-btn:hover {
          background-color: #1d4ed8;
        }
      `}</style>
    </div>
  );
};

export default VideoPlayerWithCaptcha;

2. 关键细节说明

  • 验证码替换:示例里的按钮是模拟验证,实际项目中可以替换成Google reCAPTCHA或其他第三方验证码服务,只需要把handleCaptchaVerify改成第三方验证的成功回调即可。
  • 避免重复触发:如果不想同一视频播放周期内多次弹出验证,可以添加一个isVerified状态,验证通过后标记为true,后续不再启动定时器。
  • 视频加载容错:必须等待onloadedmetadata事件触发后再获取视频时长,否则video.duration会返回NaN,导致随机时间生成失败。
  • 内存泄漏防范:组件卸载或视频暂停时一定要清理定时器和事件监听,避免内存泄漏问题。
  • 移动端适配:模态框的样式已经做了基础适配,确保在移动端也能正常显示和点击。

内容的提问来源于stack exchange,提问作者Xena

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.01 03:07:27