xHamster Mobile HTML5 Player

Replace xHamster’s custom player with native HTML5 video and auto-select highest quality stream.

2025-08-22 يوللانغان نەشرى. ئەڭ يېڭى نەشرىنى كۆرۈش.

// ==UserScript==
// @name         xHamster Mobile HTML5 Player
// @namespace    https://xhamster-html5
// @version      1.1
// @description  Replace xHamster’s custom player with native HTML5 video and auto-select highest quality stream.
// @match        *://xhamster.com/*
// @match        *://*.xhamster.com/*
// @grant        none
// @run-at       document-end
// @license MIT
// ==/UserScript==

(function() {
  'use strict';

  function replaceWithHTML5() {
    // Find original video
    const video = document.querySelector('video');
    if (!video) return;

    // Collect available sources
    const sources = Array.from(video.querySelectorAll('source')).map(s => ({
      src: s.src,
      res: parseInt((s.getAttribute('res') || s.src.match(/(\d{3,4})p/) || [])[1] || 0, 10)
    })).filter(s => s.src);

    // Pick the highest resolution
    let best = null;
    if (sources.length) {
      best = sources.sort((a, b) => b.res - a.res)[0];
    } else {
      // fallback: just use current src
      best = { src: video.currentSrc || video.src, res: 0 };
    }

    if (!best || !best.src) return;

    // Build new HTML5 player
    const newPlayer = document.createElement('video');
    newPlayer.src = best.src;
    newPlayer.controls = true;
    newPlayer.autoplay = false;
    newPlayer.style.width = "100%";
    newPlayer.style.maxHeight = "80vh";

    // Replace wrapper
    const wrapper = video.closest('.player, .video-player, .xh-video, .video-js') || video;
    wrapper.parentNode.replaceChild(newPlayer, wrapper);

    console.log(`[xHamster++] Replaced with HTML5 video @ ${best.res || "default"}p:`, best.src);
  }

  // Observe DOM for when player loads
  const mo = new MutationObserver(replaceWithHTML5);
  mo.observe(document.body, { childList: true, subtree: true });

  // Try immediately too
  replaceWithHTML5();
})();