Ish*_*Ish 23 javascript html5 html5-video
HTML5 <video>标签是反向播放视频,还是我必须下载2个视频(前进和后退播放).任何避免用户下载2个视频的解决方案?
Bap*_*teB 11
我设法在更新方法中做到了.每一帧我将video.currentTime减少到过去的时间,到目前为止,这是我设法获得的最佳结果.
Chr*_*her 11
此片段仅显示了如何完成,但复制每个帧需要一些时间。这很大程度上取决于硬件。
它生成它必须播放的每一帧的画布。当它设置为 100% 时,播放会直接开始并向后、向前播放......等等。生成后也会附加原始视频,但由于 iframe 规则不会自动播放。
它非常适合短视频和概念证明。
更新: 我更改了捕获部分的顺序,以便跳过最大持续时间的帧,但捕获 0 处的帧(之前忘记了)。
最大持续时间的帧导致我尝试的每个视频上出现白色画布。
我还更改了播放方式,一旦到达最后一帧就以相反的顺序播放,以实现无限播放。因此您很容易看出,与硬件加速视频相比,这种播放有点占用 CPU 资源。
fetch('https://i.imgur.com/BPQF5yy.mp4')
.then(res => res.blob())
.then(blob => {
return new Promise((res) => {
const fr = new FileReader();
fr.onload = e => res(fr.result);
fr.readAsDataURL(blob);
})
}).then(async(base64str) => {
const video = document.createElement("video");
video.src = base64str;
video.controls = true;
video.className = "w-50";
while (isNaN(video.duration))
await new Promise((r) => setTimeout(r, 50));
const FPS = 25;
const status = document.createElement("div"),
length = document.createElement("div");
length.innerText = `Generating ${Math.ceil(video.duration / (1 / FPS))} frames for a ${FPS} FPS playback (Video Duration = ${video.duration})`;
document.body.appendChild(length);
document.body.appendChild(status);
const frames = [],
copy = () => {
const c = document.createElement("canvas");
Object.assign(c, {
width: video.videoWidth,
height: video.videoHeight,
className: "w-50"
});
c.getContext("2d").drawImage(video, 0, 0);
return c;
};
// first seek outside of the loop this image won't be copied
video.currentTime = video.duration;
// this frame seems to be always white/transparent
while (video.currentTime) {
if (video.currentTime - 1 / FPS < 0)
video.currentTime = 0;
else
video.currentTime = video.currentTime - 1 / FPS;
await new Promise((next) => {
video.addEventListener('seeked', () => {
frames.push(copy());
status.innerText = (frames.length / (Math.ceil(video.duration / (1 / FPS))) * 100).toFixed(2) + '%';
next();
}, {
once: true
});
});
}
/*
* frames now contains all canvas elements created,
* I just append the first image and replace it on
* every tick with the next frame.
* using last.replaceWith(frames[currentPos]) guarantees a smooth playback.
*/
let i = 0, last = frames[0];
document.body.insertAdjacentHTML('beforeend', `<div class="w-50">Captured</div><div class="w-50">Video</div>`);
document.body.appendChild(frames[0]);
const interval = setInterval(() => {
if (frames[++i]) {
last.replaceWith(frames[i]);
last = frames[i];
} else {
frames.reverse();
i=0;
}
}, 1000 / FPS);
document.body.appendChild(video);
// won't :(
video.play();
});Run Code Online (Sandbox Code Playgroud)
/* Just for this example */
.w-50 {
width: 50%;
display: inline-block;
}
* {
margin: 0;
padding: 0;
font-family: Sans-Serif;
font-size: 12px;
}Run Code Online (Sandbox Code Playgroud)
Eli*_*rey 10
aMediaElement.playbackRate = -1;
Run Code Online (Sandbox Code Playgroud)
UA可能不支持此功能,但设置playbackRate为负值是有效的.
| 归档时间: |
|
| 查看次数: |
27646 次 |
| 最近记录: |