Greasy Fork

Zoom and crop YouTube videos to fill screen height

Removes letterboxing by cropping the left and right edges off of full-screen YouTube videos and zooming to fill the screen height.

当前为 2019-01-04 提交的版本,查看 最新版本

// ==UserScript==
// @name Zoom and crop YouTube videos to fill screen height
// @version      0.2
// @description  Removes letterboxing by cropping the left and right edges off of full-screen YouTube videos and zooming to fill the screen height.
// @author       uxamend
// @namespace    Violentmonkey Scripts
// @match        https://www.youtube.com/watch
// @grant        none
// @run-at       document-idle
// @license      CC0-1.0
// @compatible   firefox version >=64 (older versions untested)
// @compatible   chrome version >=71 (older versions untested)
// ==/UserScript==

"use strict";

var debug_logging_on = false;
var debug_script_name = "Userscript: Zoom YouTube videos to fill screen height"

function debug_log(message) {
  if(debug_logging_on){
    console.log("[" + debug_script_name + "] " + message);
  }
}

// Define a mutation observer and callback to re-apply zoom when ads start and end.
function mo_callback(mutation_list, observer) {
  mutation_list.forEach((mutation) => {
    if(mutation.type == "childList"){
      set_zoom_to_screen_height_with_timeout();
    }
  });
}

var mo = new MutationObserver(mo_callback);


function set_zoom_to_screen_height() {
  if(document.fullscreenElement) {
    debug_log("Full-screen. Setting video zoom.");
    
    var videoStyle = document.getElementsByClassName("html5-main-video")[0].style;
    var w = window.innerWidth;
    var h = window.innerHeight;
    
    videoStyle.height = h+"px";
    videoStyle.top = "0px";
    
    // Let's assume it's worth cropping videos with aspect ratios as wide as 7w:h.
    // Using an odd multiple of w simplifies the 'left' calculation.
    // The excess width will simply fall outside of the screen area.
    videoStyle.width = (w*7)+"px";
    videoStyle.left = "-"+(w*3)+"px";
    
    // Since we're now in full-screen, we should observe when ads start or stop and
    // re-apply the zoom when they do.
    var ad_module = document.getElementsByClassName("ytp-ad-module")[0];
    mo.observe(ad_module, {"childList" : true});
    
  } else {
      debug_log("Not full-screen. Not setting zoom.");
      
      // Don't waste time detecting ads when we're not in fullscreen
      mo.disconnect();
  }
}


function set_zoom_to_screen_height_with_timeout() {
  // Timeout to minimise chance of a race condition against standard YouTube behaviour.
  // (Our function needs to run after the video has changed to standard full-screen size.)
  setTimeout(set_zoom_to_screen_height, 200);
}


function add_event_listener_for_zoom() {
  debug_log("Adding fullscreenchange event listener.")
  document.addEventListener(
    'fullscreenchange',
    function() {
      debug_log("Full-screen state changed.");
      set_zoom_to_screen_height_with_timeout();
    }
  );
}

add_event_listener_for_zoom();