Larger videos on desktop displays via Tampermonkey

I like how videos work on the iPhone app, but have found myself frustrated with the size of YouTube videos within LingQ lessons when using my desktop system on a full-size monitor. I find the videos are far too small when in the “overlay” mode.

I was frustrated enough that I created a very simple Tampermonkey script. All this does is inject a custom CSS style to override the width/height of a few fields to make the player more visible.

This does require Tampermonkey, and I’m just trying to share this briefly for anyone else who is comfortable enough with Tampermonkey to use it. If you are not familiar with Tampermonkey, there are other posts on the Internet and on this forum which can help. That being said, I’m not providing any support for this code and using it is purely at your own risk - if you cannot read and understand the code of what you’re installing, then I would advise you to not use this.

(That being said, the script is super small and pretty straightforward to those who know JavaScript. Take a look.)

Lastly, I am not planning on providing any support for this. Others can take it and improve on it as they like. If it breaks in the future due to changes in the LingQ web site, I will likely leave it to someone else to repair - again, I’m just trying to be nice and share a script that is helping me right now.

Without further ado, the script can be found on my GitHub: https://raw.githubusercontent.com/Vultaire/lingq_video_script/main/userscript.js

(Yes, it’s ultimately just a CSS tweak. Yes, there’s likely other plugins which can handle this without needing Tampermonkey, but I don’t really work in this space nowadays and so Tampermonkey was the thing I was the most comfortable with.)

Anyway, hope it helps someone. Cheers!

2 Likes

Bleh, I’ve already found a bug. It seems to work good on initially playing videos, but if you have the video player open, then go to sentence mode and play a sentence, then things get messed up.

I’ve burnt too much time tonight on this that I should have spent studying; I may try to fix this another night. If anyone is good with debugging CSS stuff, patches are welcome. :slight_smile:

1 Like

Added a quick patch. It’s working for me in sentence mode now.

1 Like

Lastly, a screenshot of what this does in case my explanation is unclear. It’s specifically making this particular window larger. You can also easily tweak the script to use a larger/smaller size if you prefer.

1 Like

Hi Vultaire, thanks for sharing and welcome to the forums.

This video box is something LingQ really should improve and frustrations with it have been posted a few times.

Using strictly CSS seems like a very simple way to fix this. There are a few things you should consider though (which can be achieved with CSS).
Not all users have the same screen size. setting a width of 600, height of 370 etc is great… for your case. Other users will need to adjust this for their own devices.

A more robust way would be to add some javascript which allows automatic resizing of the element. Code sample below is from Rooster Reader. You’re welcome to incorporate that into your tampermonkey script

Code Block
 //add a resize indicator to bottom right of the Youtube bar

//Style for the indicator
  const resizeStyle = document.createElement('style');
      resizeStyle.type = 'text/css';
      resizeStyle.innerHTML = `
          .resize-handle {
              width: 10px;
              height: 10px;
              background-color: #666;
              position: absolute;
              bottom: 0;
              right: 0;
              cursor: nwse-resize;
          }
      `;
      document.head.appendChild(resizeStyle);


 //Inject the resize indicator into the modal's HTML
  function injectResizeHandle() {
      const modal = document.querySelector(".modal-content"); //LingQ youtube element
      if (!modal) return;  // Exit if modal isn't found
  
      const handle = document.createElement('div');
      handle.className = 'resize-handle';
      modal.appendChild(handle);
  }


//basic element drag
 function addResizingFunctionality() {
      let isResizing = false;
      let lastDownX = 0;
      let lastDownY = 0;
  
      const modal = document.querySelector(".modal-content");
      if (!modal) return;  // Exit if modal isn't found
  
      const handle = document.querySelector(".resize-handle");
  
      handle.addEventListener('mousedown', function(e) {
          isResizing = true;
          lastDownX = e.clientX;
          lastDownY = e.clientY;
      });
  
      document.addEventListener('mousemove', function(e) {
          if (!isResizing) return;
  
          const offsetX = e.clientX - lastDownX;
          const offsetY = e.clientY - lastDownY;
          
          modal.style.width = (modal.offsetWidth + offsetX) + "px";
          modal.style.height = (modal.offsetHeight + offsetY) + "px";
          
          lastDownX = e.clientX;
          lastDownY = e.clientY;
      });
  
      document.addEventListener('mouseup', function() {
          isResizing = false;
          setVideoWrapperHeight();
      });
  }


//reset the height of the video after width changes, account for padding and offsets
  function setVideoWrapperHeight() {
      // Grab the modal-content element
      const modalContent = document.querySelector('.modal-content');
  
      // If the element exists
      if (modalContent) {
          // Get the computed style of the modal-content to account for any padding
          const style = window.getComputedStyle(modalContent);
  
          // Get the height of the header section
          const headerSection = modalContent.querySelector('.modal-section--head');
          const headerHeight = headerSection ? headerSection.offsetHeight : 0;
  
          // Calculate the height: modal height - header height - (top + bottom padding)
          const targetHeight = modalContent.offsetHeight - headerHeight - parseFloat(style.paddingTop) - parseFloat(style.paddingBottom);
  
          // Set the height to the video-wrapper
          const videoWrapper = modalContent.querySelector('.video-wrapper');
          if (videoWrapper) {
              videoWrapper.style.height = `${targetHeight}px`;
          }
      }
  }

 injectStyles(); 
 setVideoWrapperHeight();
 injectResizeHandle(); 
 addResizingFunctionality(); 

image

1 Like

I’m in agreement that ideally a resizeable window would be nicer - but I’m explicitly trying not to spend too much time on this. Putting the video size in variables was intentional to allow others to quickly rweak the script without having to inject JS and deal with other potentially fragile/finicky bits of the UI which doesn’t expect this type of tweaking.

Patches are welcome though! :slight_smile:

1 Like

I’ll also look into Rooster Reader for my own usage - thank you!

1 Like