Instagram 风格视频预加载静态效果

Instagram reels 是 instagram 的一项相对较新的功能,在视频加载之前会产生这种有趣的噪音效果。最近,我的 airpods 在连接到 instagram 时遇到了一些问题,我经常在应用程序赶上并连接到它们之前得到这种静态效果。

这种噪音效果很酷,而且很怀念旧电视机。这让我开始思考如何为网络上的视频或 Javascript 应用程序中的视频做到这一点。让我们看看如何做到这一点,并带有一些perlin 噪音

Perlin Noise#

首先,我们需要一个好的柏林噪声函数。Perlin 噪声是一种生成随机噪声的方法,我们可以使用它来创建我们所追求的静态效果。

我将使用此存储库中的代码。这段代码给了我们一个函数noise,我们可以用它来生成我们的噪声上下文。让我们用它来产生一些噪音:

let video = document.getElementById('video');
let canvas = document.getElementById('noise-canvas');

canvas.width = 250;
canvas.height = 250;
    
let ctx = canvas.getContext('2d');
    
function generateNoise() {
    var image = ctx.createImageData(canvas.width, canvas.height);
    var data = image.data;
    
    for (var x = 0; x < canvas.width; x++) {
        noise.seed(Math.random());
        for (var y = 0; y < canvas.height; y++) {
            var value = Math.abs(noise.perlin2(x / 2, y / 2));
            value *= 500;
    
            var cell = (x + y * canvas.width) * 4;
            data[cell] = data[cell + 1] = data[cell + 2] = value;
            data[cell + 3] = 255; // alpha.
        }
    }
    ctx.putImageData(image, 0, 0);
}

function animation(timestamp) {
    generateNoise();
    window.requestAnimationFrame(animation);
}
window.requestAnimationFrame(animation);
<div id="video-container">
    <video id="video" muted>
      <source src="http://commondatastorage.googleapis.com/gtv-videos-bucket/sample/BigBuckBunny.mp4" type="video/mp4"> 
    </video>
    <div id="canvas-overlay"></div>
    <canvas id="noise-canvas"></canvas>
</div>  

本质上,此代码逐个像素地生成一个图像,该图像具有每个像素的随机颜色。对于这个演示,画布的宽度和高度在第 4 行和第 5 行的代码中设置为 250px。如果您的视频更大,您可能需要更改此设置

我还创建了一个带有轻微渐变的画布覆盖 div。这个样式看起来像这样:

canvas, #canvas-overlay {
    position: absolute;
    top: 0;
    left: 0;
    width: 100%;
    background: black;
    height: 100%;
    z-index: 9999;
}

#canvas-overlay {
    z-index: 9999999;
    background: linear-gradient(-135deg, #343fa99e, #2ed29d1c);
}
video {
    height: 100%;
    width: auto;
    position: absolute;
}

#video-container {
    position: relative;
    width: 250px;
    box-shadow: 0 5px 25px rgb(0 0 0 / 7%), 0 2px 5px rgb(0 0 0 / 15%), 0 15px 30px rgb(0 0 0 / 10%), 0 0 0px 5px #00000000, 0 0 3px 1px #00000000;
    border-radius: 15px;
    overflow: hidden;
    height: 250px;
}

视频自动播放#

下一步将利用Javascript Video API。加载视频后,我们将隐藏静态画布和画布叠加层:

video.addEventListener('loadeddata', function() {
    canvas.style.display = 'none';
    document.getElementById('canvas-overlay').style.display = 'none';
    video.play();
}, false);

这就是下面的完整代码: