benwiley4000 / cassette

📼 A flexible media player component library for React that requires no up-front config
https://benwiley4000.github.io/cassette/styleguide
MIT License
185 stars 28 forks source link

Render video with video element instead of canvas mirror #313

Closed benwiley4000 closed 5 years ago

benwiley4000 commented 5 years ago

In #213 we started using canvas to display the video. The advantage of this approach is that it lends well to the declarative approach of React. It becomes simpler to display a rendering of the video wherever we want without worrying about where the video element itself lives.

Unfortunately this has some bad performance implications (which led to #306). Older browsers and phones don't do well with this; either the video renders extremely slowly freezing the page, or we don't see the video at all (in Edge; this might have to do with requestAnimationFrame being processed after the render instead of before).

So the new approach will be to use the actual video element that playback is coming from, but any rendered VideoDisplay will be able to request that the video element itself is moved into its container for display. The mechanics of how this works under the hood are a bit complicated and the refactor is a bit significant. It will also mean breaking API changes in the next alpha release. Here is an outline of the work required:

  1. Remove hidden attribute from video element itself - add that to the div container
  2. in componentDidUpdate we should update sources
  3. The context should expose two new functions: -- renderVideoIntoContainer: Adds specified DOM element as an available container element for the video -- unregisterVideoContainer: Removes specified DOM elemeent from the list of available container elements for the video :: At the end of each of these metehods, we should find the most recently added available container element and move the video element into this parent if it's not there already :: If the list is empty, we render into a hidden element inside the PlayerContextProvider component :: We should render into that hidden element after first mount if the list is empty :: These are used in the VideoDisplay class and shouldn't be used directly in the general case
  4. Figure out what to do with each of the props that have been available on VideoDisplay pipeVideoStreamToCanvas: replaced in favor of new functions playlist: no longer needed activeTrackIndex: no longer needed fullscreen: kept processFrame: no longer applicable imageResolutionX: no longer applicable imageResolutionY: no longer applicable scaleForDevicePixelRatio: no longer applicable aspectRatio: kept, but enforcing this will be a bit different maybe? getPlaceholderImageForTrack: maybe this should be moved to the PlayerContextProvider shouldProcessPlaceholderImages: no longer applicable maintainAspectRatioInFullscreen: kept

    So to summarize: renderVideoIntoContainer: new unregisterVideoContainer: new fullscreen: kept aspectRatio: kept, but enforcing this will be a bit different maybe? maintainAspectRatioInFullscreen: kept

    To move: getPlaceholderImageForTrack (should be "poster" not "placeholder")

  5. Update examples and example helpers in docs to work with updated API.
  6. Videos in docs should be updated to display placeholder content when the video is playing elsewhere. This should be done via a prop made available to the VideoDisplay component.