title: Controlling MP4 Playback using javascript
body: <p>I am trying to clone the following site:</p>
  
  <p><a href="https://www.apple.com/mac-pro/" rel="nofollow noreferrer">https://www.apple.com/mac-pro/</a></p>
  
  <p>I am still in the prototyping phase and the big ticket item I am trying to figure out is how they are playing their MP4 file backwards when you scroll up the page.  If you scroll down the page a few steps and then back up, you will see what I mean.</p>
  
  <p>So far I have tried the following techniques:</p>
  
  <ul>
  <li>Tweening currentTime property of video element</li>
  <li>Using requestAnimationFrame and using the timestamp in the callback to update the currentTime property to the desired value</li>
  </ul>
  
  <p>Using the requestAnimationFrame technique, I am now getting a partially usable result in every browser other than Chrome.  Chrome is ok if you want to rewind maybe .5 seconds, but any more than that and it will get jumpy.</p>
  
  <p>I have also made the following discoveries:</p>
  
  <ul>
  <li>Chrome hates trying to rewind an MP4 file</li>
  <li>As much as Chrome hates rewinding MP4 files, also make sure that you don't have an audio track on your video file.  It will make it even slower.</li>
  </ul>
  
  <p>So I feel I have a pretty good understanding of the options available to me, but the one thing that makes me think I am missing something is that the Apple website functions ok in Chrome.  </p>
  
  <p>I have started debugging their code which is located at:</p>
  
  <p><a href="https://images.apple.com/v/mac-pro/home/b/scripts/overview.js" rel="nofollow noreferrer">https://images.apple.com/v/mac-pro/home/b/scripts/overview.js</a></p>
  
  <p>And from what I can tell they seem to be using requestAnimationFrame, but I can't understand why they are getting a better result..  Does anyone have any ideas on how to achieve this effect?</p>
  
  <p>BTW - I understand that videos are not really meant to be played backwards and they will never play predictably backwards.  I have even had occasions on the Apple website where the rewinding can be jerky.   But they still have good 2-3 second rewind transitions and the result is definitely acceptable.</p>
  
  <p>Here is my relevant javascript and HTML so far.. </p>
  
  <pre><code>var envyVideo, currentVideoTrigger = 0,
      currentIndicator, startTime, vid, playTimestamp, playTo, playAmount, triggeredTime, rewindInterval;
  
  $(function() {
  
      vid = document.getElementById("envy-video");
  
      $("#play-button").click(function() {
          vid.play();
      });
  
      $("#rewind-button").click(function() {
          vid.pause();
          playTo = parseFloat($("#play-to-time").val());
          playAmount = playTo - vid.currentTime;
          triggeredTime = vid.currentTime;
          requestAnimationFrame(rewindToPointInTime);
      });
  
  });
  
  function rewindToPointInTime(timestamp) {
  
      if (!playTimestamp) playTimestamp = timestamp;
      var timeDifference = (timestamp - playTimestamp) / 1000;
      vid.currentTime = triggeredTime + (playAmount * (timeDifference / Math.abs(playAmount)));
  
      if (vid.currentTime &gt; playTo) {
          requestAnimationFrame(rewindToPointInTime);
      } else {
          playTimestamp = null;
          playAmount = null;
      }
  
  }
  
  
  
  &lt;!DOCTYPE html&gt;
  &lt;html lang="en"&gt;           
      &lt;head&gt;
          &lt;meta charset="UTF-8"&gt;
          &lt;title&gt;Rhino Envy&lt;/title&gt;
          &lt;script src="https://code.jquery.com/jquery-3.2.1.min.js" integrity="sha256-hwg4gsxgFZhOsEEamdOYGBf13FyQuiTwlAQgxVSNgt4=" crossorigin="anonymous"&gt;&lt;/script&gt;
          &lt;script src="./js/envy.js"&gt;&lt;/script&gt;
          &lt;link rel="stylesheet" href="./css/envy.css"&gt;
      &lt;/head&gt;
      &lt;body;
          &lt;div id="envy-video-container"&gt;
              &lt;video id="envy-video" src="./videos/prototype_animation.mp4"&gt;&lt;/video&gt;
          &lt;/div&gt;
          &lt;div id="video-controls"&gt;   
              &lt;p id="video-current-time"&gt;&lt;/p&gt;
              &lt;div class="video-control"&gt;&lt;button id="rewind-button"&gt;rewind to&lt;/button&gt;&lt;input type="text" id="play-to-time" placeholder="forward time" value="0"&gt;&lt;/div&gt;
              &lt;button id="play-button"&gt;play&lt;/button&gt;
          &lt;/div&gt;
          &lt;ul id="envy-steps"&gt;
              &lt;li id="envy-step-indicator-1"&gt;&lt;/li&gt;
              &lt;li id="envy-step-indicator-2"&gt;&lt;/li&gt;
              &lt;li id="envy-step-indicator-3"&gt;&lt;/li&gt;
          &lt;/ul&gt;
          &lt;section id="envy-full-range"&gt;
              &lt;div id="envy-1-door-link"&gt;&lt;/div&gt;
              &lt;div id="envy-2-door-link"&gt;&lt;/div&gt;
              &lt;div id="envy-3-door-link"&gt;&lt;/div&gt;
          &lt;/section&gt;
      &lt;/body&gt;
  &lt;/html&gt;
  </code></pre>