Search code examples
javascriptvideo

Javascript: smooth animation between two frames


I have a video element in my html page and I play frame by frame by seeking to the frame of my time by following this: HTML5 frame-by-frame viewing / frame-seeking?. This type of playback is choppy; my question is: if I had two frame times, would it be possible to smooth out the playback between them(I read about frame interpolation, but couldn't find any javascript libraries)?

player code:

<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <meta http-equiv="X-UA-Compatible" content="ie=edge">
        <title>Playback Demo</title>
        <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.js"></script>
        <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/js/bootstrap.min.js"></script>
        <link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css" rel="stylesheet">
    </head>
    <body>


<video id="videoElement" controls tabindex="0" autobuffer preload>
    <source src="https://mdn.github.io/learning-area/javascript/apis/video-audio/finished/video/sintel-short.mp4" type="video/mp4"></video>
</video>
<button type="button" id="playButton" onclick="playVideo()">Play Video</button>
<button type="button" id="stopButton" onclick="stopVideo()">Stop Video</button>
</body>
</html>

<script>
var playerObject = $('#videoElement')[0];
var handle = undefined;
var seekTime = 0;
function seekToTime(ts){
    playerObject.pause();
    playerObject.currentTime = ts;
}
function playVideo(){       
    handle = setInterval(function() {
                seekTime = seekTime + 1;                
                seekToTime(seekTime);
            
    }, 1000);
}

function stopVideo(){
    clearInterval(handle);
    seekToTime(0);
}
</script>

Solution

  • Increase the Frame Rate by Reducing the Interval: reduce the setInterval delay to make frame transitions faster and smoother:

    handle = setInterval(function () {
        seekTime += 0.033; // 30 fps (1 second / 30)
        seekToTime(seekTime);
    }, 33); // Run every ~33ms
    

    If this doesnt work for you, you will have to switch to canvas :(