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

如何在React中存储已登录用户的观看视频记录?附播放器代码

解决已登录用户YouTube视频观看记录存储问题

嘿,针对你已登录用户观看视频记录的存储需求,结合你给出的VideoDetails组件,我整理了一套可落地的解决方案:

第一步:集成YouTube IFrame API监听播放行为

YouTube原生iframe不会主动暴露播放状态,所以我们得借助YouTube IFrame Player API来捕获用户的观看行为(比如视频开始播放、播放进度达标),这样才能准确记录有效观看记录。

修改你的组件,加入API加载和事件监听逻辑:

import React, { Component } from 'react';

class VideoDetails extends Component {
  constructor(props){
    super(props);
    this.player = null;
    this.videoId = props.video?.id.videoId;
    this.hasRecorded = false; // 避免同一视频重复记录
  }

  componentDidMount() {
    // 加载YouTube IFrame API
    if (!window.YT) {
      const tag = document.createElement('script');
      tag.src = "https://www.youtube.com/iframe_api";
      const firstScriptTag = document.getElementsByTagName('script')[0];
      firstScriptTag.parentNode.insertBefore(tag, firstScriptTag);
      
      // API加载完成后初始化播放器
      window.onYouTubeIframeAPIReady = () => {
        this.initPlayer();
      };
    } else {
      this.initPlayer();
    }
  }

  initPlayer() {
    this.player = new window.YT.Player('youtube-player', {
      videoId: this.videoId,
      events: {
        'onProgress': this.onPlayerProgress // 监听播放进度,确保用户真的在看
      }
    });
  }

  onPlayerProgress = (event) => {
    // 当视频播放超过30%时记录(可根据需求调整阈值),且只记录一次
    if (this.hasRecorded) return;
    
    const duration = event.target.getDuration();
    const currentTime = event.target.getCurrentTime();
    if (duration > 0 && currentTime / duration > 0.3) {
      this.saveWatchHistory();
      this.hasRecorded = true;
    }
  }

  saveWatchHistory = () => {
    const { video } = this.props;
    if (!video) return;

    // 构造观看记录数据
    const watchRecord = {
      userId: '替换为当前登录用户ID', // 从你的登录状态管理(如Context/Redux/localStorage)获取
      videoId: video.id.videoId,
      videoTitle: video.snippet.title,
      watchedAt: new Date().toISOString(),
      progress: Math.round(this.player.getCurrentTime())
    };

    // 核心:发送到后端存储(已登录用户必须持久化到数据库)
    fetch('/api/user/watch-history', {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
        'Authorization': `Bearer ${localStorage.getItem('authToken')}` // 替换为你的认证方式
      },
      body: JSON.stringify(watchRecord)
    })
    .then(response => response.json())
    .then(() => console.log('观看记录已成功保存'))
    .catch(err => console.error('保存观看记录失败:', err));

    // 可选:本地缓存作为补充(比如离线时暂存,上线后同步)
    // const localHistory = JSON.parse(localStorage.getItem('localWatchHistory')) || [];
    // localHistory.unshift(watchRecord);
    // localStorage.setItem('localWatchHistory', JSON.stringify(localHistory.slice(0, 50)));
  }

  render(){
    const video = this.props.video;
    if(!video) {
      return <div />
    }

    return (
      <div>
        <div>
          {/* 用带ID的div替代原生iframe,由YouTube API初始化播放器 */}
          <div id="youtube-player" className="Videoplayer"></div>
        </div>
        <div>
          <h2>{video.snippet.title}</h2>
          <div>{video.snippet.description}</div>
        </div>
      </div>
    )
  }
}

export default VideoDetails;

第二步:后端存储配套逻辑

对于已登录用户,观看记录需要持久化到数据库,你需要在后端完成:

  1. 创建user_watch_history表,字段建议包含:id(主键)、user_id(关联用户表)、video_id、video_title、watched_at、progress
  2. 编写POST接口/api/user/watch-history,验证用户身份后,将前端传来的记录存入数据库
  3. 可额外编写GET接口,供用户查询自己的观看历史

第三步:优化细节

  • 避免重复记录:前端用hasRecorded标记,后端可给user_id + video_id加唯一约束(或允许重复但保留最新记录)
  • 用户身份校验:确保userId和认证令牌的正确性,避免未登录用户或伪造请求
  • API加载容错:可添加API加载超时处理,避免因网络问题导致播放器初始化失败

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 08:30:49