使用javascript

时间:2017-05-09 02:33:59

标签: javascript mp4

我正在尝试克隆以下网站:

https://www.apple.com/mac-pro/

我仍然处于原型制作阶段,我想弄清楚的是,当你向上滚动页面时,他们是如何向后播放MP4文件的。如果您向下滚动页面几步然后再备份,您将看到我的意思。

到目前为止,我尝试了以下技术:

  • 补间视频元素的currentTime属性
  • 使用requestAnimationFrame并使用回调中的时间戳将currentTime属性更新为所需的值

使用requestAnimationFrame技术,我现在可以在Chrome以外的每个浏览器中获得部分可用的结果。如果你想倒回0.5秒,Chrome就可以了,但不止于此,它会变得很激动。

我也做了以下发现:

  • Chrome讨厌尝试回放MP4文件
  • 尽管Chrome不喜欢重绕MP4文件,但也请确保您的视频文件没有音轨。它会使它更慢。

所以我觉得我对我可用的选项有很好的理解,但让我觉得我遗漏的一件事就是Apple网站在Chrome中运行正常。

我已经开始调试他们的代码,该代码位于:

https://images.apple.com/v/mac-pro/home/b/scripts/overview.js

从我可以看出他们似乎正在使用requestAnimationFrame,但我无法理解为什么他们会得到更好的结果..有没有人对如何实现这种效果有任何想法?

顺便说一句 - 我知道视频并不是真的意味着向后播放,而且它们永远不会以可预测的方式向后播放。我甚至曾经在苹果网站上遇到过倒钩可能会生涩的情况。但是它们仍然具有良好的2-3秒倒带过渡,结果肯定是可以接受的。

到目前为止,这是我的相关javascript和HTML ..

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 > playTo) {
        requestAnimationFrame(rewindToPointInTime);
    } else {
        playTimestamp = null;
        playAmount = null;
    }

}



<!DOCTYPE html>
<html lang="en">           
    <head>
        <meta charset="UTF-8">
        <title>Rhino Envy</title>
        <script src="https://code.jquery.com/jquery-3.2.1.min.js" integrity="sha256-hwg4gsxgFZhOsEEamdOYGBf13FyQuiTwlAQgxVSNgt4=" crossorigin="anonymous"></script>
        <script src="./js/envy.js"></script>
        <link rel="stylesheet" href="./css/envy.css">
    </head>
    <body;
        <div id="envy-video-container">
            <video id="envy-video" src="./videos/prototype_animation.mp4"></video>
        </div>
        <div id="video-controls">   
            <p id="video-current-time"></p>
            <div class="video-control"><button id="rewind-button">rewind to</button><input type="text" id="play-to-time" placeholder="forward time" value="0"></div>
            <button id="play-button">play</button>
        </div>
        <ul id="envy-steps">
            <li id="envy-step-indicator-1"></li>
            <li id="envy-step-indicator-2"></li>
            <li id="envy-step-indicator-3"></li>
        </ul>
        <section id="envy-full-range">
            <div id="envy-1-door-link"></div>
            <div id="envy-2-door-link"></div>
            <div id="envy-3-door-link"></div>
        </section>
    </body>
</html>

1 个答案:

答案 0 :(得分:0)

我能想到的一个可靠的方法是使用两个视频:一个是正常方向,另一个是反转。

然后,您可以简单地在要播放的视频之间切换,并且仅在后台更新隐藏的视频的ffmpeg -i input.mp4 -vf reverse -af areverse reversed.mp4

使用此解决方案,您甚至可以快退音频

要反转视频,您可以使用ffmpeg的命令
const vids = document.querySelectorAll('video'); vids.forEach(v => { v.addEventListener('loadedmetadata', canplay); v.addEventListener('timeupdate', timeupdate); }); let visible = 0; function timeupdate(evt) { if (this !== vids[visible]) return; let other = (visible + 1) % 2; vids[other].currentTime = this.duration - this.currentTime; } document.getElementById('switch').onclick = e => { visible = (visible + 1) % 2; show(vids[visible]); } // waith both vids have loaded a bit let loaded = 0; function canplay() { if (++loaded < vids.length) return; hide(vids[1]); show(vids[0]); } function show(el) { el.muted = false; const p = el.play(); el.style.display = 'block'; const other = vids[(visible + 1) % 2]; // only newest chrome and FF... if (p && p.then) { p.then(_ => hide(other)); } else { hide(other); } } function hide(el) { el.muted = true; el.pause(); el.style.display = 'none'; } document.getElementById('pause').onclick = function(e) { if (vids[visible].paused) { this.textContent = 'pause'; vids[visible].play(); } else { this.textContent = 'play'; vids[visible].pause(); } }

注意:您可能会在交换机上感觉到一些空白,这可能是通过使用来自其他元素流的单个可见视频元素来利用的,但是我可以使用它。我会把它留给更新,我的时间很短

&#13;
&#13;
<button id="switch">switch playing direction</button>
<button id="pause">pause</button>
<div id="vidcontainer">
  <video id="normal" src="https://dl.dropboxusercontent.com/s/m2htty4a8a9fel1/tst.mp4?dl=0" loop="true"></video>
  <video id="reversed" src="https://dl.dropboxusercontent.com/s/lz85k8tftj2j8x6/tst-reversed.mp4?dl=0" loop="true"></video>
</div>
&#13;
{{1}}
&#13;
&#13;
&#13;