igrigorik / videospeed

HTML5 video speed controller (for Google Chrome)
https://chrome.google.com/webstore/detail/video-speed-controller/nffaoalbilbmmfgbnbgppjihopabppdk
MIT License
3.82k stars 544 forks source link

Extension causing videos on Hellosaurus website to disappear #979

Open cedricium opened 2 years ago

cedricium commented 2 years ago

Steps to Reproduce:

  1. Ensure "Video Speed Controller" is enabled
  2. Navigate to https://www.hellosaurus.com
  3. Scroll down until you get to the "Hellosaurus activates the multi-touch screen, camera…" section

Expected: Comparison slider shows two videos side by side. Actual: The two videos in the comparison slider are hidden/not displayed. Disabling this extension causes the page to work as expected.

xAdler commented 1 year ago

Investigation Results

The mentioned video is not completely hidden, but blinking erratically every 350 to 500 ms. Buckle up for a run through an async adventure.

How The Video is Structured

Hellosaurus uses two relatively placed and overlapping videos and a slider that is hiding the overflow of the other video to show a comparison.

The Underlying Issue

As the videos are positioned relative and the VSC Controller is also placed relative, it's inheriting it's styles. Especially the height: 100% property, which forces the video to be completely in the hidden overflow and therefore seem to not be rendered anymore. We have two possible solutions here:

  1. Dynamically wrap the VSC Controller in a <div style="position: absolute; top: 0px; left: 0px; width: 100%; height: 100%;"></div> to prevent inheriting styles. This could have major side-effects like preventing click propagation or interfering with positioning in some exotic players. The advantage here would be, that it's much more generic and could fix issues with a lot more sites, but at least it's only used in a handful of them, as we should only apply this fix, if the parent of the controller is also positioned relative.
  2. Fixate the height to a static value. This would only fix this issue, but the same problems could occur with many CSS styles, like width: 100%, and we would have to fixate a whole bunch of them or start an investigation for each.

I personally more tend to solution one, but can not provide much experience in the world of exotic player setups and therefore this decision should be up to the main maintainers of VSC.

The Blinking

So it should be clear by now, that the blinking is caused, by the VSC Controller hiding and showing periodically. So what are the reasons for that? Several actually, let's take a look:

  1. When the player moves in and out of the overflow, some Browser performance optimizations are restarting the video, firing off MutationOberservers and <video> events, meaning, that the controller is shown again and restarting the cycle.
  2. Hellosaurus honored us, by dedicating some code to us in index-15f810c74a6f04b2.js. We can crudely, for development purposes, fix that by running qsa = document.querySelectorAll; document.querySelectorAll = (...a) => a[0] != ".vsc-controller" ? qsa.bind(document)(...a) : [] in the console:
          window.setInterval((function() {
              document.querySelectorAll(".vsc-controller").forEach((function(e) {
                  return e.classList.add("vsc-hidden")
              }
              ))
          }
          ), 500)
  3. The videos are very short, just about 6 seconds and looping. Every loop is redisplaying the controller for a second, therefore restarting the blinking, even when we somehow escaped it. This is not necessarily an unintended behavior, but it would make sense to not show the controller on start for looping videos.
  4. If the controllers are shown on the start of the video and shortly after manually hidden using the shortcut, the controllers start to blink. This could also have many issues, in which I didn't look much further, but here are my ideas:
    1. Something with the timeout. It seems, that the controller is successfully hidden but immediately shown again. As the timeframe aligns well, the timeout might miss a check for vsc-manual.
    2. There are multiple videos on the site and multiple are in view at the same site. This could create some sort of race condition, as all controllers are shown, when just a single controller needs to be displayed. This could also mean that some timeout of a different controller is hiding all controllers
    3. The class vcs-show is not defined. I mean, this one is obvious, as it should be vsc-show after all, but man, did I often read over this typo and wondered, why it's not applying my changes. A typo that needs urgent fixing, fortunately, this can't break anything as vsc-show is also not defined! So that might be the issue aswell

The Next Steps

Please take a look and let me know if you still have open questions and of what you think of the proposed solutions. These are only tested prototypically but I'd be open to create a PR for the above issues. These are the things I would like to update:

  1. Dynamically wrap the VSC Controller in a absolutely positioned container, if necessary
  2. Rename vcs-show to vsc-show in all occurrences
  3. Only show the controller of a starting video, if it's not a looping one
  4. Look into, why the controller is blinking, when hidden manually. (Might already be fixed by Step 3)