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

Youtube API限制视频仅播放2次功能仅首视频生效问题排查求助

Fixing the YouTube Video Playback Limit for Dynamic Content

It looks like your current code is relying on a single global player instance and play count variable, which is why it only works for the first video—when new videos are loaded later, those variables are still tied to the initial video, and there's no logic to set up the YouTube API listeners for the new iframes. Let's break down the fixes step by step:

Root Causes of the Issue

  • Global state: Your player variable and play count tracking are global, so they don't reset or apply to new videos added dynamically.
  • No dynamic initialization: When new videos load after users complete questions, the YouTube API isn't reattached to the new iframe elements.
  • Unscoped play count: There's no way to track how many times each individual video has been played.

Solution Code

First, update your HTML structure to use reusable classes and data attributes for per-video tracking:

<!-- Initial video container -->
<div class="video-container" style="width:640px;height:360px;background-color:#000;" data-play-count="0">
  <iframe class="youtube-iframe" height="360" src="https://www.youtube.com/embed/Qp0EztigQew?enablejsapi=1&amp;rel=0&amp;controls=0&amp;loop=0&amp;disablekb=1&amp;modestbranding=0&amp;showinfo=0" width="640"></iframe>
</div>

<!-- Later loaded videos should follow this exact structure -->

Then, replace your JavaScript with this dynamic, scalable version:

// Load YouTube iframe API once (only needs to happen once per page)
var tag = document.createElement('script');
tag.id = 'iframe-demo';
tag.src = 'https://www.youtube.com/iframe_api';
var firstScriptTag = document.getElementsByTagName('script')[0];
firstScriptTag.parentNode.insertBefore(tag, firstScriptTag);

// Store all player instances to manage cleanup and state
const players = {};

// Initialize all unsetup players when the API is ready
function onYouTubeIframeAPIReady() {
  initializeAllPlayers();
}

// Initialize a single YouTube player for an iframe
function initializePlayer(iframe) {
  // Assign a unique ID to the iframe if it doesn't have one
  let iframeId = iframe.id;
  if (!iframeId) {
    iframeId = `youtube-iframe-${Date.now()}`;
    iframe.id = iframeId;
  }

  // Mark the iframe as initialized to avoid duplicate setup
  iframe.dataset.initialized = 'true';
  const container = iframe.closest('.video-container');

  // Create the player instance and attach state listeners
  players[iframeId] = new YT.Player(iframeId, {
    playerVars: {
      'autoplay': 0,
      'controls': 0
    },
    events: {
      'onStateChange': (event) => handlePlayStateChange(event, container, iframeId)
    }
  });
}

// Initialize all uninitialized YouTube iframes on the page
function initializeAllPlayers() {
  document.querySelectorAll('.youtube-iframe:not([data-initialized="true"])').forEach(initializePlayer);
}

// Handle play state changes to track counts and enforce limits
function handlePlayStateChange(event, container, iframeId) {
  // Only count when the video starts playing (state code 1 = PLAYING)
  if (event.data === YT.PlayerState.PLAYING) {
    let playCount = parseInt(container.dataset.playCount) || 0;
    playCount++;
    container.dataset.playCount = playCount;

    // If we've hit the 2-play limit
    if (playCount >= 2) {
      // Clean up the player instance to avoid memory leaks
      players[iframeId].destroy();
      // Replace the iframe with an empty container (which is already black)
      container.innerHTML = '';
      // Optional: Add a user-facing message
      container.innerHTML = '<div style="color:white;display:flex;align-items:center;justify-content:center;height:100%;">Video playback limit reached</div>';
    }
  }
}

// Call this function AFTER loading new videos into the DOM (after user completes questions)
function onNewVideoContentLoaded() {
  initializeAllPlayers();
}

Key Improvements

  1. Per-video state tracking: We use data-play-count on each video container to track how many times that specific video has been played.
  2. Dynamic initialization: The initializeAllPlayers function scans for any new, uninitialized iframes and sets up the YouTube player for them—call onNewVideoContentLoaded() right after inserting new videos into the page.
  3. Clean player management: The players object keeps track of all active player instances, so we can properly destroy them when the limit is reached to avoid memory issues.
  4. Scalable structure: This code will work for any number of videos loaded dynamically, not just the first one.

How to Use with Your Questionnaire

Whenever you load a new video and its corresponding questions into the page:

  1. Insert the new .video-container and .youtube-iframe elements into the DOM (following the structure above).
  2. Immediately call onNewVideoContentLoaded() to initialize the player for the new video.

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.21 03:59:24