我正在尝试克隆以下网站:
https://www.apple.com/mac-pro/
我仍然处于原型制作阶段,我想弄清楚的是,当你向上滚动页面时,他们是如何向后播放MP4文件的。如果您向下滚动页面几步然后再备份,您将看到我的意思。
到目前为止,我尝试了以下技术:
使用requestAnimationFrame技术,我现在可以在Chrome以外的每个浏览器中获得部分可用的结果。如果你想倒回0.5秒,Chrome就可以了,但不止于此,它会变得很激动。
我也做了以下发现:
所以我觉得我对我可用的选项有很好的理解,但让我觉得我遗漏的一件事就是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>
答案 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();
}
}
注意:您可能会在交换机上感觉到一些空白,这可能是通过使用来自其他元素流的单个可见视频元素来利用的,但是我可以使用它。我会把它留给更新,我的时间很短
<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;