YVPlayer Knowledge Base & Help

Documentation & Guides

Everything you need to embed, customize, and deploy YVPlayer across React, Next.js, Vue, and vanilla HTML.

Popular topics:
Cinema-Grade HTML5 Overlay

Introduction to YVPlayer

YVPlayer is a high-performance, distraction-free HTML5 video player overlay designed specifically for YouTube videos. It strips away 100% of YouTube's native interface clutter, including video titles, channel avatars, "More videos" recommended drawers, and end-screen cards, while elevating playback with cinema-grade features inspired by modern production players like Video.js 10.

Zero AI Slop Guarantee

YVPlayer is handcrafted in pure vanilla ES6 JavaScript and clean modern CSS with zero heavy framework dependencies. Every animation uses GPU-accelerated cubic-bezier curves, every layout is mathematically locked to 16:9, and every theme dynamically recalculates CSS custom property tokens in real-time.

Quick Start: Embed in 3 Simple Steps (Under 60 Seconds)

No complicated setups or bundler configurations required:

  1. Step 1: Include the CSS & JS links in your <head>.
  2. Step 2: Place <div data-yv-video="YOUR_VIDEO_ID" style="aspect-ratio:16/9;"></div> anywhere on your page.
  3. Step 3: That is it! The player automatically initializes with custom controls, themes, and scrubbing.

Zero YouTube Clutter

Masks top branding banners, avatars, share pills, and end-screen video grids for a pure theatrical playback experience.

Interactive Storyboard

Scrub across the timeline with high-resolution frame previews stitched on-the-fly from YouTube's storyboard sprites.

Triple-Engine PiP

Independent Document PiP (full custom player in OS window), Native Video PiP (720p HD stream with synced controls), and In-Page Dock mini-player.

Real-Time Color Theming

Pick from 7 polished presets or feed any custom hex color. Controls, glow effects, hover states, and ripples adapt instantly.

Benchmark

Feature Comparison Matrix

How YVPlayer compares against standard YouTube embeds and alternative web players:

Capability YVPlayer Standard YouTube Embed Video.js (YouTube Plugin) Plyr
Zero Branding & Overlays 100% Masked YouTube UI Partial Partial
Storyboard Timeline Previews Native Sprites Built-in Requires VTT Requires VTT
True OS-Level Desktop PiP 720p Native Stream Context Menu Only Blocked by iframe In-tab only
In-Page Connected Mini-Player 16:9 Corner Resizing None None None
Custom Caption Styling Box/Transparent + Alpha Fixed Limited Limited
Built-in Sleep Auto-Pause Timer 15m - End of Video None None None
YouTube Live Stream & DVR Support Auto 🔴 LIVE Pill + DVR Edge Sync Cluttered UI HLS plugin needed HLS plugin needed
YouTube Shorts (9:16 Vertical Ratio) 9:16 Vertical + Streamlined Controls Feed overlay Manual CSS override Manual CSS override
Background Play (Ambient Video Behind Content) Muted, Looping, Zero Controls Native branding visible Complex plugin config Not supported
1-Click HTML Drop-In (Zero JS) <div data-yv-video> <iframe> Complex setup Complex setup
Internals

Core Architecture & Data Flow

YVPlayer bridges YouTube's underlying streaming infrastructure with a custom HTML5 canvas and controls tree:

Frontend Client
YVPlayer Host Page
Custom controls row, storyboard scrubber, HUD pill, theme variables, sleep timer
➔ Dual-Engine Bridge ➔
Engine A: In-Page Playback

Masked YouTube IFrame API with custom event dispatcher & audio sync

Engine B: OS-Level PiP

Native <video> element connected to 720p stream proxy with 16:9 aspect lock

➔ Resolver Proxy ➔
Stream Resolver
Cloudflare Worker / Server
Extracts format 22 (720p HD with muxed audio) & storyboard specs with byte-range caching
AI Prompt Architect

Generate Production AI Prompts in 1 Click

Select your tech stack, PiP engine, theme palette, and open-source stream proxies. Copy and paste the generated prompt into ChatGPT, Claude, Cursor, Copilot, or Gemini to integrate YVPlayer flawlessly into your codebase.

Live Generated Prompt
~380 tokens
Getting Started

1-Click Drop-In HTML (Zero JavaScript)

The simplest way to integrate YVPlayer into any HTML website, WordPress template, Webflow embed, or Shopify theme. You do not need to write a single line of JavaScript.

HTML — Drop-In Embed
<!-- 1. YVPlayer Styles & Script via jsDelivr CDN -->
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@tabler/icons-webfont@latest/tabler-icons.min.css" />
<link rel="stylesheet" href="https://cdn.jsdelivr.net/gh/your-username/yvplayer@main/yvPlayer.css" />
<script src="https://cdn.jsdelivr.net/gh/your-username/yvplayer@main/yvPlayer.js"></script>

<!-- 2. Player Element: Set data-yv-video with your YouTube ID or URL -->
<div 
  data-yv-video="M7lc1UVf-VE" 
  data-yv-theme="red"
  style="max-width: 960px; aspect-ratio: 16/9; margin: 0 auto; border-radius: 12px; overflow: hidden;"
></div>
Automatic Lifecycle Management

When the browser parses yvPlayer.js, it automatically scans the DOM for elements with data-yv-video, loads the YouTube IFrame API in the background, parses full URLs or raw 11-char IDs, and mounts the player. No manual initialization scripts required!

Distribution

CDN Providers & Local Assets

YVPlayer is distributed through leading global CDNs with automatic HTTP/3 caching and Brotli compression:

CDN Provider Stylesheet (CSS) URL JavaScript (JS) URL Status
jsDelivr (Recommended) https://cdn.jsdelivr.net/gh/your-username/yvplayer@main/yvPlayer.css https://cdn.jsdelivr.net/gh/your-username/yvplayer@main/yvPlayer.js Production / Fast
Self-Hosted / Local ./yvPlayer.css ./yvPlayer.js Offline / Private
Programmatic Control

Standard JavaScript API

When you need programmatic playback control, custom callbacks, or dynamic video switching, use the YVPlayer.init() Promise API:

JavaScript — API Initialization
<div id="player" style="max-width: 960px; aspect-ratio: 16/9; margin: 0 auto; border-radius: 12px; overflow: hidden;"></div>

<script src="https://www.youtube.com/iframe_api"></script>
<script src="yvPlayer.js"></script>

<script>
  window.onYouTubeIframeAPIReady = function() {
    YVPlayer.init("player", {
      defaultId: "M7lc1UVf-VE",
      theme: "red",
      autoplay: true,
      loop: false
    }).then(function() {
      console.log("YVPlayer initialized successfully!");
    });
  };
</script>
Framework Integration

React & Next.js Component

Integrate YVPlayer into React 18, React 19, or Next.js (App Router / Pages Router) with proper mounting, unmounting, and memory leak cleanup:

React / Next.js — VideoPlayer.tsx
import React, { useEffect, useRef } from "react";

export function VideoPlayer({ videoId, theme = "red", customColor, autoplay = true }) {
  const containerRef = useRef(null);
  const playerIdRef = useRef("yv-" + Math.random().toString(36).substring(2, 9));

  useEffect(() => {
    const id = playerIdRef.current;
    if (typeof window === "undefined" || !window.YVPlayer) return;

    window.YVPlayer.init(id, {
      defaultId: videoId,
      theme,
      autoplay
    }).then(() => {
      if (customColor) window.YVPlayer.setTheme(id, customColor, "Custom");
    });

    return () => {
      if (window.YVPlayer?.destroy) window.YVPlayer.destroy(id);
    };
  }, [videoId, theme, customColor, autoplay]);

  return (
    <div
      id={playerIdRef.current}
      ref={containerRef}
      style={{ maxWidth: "960px", aspectRatio: "16/9", borderRadius: "14px", overflow: "hidden" }}
    />
  );
}
Framework Integration

Vue 3, Nuxt & Svelte Integration

Official production wrappers for Vue 3 Composition API, Nuxt 3 SSR applications, and Svelte 4/5 with reactive props, automatic player instance cleanup, and dynamic video switching.

Vue 3 (Composition API & <script setup>)

Drop the following reusable Single File Component (SFC) into your Vue 3 or Vite project. It automatically synchronizes video IDs, themes, and PiP modes with full reactive watchers:

Vue 3 Component — YVPlayer.vue
<template>
  <div
    :id="playerId"
    class="yvPlayer"
    :style="{ width: '100%', aspectRatio: '16 / 9', borderRadius: radius, overflow: 'hidden' }"
  ></div>
</template>

<script setup>
import { ref, onMounted, onBeforeUnmount, watch } from "vue";

const props = defineProps({
  videoId: { type: String, required: true },
  theme: { type: String, default: "red" },
  customColor: { type: String, default: null },
  autoplay: { type: Boolean, default: true },
  pipMode: { type: String, default: "document" },
  radius: { type: String, default: "14px" }
});

const playerId = "yv-" + Math.random().toString(36).substring(2, 9);

onMounted(() => {
  if (typeof window === "undefined" || !window.YVPlayer) return;

  window.YVPlayer.init(playerId, {
    defaultId: props.videoId,
    theme: props.theme,
    customColor: props.customColor,
    autoplay: props.autoplay,
    pipMode: props.pipMode,
    storyboard: true
  });
});

watch(() => props.videoId, (newId) => {
  if (window.YVPlayer && window.YVPlayer.changeVideo) {
    window.YVPlayer.changeVideo(playerId, newId);
  }
});

watch(() => props.theme, (newTheme) => {
  if (window.YVPlayer && window.YVPlayer.setTheme) {
    window.YVPlayer.setTheme(playerId, props.customColor || newTheme, newTheme);
  }
});

onBeforeUnmount(() => {
  if (window.YVPlayer && window.YVPlayer.destroy) {
    window.YVPlayer.destroy(playerId);
  }
});
</script>
Nuxt 3 SSR Note: Wrap your player component in <ClientOnly> to ensure client-side DOM evaluation since YVPlayer operates on browser window objects and the YouTube IFrame API.

Svelte 4 & Svelte 5 Component

In Svelte, bind the player target element with bind:this and control the lifecycle through onMount and onDestroy:

Svelte Component — VideoPlayer.svelte
<script>
  import { onMount, onDestroy } from "svelte";

  export let videoId = "M7lc1UVf-VE";
  export let theme = "red";
  export let customColor = null;
  export let pipMode = "document";
  export let autoplay = true;

  let playerEl;
  let playerId = "yv-svelte-" + Math.random().toString(36).substring(2, 8);
  let playerReady = false;

  onMount(() => {
    if (typeof window === "undefined" || !window.YVPlayer) return;

    window.YVPlayer.init(playerId, {
      defaultId: videoId,
      theme,
      customColor,
      pipMode,
      autoplay,
      storyboard: true
    }).then(() => {
      playerReady = true;
    });
  });

  $: if (playerReady && videoId && window.YVPlayer) {
    window.YVPlayer.changeVideo(playerId, videoId);
  }

  onDestroy(() => {
    if (window.YVPlayer && window.YVPlayer.destroy) {
      window.YVPlayer.destroy(playerId);
    }
  });
</script>

<div
  bind:this={playerEl}
  id={playerId}
  class="yvPlayer"
  style="width: 100%; aspect-ratio: 16 / 9; border-radius: 14px; overflow: hidden;"
></div>
Declarative API

HTML Data Attributes Reference

All declarative properties supported by 1-Click Drop-in containers:

Attribute Type Default Description
data-yv-video string required YouTube Video ID (11 chars) or full URL (e.g. https://youtube.com/watch?v=...).
data-yv-theme string "default" Preset theme name: red, cyan, purple, emerald, teal, gold, white.
data-yv-color hex string null Custom accent color (e.g. #ff0055). Overrides preset theme dynamically.
data-yv-autoplay boolean "true" Whether the player should start playback immediately on mount (subject to browser policy).
data-yv-pip "document" | "os" | "inpage" "os" Default Picture-in-Picture engine preference (Document PiP, Native Video 720p PiP, or In-Page Dock).
data-yv-storyboard boolean "true" Whether to prefetch and display storyboard thumbnails on seekbar hover.
Configuration

JavaScript Options Reference

Available parameters passed into YVPlayer.init(elementId, options):

Option Type Default Description
defaultId string required The 11-character YouTube video ID or full URL.
theme string "default" Theme preset name ("red", "cyan", "purple", "emerald", etc.).
autoplay boolean true Auto-start playback on ready.
loop boolean false Whether to auto-replay video upon reaching the end.
thumbnail boolean false Show YouTube thumbnail preview overlay prior to playback start.
pipMode "os" | "inpage" "os" Picture-in-Picture mode preference (OS desktop window vs in-tab mini-player).
Methods

Programmatic Methods

All player methods accept the target element ID as the first argument:

Method Signature Return Type Description
YVPlayer.play(targetId) void Starts or resumes video playback.
YVPlayer.pause(targetId) void Pauses current video playback.
YVPlayer.togglePlay(targetId) void Toggles between play and pause states.
YVPlayer.seekTo(targetId, seconds) void Seeks timeline directly to specified seconds.
YVPlayer.changeVideo(targetId, newVideoId) void Switches the video stream to another YouTube ID seamlessly.
YVPlayer.setTheme(targetId, hexColor, name) void Dynamically updates all theme custom properties and glows in real time.
YVPlayer.togglePiP(targetId) void Triggers Picture-in-Picture according to the active engine preference.
YVPlayer.setPipMode(targetId, mode) void Sets active PiP engine: "document", "os", or "inpage".
YVPlayer.setVolume(targetId, 0-100) void Sets player volume percentage.
YVPlayer.mute(targetId) / unMute(targetId) void Mutes or unmutes audio.
YVPlayer.setPlaybackRate(targetId, speed) void Adjusts playback speed rate (e.g. 0.5, 1.0, 1.5, 2.0).
YVPlayer.setLoop(targetId, boolean) void Enables or disables seamless video loop repeat and syncs player settings drawer.
YVPlayer.isLooping(targetId) boolean Returns whether the video is currently configured to loop continuously upon completion.
YVPlayer.destroy(targetId) void Completely tears down DOM, removes listeners, intervals, and cleans memory.
Lifecycle & Events

Events, State & Callbacks

Monitor player lifecycle transitions, real-time playback milestones, volume adjustments, and Picture-in-Picture handoffs using YVPlayer's unified event listener engine.

Playback State Constants

YVPlayer normalizes YouTube playback states into standard string identifiers and numeric constants accessible via YVPlayer.getState(videoTag):

Code State Constant Lifecycle Description Controls UI Appearance
-1 unstarted Player initialized with video metadata; waiting for play trigger. Large frosted center play button visible; poster thumbnail shown.
1 playing Video actively decoding and playing audio/video frames. Controls auto-fade after 3s; center pause icon on hover; seekbar glowing.
2 paused Playback halted by user, sleep timer, or window blur. Controls persistently visible; center play icon displayed.
3 buffering Network fetching stream chunks or seeking to a new timestamp. Smooth pulsating spinner displayed at the center of the video stage.
5 cued New video queued via changeVideo() ready for instant start. Timeline slider resets to 0:00; title badge updates.
0 ended Video completed playback without looping enabled. Replay glyph appears; end-screen recommendations completely stripped.

Subscribing to Events

Use YVPlayer.on(videoTag, eventName, handler) to listen for real-time player actions. Remove listeners via YVPlayer.off():

JavaScript — Event Subscription
// 1. Listen for playback start
YVPlayer.on("my-player", "play", () => {
  console.log("Playback started or resumed");
});

// 2. High-frequency timeline updates (every 250ms)
YVPlayer.on("my-player", "timeupdate", ({ currentTime, duration, progress }) => {
  console.log(`Current: ${currentTime.toFixed(1)}s / ${duration.toFixed(1)}s (${progress.toFixed(1)}%)`);
});

// 3. Picture-in-Picture mode activation
YVPlayer.on("my-player", "pipenter", ({ mode }) => {
  console.log(`Entered PiP mode: ${mode}`); // "document", "os", or "inpage"
});

// 4. Picture-in-Picture window closed
YVPlayer.on("my-player", "pipexit", () => {
  console.log("Returned to on-page player stage");
});

// 5. Volume or mute toggle
YVPlayer.on("my-player", "volumechange", ({ volume, isMuted }) => {
  console.log(`Volume: ${volume}%, Muted: ${isMuted}`);
});

// 6. Theme accent color change
YVPlayer.on("my-player", "themechange", ({ color, theme }) => {
  console.log(`Switched to theme ${theme} (${color})`);
});
Deep Dive

Dynamic Real-Time Theme Engine

YVPlayer features a GPU-accelerated CSS variable theming system. Switch branding accents, timeline gradients, glowing thumbs, and frosted overlays dynamically in real time without refreshing or reloading the video buffer.

CSS Custom Property Design Tokens

Every visual component inherits from standard scoped CSS custom properties applied directly to the .yvPlayer container:

CSS Variable Token Default Value Target Component & Computed Effect
--themeAccent #fe0001 Primary brand accent applied to active buttons, volume pills, and hover badges.
--sliderSeekTrackColor var(--themeAccent) High-contrast fill color for the completed portion of the scrubbing timeline.
--sliderThumbColor var(--themeAccent) Color of the glowing seek thumb handle.
--themeGlow rgba(r, g, b, 0.45) Luminescent drop-shadow filter applied to the seekbar head and primary play button.
--themeHoverBg rgba(r, g, b, 0.22) Translucent background tint applied to icon button hover rings.
--startBtnBg var(--themeAccent) Backdrop tint for the initial center frosted play button.

Built-In Preset Color Palettes

YVPlayer ships with 6 hand-tuned production presets engineered for perfect contrast across dark and light canvases:

Preset Name Key Hex Code RGB Glow Token Best Used For
● Classic Cinema Red red #fe0001 rgba(254, 0, 1, 0.45) YouTube-native aesthetic, action cinema, bold branding.
● City Cyan cyan #00e5ff rgba(0, 229, 255, 0.45) Modern SaaS applications, dark mode dashboards, fintech.
● Fantasy Purple purple #a855f7 rgba(168, 85, 247, 0.45) AI platforms, creative portfolios, Web3 and gaming streams.
● Forest Emerald emerald #10b981 rgba(16, 185, 129, 0.45) Nature docs, educational courses, calm productivity tools.
● Amber Gold gold #f59e0b rgba(245, 158, 11, 0.45) Luxury brands, podcasts, retrospectives, warm cinematics.
● Minimal Monochrome white #ffffff rgba(255, 255, 255, 0.45) Clean architectural sites, typography-first portfolios, editorial.

Applying Themes at Runtime

Switch themes via HTML data attributes or programmatically via the JavaScript API with zero latency:

JavaScript & HTML — Dynamic Theming
<!-- 1. Declarative HTML preset theme -->
<div class="yvPlayer" id="player" data-yv-theme="purple"></div>

<!-- 2. Arbitrary Custom Brand Hex via HTML -->
<div class="yvPlayer" id="brand-player" data-yv-color="#8b5cf6"></div>

<!-- 3. Programmatic runtime theme switch (zero video interruption) -->
<script>
  // Switch to preset theme
  YVPlayer.setTheme("player", "emerald");

  // Or apply any custom 6-digit hex color
  YVPlayer.setTheme("player", "#ec4899", "Neon Pink");
</script>
Deep Dive

Triple-Engine Picture-in-Picture (PiP) Architecture

Unlike ordinary video players that restrict users to basic OS video windows without controls, YVPlayer provides three distinct, independent Picture-in-Picture architectures engineered for every browser capability, operating system, and deployment workflow.

Architecture Highlights: Document PiP pops out the complete interactive HTML DOM (with scrubbing thumbnails and themes) into an OS desktop window; Native Video PiP provides hardware-accelerated 720p streaming with live subtitles and OS media keys; and In-Page Dock delivers 100% universal compatibility with 4-corner aspect-locked resizing.
ENGINE A — MODERN W3C STANDARD

Document Picture-in-Picture (Full Desktop OS Window)

Chrome 116+ — Edge 116+ — Opera data-yv-pip="document"

Pops out the entire rich YVPlayer DOM into an independent, always-on-top desktop operating system window using window.documentPictureInPicture.requestWindow(). All custom controls, storyboard scrubbing, audio sliders, and theme accents continue running smoothly outside the browser tab.

100% Custom UI & Theming Preserved Custom seekbar track, glowing thumbs, volume pills, sleep countdown badge, and storyboard preview tooltips render natively inside the floating window.
Zero-Crop Letterboxing & Aspect Guard Preserves 100% of the video canvas with zero cropping. When resized to non-16:9 aspect ratios, cinema-grade letterboxing and pillarboxing with pure black borders automatically adapt to any window dimensions.
State Handoff & Zero-Frame Snap Return The host webpage displays an elegant frosted "Playing in OS Window" placeholder with a single-click return button. Closing the OS window instantly snaps video playback back into the webpage with zero dropped frames.
Zero Proxy Requirement Document PiP operates directly on the client DOM without requiring a backend stream proxy or serverless workers.
JavaScript & HTML — Document PiP Integration
<!-- HTML: Set Document PiP as preferred mode -->
<div class="yvPlayer" id="my-player" data-yv-pip="document"></div>

<!-- JavaScript: Programmatically trigger Document PiP -->
<script>
  YVPlayer.setPipMode("my-player", "document");
  YVPlayer.enterPiP("my-player");
</script>
ENGINE B — 720P DIRECT STREAM

Native Hardware Video PiP (Hardware OS Streaming)

Universal Desktop OS — Chrome, Edge, Safari, Firefox data-yv-pip="os"

Leverages the W3C standard HTMLVideoElement.requestPictureInPicture() specification by streaming clean, direct 720p HD MP4 (YouTube Format 22) through the Cloudflare Worker or Python edge proxy. Delivers full OS-level hardware-accelerated playback with native operating system controls.

Live WebVTT Subtitle Shipping Dynamically injects timed VTTCue objects into the native video element's TextTrack. Captions render crisp, clean subtitles directly inside the floating OS Picture-in-Picture window.
Synchronized Host Stage Control Bar While playing in the floating OS window, the main on-page player remains fully synchronized with an interactive scrubber bar, time counter, volume slider, and "Exit picture-in-picture" pill.
Unmuted Volume & OS Media Keys Audio streams unmuted by default with smooth OS volume slider integration, keyboard shortcuts (↑, ↓, M), and hardware media play/pause keys.
Edge Stream Proxy Integration Connects seamlessly with the bundled serverless Cloudflare Worker or self-hosted Python proxy with automatic format resolution and in-memory URL caching.
JavaScript & HTML — Native Video PiP Integration
<!-- HTML: Configure Native Video PiP with proxy URL -->
<div class="yvPlayer" id="my-player" data-yv-pip="os" data-yv-proxy="https://my-worker.workers.dev"></div>

<!-- JavaScript: Toggle Native Hardware PiP -->
<script>
  YVPlayer.setPipMode("my-player", "os");
  YVPlayer.togglePiP("my-player");
</script>
ENGINE C — UNIVERSAL CLIENT OVERLAY

In-Page Dock Mini-Player (Corner Resizable)

100% All Modern Browsers & Mobile data-yv-pip="inpage"

A fluid, corner-docked viewport overlay confined within the active browser tab with physical spring animations. Operates purely on client DOM with zero proxy or external network requirements.

Connected 4-Corner Interactive Resize Grab any corner handle (TL, TR, BL, BR) to resize smoothly. Mathematical aspect locking enforces exact 16:9 widescreen geometry continuously during resize gestures.
Quadrant Drag & Snap Animations Drag the mini-player across the page. Upon release, physics-based springs snap the player into the nearest corner quadrant (Top-Left, Top-Right, Bottom-Left, Bottom-Right).
Zero Proxy or Server Dependencies Operates directly on the embedded iframe and custom DOM overlay. Works in strict corporate intranets, air-gapped systems, and mobile web views.
Universal Cross-Browser Fallback Automatically serves as the graceful fallback when Document PiP or native video streaming is unavailable in older browser builds.
JavaScript & HTML — In-Page Dock Integration
<!-- HTML: Configure In-Page Dock mode -->
<div class="yvPlayer" id="my-player" data-yv-pip="inpage"></div>

<!-- JavaScript: Activate In-Page Dock Mini-Player -->
<script>
  YVPlayer.setPipMode("my-player", "inpage");
  YVPlayer.togglePiP("my-player");
</script>

Comprehensive PiP Engine Comparison

Feature / Capability Engine A — Document PiP Engine B — Native Video PiP Engine C — In-Page Dock
Operating System Floating Window Yes (Independent OS Window) Yes (Hardware OS Surface) Tab Viewport Dock Only
Full Custom UI & Theming Preserved Complete DOM Preserved On-Page Stage Synced Complete DOM Preserved
Live Subtitles in Floating Window Styled HTML Subtitles Native WebVTT Cues Injected Styled HTML Subtitles
16:9 Aspect Ratio Enforcement Dynamic JS Guard Native OS Surface Lock 4-Corner Math Calculation
Scrubbing & Timeline Preview Storyboard Tooltip Inside Window Scrubber on Main Stage Storyboard Tooltip on Hover
Backend Stream Proxy Required No (Direct DOM) Yes (Cloudflare or Python) No (Direct DOM)
Browser & Device Compatibility Chrome 116+, Edge 116+, Opera Universal Desktop OS (Safari, Firefox, Chrome, Edge) 100% All Modern Browsers, Tablets & Mobile
Deep Dive

Frame-Accurate Storyboard Scrubbing

YVPlayer extracts YouTube timeline mosaic sheets to deliver instant, zero-latency visual thumbnail previews on hover without downloading video frames or consuming heavy streaming bandwidth.

How YouTube Storyboards Work

YouTube encodes video previews into compressed JPEG mosaic sheets (e.g. 5x5 or 10x10 grids of frames captured at strict intervals like every 2 or 5 seconds). YVPlayer parses the video's storyboard_spec, computes the precise row and column coordinate for any cursor position along the timeline, and positions the preview via CSS background offsets:

Mosaic Variable Standard Value Mathematical Role in Sprite Calculations
cols ($N_{\text{cols}}$) 5 (or 10) Number of horizontal frame tiles across a single JPEG sheet.
rows ($N_{\text{rows}}$) 5 (or 10) Number of vertical frame tiles down a single JPEG sheet.
width ($W$) 160px Exact pixel width of each individual 16:9 thumbnail frame tile.
height ($H$) 90px Exact pixel height of each individual 16:9 thumbnail frame tile.
interval ($\Delta t$) 2.0s (or 5.0s) Seconds of video playback represented between consecutive thumbnail frames.

Sprite Coordinate Math & Offset Formula

Given total duration $D$, cursor hover ratio $R \in [0, 1]$, and hover timestamp $T = R \times D$:

Mathematical Algorithm — Background Position Offset
// 1. Calculate overall tile index
const tileIndex = Math.floor(hoverTime / interval);
const tilesPerSheet = cols * rows;

// 2. Determine target mosaic sheet number
const sheetIndex = Math.floor(tileIndex / tilesPerSheet);

// 3. Determine exact column and row coordinates
const indexInSheet = tileIndex % tilesPerSheet;
const col = indexInSheet % cols;
const row = Math.floor(indexInSheet / cols);

// 4. Apply CSS background position offset
tooltipImg.style.backgroundImage = `url(${sheetUrl.replace("$M", sheetIndex)})`;
tooltipImg.style.backgroundPosition = `-${col * tileWidth}px -${row * tileHeight}px`;

Boundary Edge Clamping

To prevent the hover tooltip from clipping past the left or right edge of the video stage, YVPlayer implements sub-pixel boundary clamping:

Boundary Clamping Algorithm
// Keep tooltip center point strictly within [halfTooltip, stageWidth - halfTooltip]
const halfTooltip = tooltipWidth / 2;
const clampedX = Math.max(halfTooltip, Math.min(cursorX, stageWidth - halfTooltip));
Deep Dive

Subtitle Styling & WebVTT Engine

Extract, style, and ship YouTube captions into both the HTML5 stage overlay and native OS Picture-in-Picture windows with full control over typography, backing modes, opacity, and languages.

Subtitle Display Modes

Configure caption rendering through the player's built-in Settings Drawer () or programmatically:

Backing Mode CSS Implementation Visual Result
Frosted Box (Default) background: rgba(0,0,0,0.75); backdrop-filter: blur(8px); border-radius: 6px; Modern cinema aesthetic with high contrast across busy backgrounds.
Solid Opaque Box background: #000000; color: #ffffff; border-radius: 4px; padding: 4px 10px; Maximum legibility and strict accessibility compliance.
Drop-Shadow Outline (No Box) text-shadow: 0 2px 4px rgba(0,0,0,0.9), 0 0 2px #000000; Clean broadcast styling without any obstructive background card.

Shipping Subtitles into OS Picture-in-Picture

Standard browser Picture-in-Picture windows do not render HTML DOM elements. To display subtitles inside the floating OS window during Native Video PiP playback, YVPlayer bridges HTML captions to native VTTCue objects:

JavaScript — Dynamic WebVTT Cue Shipping
// 1. Create native text track on hidden video element
const textTrack = nativeVideo.addTextTrack("subtitles", "English", "en");
textTrack.mode = "showing";

// 2. Parse YouTube timed text and inject VTTCue objects
captionsArray.forEach(cap => {
  const cue = new VTTCue(cap.start, cap.end, cap.text);
  cue.line = -2; // Clean placement near the bottom
  cue.size = 80;
  textTrack.addCue(cue);
});
Deep Dive

Tactile Gestures & Keyboard Hotkeys

YVPlayer provides a complete set of desktop keyboard shortcuts and mobile touch gestures engineered for muscle memory and rapid media scrubbing.

Complete Desktop Hotkey Reference

Key / Shortcut Action Description HUD Feedback Pill
Space or K Toggle Play / Pause playback. Center circle morphs with micro-animation.
J / L Instant 10-Second Rewind (J) or Fast-Forward (L). Curved tactile ripple badge with ±10s indicator.
← / → Precise 5-Second Seek Backward / Forward. Seekbar thumb glowing jump animation.
↑ / ↓ Volume Increase / Decrease by 5%. Volume percentage HUD pill floats near top-right.
M Toggle Mute / Unmute audio. Volume icon toggles between muted and active.
F Toggle Fullscreen Mode. Canvas expands to fill 100% monitor resolution.
P Toggle Picture-in-Picture (active engine). Pops out into OS window or In-Page dock.
C Toggle Captions / Subtitles. Subtitle line fades in/out with smooth opacity.
0 – 9 Direct Jump to 0% through 90% of duration. Instant timeline seek.
< / > Decrease / Increase playback speed (0.25x – 2.0x). Speed badge indicator (e.g. 1.25x, 1.5x, 2x).
Cmd+E / Ctrl+E Open Quick Embed Code Customizer Modal. Modal backdrop fades in smoothly.

Mobile & Touch Ripple Gestures

On touch devices or laptops, double-tapping the left half of the player triggers a 10s rewind ripple; double-tapping the right half triggers a 10s fast-forward ripple. Both gestures feature GPU-accelerated spring animations.

Deep Dive

YouTube Shorts Mode (9:16 Vertical Aspect Ratio)

Standard embedded YouTube videos force a 16:9 widescreen letterbox even when playing vertical shorts. YVPlayer provides native 9:16 mobile-first vertical aspect ratio support. It automatically crops YouTube's horizontal letterboxing, optimizes the layout for vertical viewing, and strips away UI clutter while preserving essential controls.

Streamlined Shorts Controls Architecture

In Shorts mode, the player hides redundant horizontal desktop chrome and keeps only the controls essential for short-form video:

  • Timeline Scrubber: Ultra-responsive seekbar at the bottom for instant scrubbing across the short.
  • Volume & Mute Pill: Quick toggle and volume slider without opening menus.
  • Picture-in-Picture (PiP): Send the vertical Short into OS-level floating PiP or in-page mini player.
  • Full Screen: Maximize to immersive full-device vertical display.
  • Settings Button: Opens the full settings drawer with Playback Speed (0.25x - 2x), Subtitle Styles, Theme Accents, and Sleep Timer.
HTML Drop-In
<!-- Drop-in vertical YouTube Short with 9:16 aspect ratio -->
<div
  data-yv-video="https://www.youtube.com/shorts/YlyI2jmHEYc"
  data-yv-shorts="true"
  data-yv-theme="red"
  style="width: 100%; max-width: 400px; aspect-ratio: 9 / 16; margin: 0 auto; border-radius: 20px; overflow: hidden;"
></div>
JavaScript API
YVPlayer.init("shorts-player", {
  defaultId: "YlyI2jmHEYc", // YouTube Short Video ID
  shorts: true,             // Enables 9:16 vertical ratio & streamlined controls
  theme: "red",
  autoplay: true
});

// Runtime toggle
YVPlayer.setShortsMode("shorts-player", true);
Deep Dive

Ambient Background Play ("Muted, Looping Video Behind Your Content")

Similar to Video.js's ambient background video engine, YVPlayer allows you to transform any YouTube video into a muted, looping decorative background that plays seamlessly behind hero sections, banners, headers, or landing page content.

Zero-Interference Background Architecture

When background mode is enabled, YVPlayer automatically configures:

  • Permanently Muted: Unconditionally mutes audio (muted: true) to guarantee instant, unrestricted browser autoplay on mobile and desktop without user gestures.
  • Infinite Seamless Loop: Continuously restarts the video prior to reaching the final 0.2 seconds, preventing YouTube's native end-screen cards, channel suggestions, and replay overlays from ever displaying.
  • 100% Zero Controls: Strips away the play button, progress bar, volume pill, HUD notices, keyboard shortcut listeners, and right-click menus.
  • Full Pointer-Events Pass-Through: Sets pointer-events: none so user clicks, text selection, and touch gestures effortlessly pass straight through to your foreground buttons, forms, and cards.
HTML & CSS Layering Pattern
<!-- Hero Section with Ambient Video Background -->
<div class="hero-container" style="position: relative; overflow: hidden; min-height: 480px;">
  
  <!-- 1. Ambient Video Layer (Zero controls, automated loop) -->
  <div 
    data-yv-video="aqz-KE-bpKQ" 
    data-yv-background="true"
    style="position: absolute; inset: 0; width: 100%; height: 100%; z-index: 1; pointer-events: none; opacity: 0.65;"
  ></div>

  <!-- 2. Optional Tint / Scrim Layer -->
  <div style="position: absolute; inset: 0; background: rgba(0,0,0,0.45); z-index: 2;"></div>

  <!-- 3. Your Foreground Content (Interactive buttons, headings, text) -->
  <div class="hero-content" style="position: relative; z-index: 3; padding: 60px 24px; text-align: center;">
    <h1>Welcome to Next-Gen Web Video</h1>
    <p>High-performance HTML5 video player built for modern developer workflows.</p>
    <button class="btn-primary">Get Started Now</button>
  </div>

</div>
JavaScript API
YVPlayer.init("hero-bg-player", {
  defaultId: "aqz-KE-bpKQ",
  background: true, // Enables muted, looping, zero controls ambient mode
  autoplay: true
});

// Runtime toggle
YVPlayer.setBackgroundMode("hero-bg-player", true); // Enable ambient background
YVPlayer.setBackgroundMode("hero-bg-player", false); // Restore interactive controls
Deployment

Cloudflare Worker Proxy (Serverless)

Deploy your stream resolver on Cloudflare Workers for global edge delivery with $0 server maintenance costs and ultra-low latency. Below is the complete production script:

JavaScript — worker.js (Cloudflare Workers)
// ============================================================
// Cloudflare Worker: YouTube Stream & Storyboard Edge Proxy
// ============================================================
export default {
  async fetch(request, env, ctx) {
    const url = new URL(request.url);

    // Handle CORS preflight
    if (request.method === "OPTIONS") {
      return new Response(null, {
        headers: {
          "Access-Control-Allow-Origin": "*",
          "Access-Control-Allow-Methods": "GET, HEAD, OPTIONS",
          "Access-Control-Allow-Headers": "Range, Content-Type",
          "Access-Control-Max-Age": "86400"
        }
      });
    }

    const videoId = url.searchParams.get("id");
    if (!videoId || !/^[a-zA-Z0-9_-]{11}$/.test(videoId)) {
      return new Response(JSON.stringify({ success: false, error: "Invalid video ID" }), {
        status: 400,
        headers: { "Content-Type": "application/json", "Access-Control-Allow-Origin": "*" }
      });
    }

    // Proxy Range requests to raw YouTube streams
    if (url.pathname === "/api/stream") {
      const clientRange = request.headers.get("Range");
      const headers = new Headers({
        "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) Chrome/147.0.0.0 Safari/537.36"
      });
      if (clientRange) headers.set("Range", clientRange);

      const upstream = await fetch(streamUrl, { headers });
      const respHeaders = new Headers(upstream.headers);
      respHeaders.set("Access-Control-Allow-Origin", "*");
      return new Response(upstream.body, { status: upstream.status, headers: respHeaders });
    }
  }
};
Streaming Infrastructure

Open-Source Stream Proxies (Zero Backend Required)

When integrating YVPlayer into static Jamstack apps, client-only SPAs, or serverless projects where running a dedicated Python yt-dlp backend is undesirable, you can configure open-source community stream proxy networks.

100% Free & Decentralized Leverage globally distributed, community-hosted proxy instances with zero cloud hosting bills or VPS management.
No Tracking & No Cookies Direct requests to Google CDN (googlevideo.com) without telemetry, tracking cookies, or user profile linkage.
Automatic Failover YVPlayer automatically cycles through healthy secondary community instances if the primary instance encounters rate limits.

1. Piped API Network (Recommended)

Piped is an open-source privacy frontend for YouTube. Its public API clusters decrypt YouTube video ciphers on the fly and return clean JSON payloads containing direct Google CDN streaming URLs.

  • Endpoint Format: GET https://<instance>/streams/{VIDEO_ID}
  • Live Instance Discovery: piped-instances.kavin.rocks (Real-time uptime tracker)
  • Default Public Node: https://pipedapi.kavin.rocks
  • Fallback Public Node: https://api.piped.privacy.com.de
JavaScript — Initializing with Piped Stream Proxy
YVPlayer.init("video-stage", {
  defaultId: "M7lc1UVf-VE",
  proxyProvider: "piped",
  pipedInstance: "https://pipedapi.kavin.rocks", // Optional custom instance
  pipMode: "dual"
});

2. Invidious API Network

Invidious is a Crystal-based open-source YouTube alternative. Its API exposes pre-muxed combined MP4 video+audio streams via the formatStreams array.

  • Endpoint Format: GET https://<instance>/api/v1/videos/{VIDEO_ID}
  • Official Instances List: instances.invidious.io
  • Default Public Node: https://inv.tux.pizza
  • Fallback Public Node: https://vid.puffyan.us
JavaScript — Initializing with Invidious Stream Proxy
YVPlayer.init("video-stage", {
  defaultId: "M7lc1UVf-VE",
  proxyProvider: "invidious",
  invidiousInstance: "https://inv.tux.pizza"
});

3. Cobalt API

Cobalt is a high-speed media processing engine built specifically to return single, direct streaming links without third-party adverts or tracking cookies.

  • Endpoint Format: POST https://api.cobalt.tools/ (Body: {"url": "...", "videoQuality": "720"})
  • Official Endpoint: https://api.cobalt.tools
JavaScript — Initializing with Cobalt Stream API
YVPlayer.init("video-stage", {
  defaultId: "M7lc1UVf-VE",
  proxyProvider: "cobalt",
  cobaltInstance: "https://api.cobalt.tools"
});

Architecture Comparison Matrix

Proxy Option Backend Required Resolution Speed Direct Stream Format Monthly Cost Best Suited For
Piped API Zero (Community CDN) Fast (~180ms) 720p / 1080p MP4 $0 Production SPAs, Next.js, and static websites.
Invidious API Zero (Community CDN) Moderate (~280ms) 720p / 360p Pre-Muxed MP4 $0 Decentralized and privacy-strict web apps.
Cobalt API Zero (Community CDN) Ultra-Fast (~120ms) 720p HD Direct MP4 $0 Clean single-link video playback and embeds.
Self-Hosted yt-dlp Python 3.10+ (demo/server.py) Near-Instant (Cached) Adaptive 1080p / 720p $0 (Local) / VPS Enterprise intranets and full custom backend control.
Cloudflare Worker Serverless Edge (worker.js) Edge Cached (~40ms) Direct 206 Byte Ranges $0 (100k req/day free) High-scale global edge architectures.
Deployment

Self-Hosted Python Stream Proxy

Deploy your own lightweight, zero-maintenance HTTP stream proxy on Linux, macOS, or Windows using Python and yt-dlp with built-in in-memory caching and HTTP 206 Partial Content range support.

Architecture & Features

The included demo/server.py is a hardened, multi-threaded HTTP server engineered specifically for direct 720p stream resolution and instant seeking:

Multi-Threaded HTTP Server Built on Python's ThreadingHTTPServer to serve concurrent video streams and static assets without request blocking.
HTTP 206 Partial Content Range Support Proxies byte ranges (bytes=start-end) directly to upstream CDNs, enabling smooth timeline scrub seeking in Native Video PiP.
In-Memory URL Cache with TTL Caches direct CDN stream URLs with automatic expiration, eliminating redundant yt-dlp extraction calls for frequently requested videos.
Regex Validation & Injection Protection Strictly validates video IDs against ^[a-zA-Z0-9_-]{11}$ to prevent command injection and SSRF exploits.

Running Locally or in Production

Start the server with Python 3.10+ and yt-dlp installed:

Terminal — Running the Proxy
# 1. Install yt-dlp dependency
pip install yt-dlp

# 2. Launch the multi-threaded proxy server
python demo/server.py

Production Systemd Service

For permanent 24/7 deployment on Ubuntu or Debian servers, create a systemd service file at /etc/systemd/system/yvplayer.service:

Systemd Service — /etc/systemd/system/yvplayer.service
[Unit]
Description=YVPlayer Stream Proxy & Demo Server
After=network.target

[Service]
Type=simple
User=www-data
WorkingDirectory=/var/www/yvplayer
ExecStart=/usr/bin/python3 demo/server.py
Restart=always
RestartSec=3
Environment=PORT=3000

[Install]
WantedBy=multi-user.target
Security

Security, XSS Defense & CSP Guidelines

YVPlayer follows strict defensive design patterns to guarantee safety when embedding in multi-tenant or enterprise environments:

Strict Video ID Validation: All entry points validate IDs against ^[a-zA-Z0-9_-]{11}$ to prevent command flag injection, path traversal, or SSRF attacks.
XSS-Proof Caption Rendering: Captions are injected via .textContent rather than innerHTML, ensuring external WebVTT/SRT text cannot execute arbitrary script payloads.
Strict postMessage Target Origin: All communication to YouTube iframes specifies "https://www.youtube.com" as the target origin rather than wildcard "*".
Recommended Content Security Policy (CSP):
default-src 'self'; script-src 'self' https://www.youtube.com https://cdn.jsdelivr.net; frame-src https://www.youtube.com; media-src 'self' blob:; style-src 'self' 'unsafe-inline' https://cdn.jsdelivr.net https://fonts.googleapis.com; font-src https://cdn.jsdelivr.net https://fonts.gstatic.com;