LoginSignup
1
0

More than 1 year has passed since last update.

javascriptでvideoのバッファをシークバーにうまく表示する。

Last updated at Posted at 2022-05-24

概要

なんとなく動画再生サイトを作る中で、バッファをどうにかして目に見えるようにするため、
プログラムを作っていたらかなり壁に当たったので、js経験あまりない僕がそのコードを残しておく。
ちょっと文がおかしいとか思ってもコメントでボロクソ言って終わりにしてくれ(´・ω・`)

ちなみに言っておくけど、オフラインというかhtmlをそのまま開いただけだと、
このbuffer表示は無意味と化すから、オンラインのサイトで使うとか、WindowsのIISを使うとかしないといけない。

仕組み

<video>のidを取得し、動画を再生すると再生時間を取得するイベントリスナーを登録している。
for文の内容は、バラバラになったバッファを管理していて、再生時間によって参照するデータを切り替えてる。
最終的にバッファ時間をbufferNoに出力するようにしている(そこらへん自由に書き換えていってくれ)。
あとはその値をcurrentTimeに似た扱い方で使ってくれるといいかも。

javascript

index.js
var v = document.getElementById("video"),
    bufferNo;

v.addEventListener("timeupdate", function () {
    for (let i = (v.buffered.length); bufferNo == undefined && v.buffered.length != 0 && i != 0; i--) {
        if (v.buffered.start(i - 1) < v.currentTime) {
            bufferNo = v.buffered.end(i - 1);
        }
    }
}, false);

html

index.html
<video id="video" poster="" muted autoplay preload="metadata">
    <source src="test.mp4" type="video/mp4">
</video>
<script type="text/javascript" src="index.js"></script>

コードの全体

一応実用的に使うならばと作っておいた。
いらないと思うけど()

index.html
<!DOCTYPE html>
<html>

<head>
    <meta http-equiv="content-type" content="text/html; charset=UTF-8">
    <meta name="viewport" content="width=device-width,initial-scale=1.0,minimum-scale=1.0">
    <title>シークバー</title>
    <link rel="stylesheet" href="stylesheet.css">
</head>

<body>
    <div id="window">
        <video id="video" poster="" muted autoplay preload="metadata">
            <source src="test.mp4" type="video/mp4">
        </video>
        <div id="seekbar-wrap">
            <div id="seekbar-out">
                <div id="seekbar-load"></div>
                <div id="seekbar-in"></div>
            </div>
        </div>
        <input type="button" value="再生" onclick="v.play()">
        <input type="button" value="一時停止" onclick="v.pause()">
        <input type="button" value="ミュート" onclick="v.muted = true">
        <input type="button" value="ミュート解除" onclick="v.muted = false">
        <input type="button" value="ループ" onclick="v.loop = true">
        <input type="button" value="ループ解除" onclick="v.loop = false">
        <script type="text/javascript" src="index.js"></script>
    </div>
</body>

</html>
stylesheet.css
video {
    width: 100%;
}
#window {
    width: 600px;
    height: auto;
}
#seekbar-wrap {
    width: auto;
    height: 15px;
    overflow: hidden;
}
#seekbar-out, #seekbar-in, #seekbar-load {
    width: 100%;
    height: 100%;
}
#seekbar-out {
    display: flex;
    background-color: rgb(131, 131, 131);
    transform: scaleY(1);
}
#seekbar-in {
    position: absolute;
    margin: 0 auto 0 0;
    background-color: #00c3ff;
    transform-origin: top left;
    transition: 0.1s;
}
#seekbar-load {
    margin: 0 auto 0 0;
    background-color: #ffffff88;
    transform-origin: top left;
    transition: 0.1s;
}
index.js
var v = document.getElementById("video"),
    seekbarDrag = document.getElementById("seekbar-wrap"),
    seekbarLoad = document.getElementById("seekbar-load"),
    seekbarIn = document.getElementById("seekbar-in"),
    bufferNo;

v.addEventListener("timeupdate", function () {
    seekbarIn.style.transform = `scaleX(${v.currentTime / v.duration})`;
    for (let i = (v.buffered.length); bufferNo == undefined && v.buffered.length != 0 && i != 0; i--) {
        if (v.buffered.start(i - 1) < v.currentTime) {
            bufferNo = v.buffered.end(i - 1);
        }
    }
    seekbarLoad.style.transform = `scaleX(${bufferNo / v.duration})`;
}, false);
seekbarDrag.addEventListener('click', function (e) {
    var percent = (e.pageX - (seekbarDrag.getBoundingClientRect().left + window.pageXOffset)) / seekbarDrag.clientWidth;
    v.currentTime = v.duration * percent;
    console.log("click");
}, false);

これをコピーすれば、とりあえずサイトで動画は見れる

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0