2

Trying to implement a similar functionality that Apple's been using lately for the MacBook, iPhone and most lately MacBook Pro product page.

If you check out the MBP product page you'll notice that the screen and Touch Bar is animating when scrolling. That is infact a video.

I'm having troubles adopting this as the video seems to stutter alot. In my case there's 4 videos, if I cut it down to 1 video it'll work better, but still not 100%.

I'm curious what methods / tactics that can be applied here to make it flow better.

Will putting the video files as blobs make it better? Better to convert video to a series images work with that instead?

Demo.

The code in question here:

// select video element
var vid0 = document.getElementById('v0');
var vid1 = document.getElementById('v1');
var vid2 = document.getElementById('v2');
var vid3 = document.getElementById('v3');
var windowheight = $(window).height()-20;

var scrollpos = window.pageYOffset/400;
var targetscrollpos = scrollpos;
var accel = 0;

// ---- Values you can tweak: ----
var accelamount = 0.1; //How fast the video will try to catch up with the target position. 1 = instantaneous, 0 = do nothing.

// pause video on load
vid0.pause();
vid1.pause();
vid2.pause();
vid3.pause();

window.onscroll = function(){
  targetscrollpos = window.pageYOffset/400;
};


setInterval(function(){   
  scrollpos += (targetscrollpos - scrollpos)*accelamount;

  //update video playback
  vid0.currentTime = scrollpos;
  vid0.pause();

  vid1.currentTime = scrollpos;
  vid1.pause();

  vid2.currentTime = scrollpos;
  vid2.pause();

  vid3.currentTime = scrollpos;
  vid3.pause();

}, 40);
INT
  • 910
  • 4
  • 21
  • 45

1 Answers1

2

MP4/H.264 is not the best format for scrubbing - it's designed primarily for streamed forward linear playback. The Apple page do use some MP4 videos but, only for triggered linear playback when in view, not for scrubbing.

You can try other supported video formats (f.ex. OGV, webm) and provide those as first options through the order in a <sources>...</sources> section for your videos to see if they better support random playback - do note that the browser's caching strategy will affect lag and loading in any case. You can better control caching at a more low-level using the Media Source Extensions API.

It can also help to control the video using its visible portion inside the client window to trigger pause or play. This answer can get you started, and there is a new upcoming API called Intersection Observer API for things like this (a poly-fill exist).

Converting to sprite-sheets and/or JPEG stills is a viable option (Sony did this in at least one of their web presentations using scroll to scrub). You would of course need to give a little more attention to the loading strategy (think preload/buffering) so you have something to show as soon as possible rather than waiting to all frames to be loaded.

  • 2
    Very informative answer, thank you! I found a little script via npm that does what I want rather well. It also loads the videos into blobs. Setting the keyframe frame distance to `1` helps alot with being able to scrub. It does however increase the file size a little bit. I noticed that the fans will speed up alot (Safari is fine, Chrome and FX is not). Seeing as the demo I made (http://output.jsbin.com/lewizuyamo/1) only have 2 videos, and the end product would most likely have 5-6 videos. With this in mind do you think it's even possible to optimize to get around the fans speeding up? – INT Nov 30 '16 at 23:07
  • As it is now, I'm leaning towards JPEG stills (don't think sprites is viable as too large images will crash Safari on iOS). But that comes with a premium on the file size. I do wonder if it'll perform better than video regarding CPU load and fans speeding up.. – INT Nov 30 '16 at 23:08
  • @INT I doubt it as the video processing is quite heavy with this many elements - I would rely on visibility for this (only play when visible). You could do all sort of optimizations for the video to reduce the load (I gave some tips in [this answer](https://stackoverflow.com/questions/40359750/html5-video-and-canvas-cpu-optimization/40398424#40398424) - the most relevant parts are the two last ones). Safari probably integrates well with the sub-system to utilize hw decoding, chrome depends on ffmpeg- Loading it in as blob is great, it consumes more memory, but is instantly available. [...] –  Nov 30 '16 at 23:12
  • The keyframe distance will force decoding full frames which can be heavier than intermediate frames, but as you state the size will increase but you will get a better scrub as it does not need to scan for other full frames and recalculate to current frame. –  Nov 30 '16 at 23:14
  • 1
    @INT Personally I think I would go with JPEG sequences as well. There will be a little more waiting on the loading side due to number of requests (can be reduced with spritesheets with 2-4 images only, half the number of requests) but gives full control and instant updates. –  Nov 30 '16 at 23:16