Youtubeから取得したサムネイルをきれいに表示する

サイトにYoutubeを埋め込むと読み込み速度がかなり悪化したため、なにか良い方法がないか調べていたら、こちらの方法にたどり着きました。

「方法①:iframe動画の遅延読み込み」と「方法②:そもそも動画読込無しで代替画像を表示しておく」について紹介されていて、説明もとてもわかり易いです。

今回は「方法②」を使わせていただきましたが、おかげさまでサイトの読み込み速度もかなり改善され、動画の再生サムネイルが表示されるまでのストレスがなくなりました。

記事ではjQueryを使用していましたが、私が制作しているサイトでは訳あって使用ができないため、Javascriptに変えて使用させてもらいました。

以下はそのコードなので、同じようにjQueryが使用できない場合に参考にしていただければと思います。

document.addEventListener("DOMContentLoaded", function() {
  var youtubeElements = document.querySelectorAll('.youtube');

  youtubeElements.forEach(function(element) {
    var iframe = element.querySelector('iframe');
    var url = iframe.getAttribute('data-src');
    var id = url.match(/[\/?=]([a-zA-Z0-9_-]{11})[&\?]?/)[1];

    var img = document.createElement('img');
    img.src = 'https://img.youtube.com/vi/' + id + '/mqdefault.jpg';
    element.insertBefore(img, iframe);
    element.removeChild(iframe);

    element.addEventListener('click', function() {
      var newIframe = document.createElement('iframe');
      newIframe.src = 'https://www.youtube.com/embed/' + id;
      newIframe.frameBorder = '0';
      newIframe.allow = 'accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture';
      newIframe.allowFullscreen = true;
      
      var newDiv = document.createElement('div');
      newDiv.className = 'youtube';
      newDiv.appendChild(newIframe);
      
      element.parentNode.insertBefore(newDiv, element.nextSibling);
      element.parentNode.removeChild(element);
    });
  });
});

動かすためには参考サイトにもある通り、埋め込み用のifeameタグを”youtube”クラスを付与したdivタグで囲い、”data-src”に変更する必要があるので注意が必要です。

<div class="youtube">
  <iframe data-src="https://www.youtube.com/embed/~"~></iframe>
</div>

無事、Youtubeから自動的にサムネイル画像を取得して表示し、クリックしたときに動画が読み込まれるようになりました。

Youtubeから自動的にサムネイル画像を取得して表示し、クリックしたときに動画が読み込まれるGIFアニメ

・・・が、取得したサムネイル画像がびみょーに汚いです。

画像が荒いサムネイル

お客様のサイトなので、このまま「はいどーぞ」というわけにもいかないため、改善する必要があります。

調べたところ、「mqdefault.jpg」で取得した場合はサイズが『320 × 180』となるようです。
参考: YouTube動画のサムネイル画像を取得する方法

このサイズを引き伸ばして表示しているため、画像が粗くなってしまうわけですね。

フルサイズ『1280 × 720』で取得するには「maxresdefault.jpg」を使用するということで、Javascriptを以下のように修正しました。

ファイル名の部分は10行目です。

document.addEventListener("DOMContentLoaded", function() {
    var youtubeElements = document.querySelectorAll('.youtube');

    youtubeElements.forEach(function(element) {
        var iframe = element.querySelector('iframe');
        var url = iframe.getAttribute('data-src');
        var id = url.match(/[\/?=]([a-zA-Z0-9_-]{11})[&\?]?/)[1];

        var img = document.createElement('img');
        img.src = 'https://img.youtube.com/vi/' + id + '/maxresdefault.jpg';
        img.style.width = '100%';
        img.style.height = 'auto';
        img.width = 1280;
        img.height = 720;
        element.insertBefore(img, iframe);
        element.removeChild(iframe);

        element.addEventListener('click', function() {
            var newIframe = document.createElement('iframe');
            newIframe.src = 'https://www.youtube.com/embed/' + id;
            newIframe.frameBorder = '0';
            newIframe.allow = 'accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture';
            newIframe.allowFullscreen = true;

            var newDiv = document.createElement('div');
            newDiv.className = 'youtube';
            newDiv.appendChild(newIframe);

            element.parentNode.insertBefore(newDiv, element.nextSibling);
            element.parentNode.removeChild(element);
        });
    });
});

念のため画像が親要素に合わせて最大サイズでスケーリングされるように、画像に直接スタイルで幅100%、高さautoを指定してあります。

CSSで別途指定している場合は不要なので削除してOKです。

img.style.width = '100%';
img.style.height = 'auto';

またレイアウトシフトが起こらないように、画像自体にサイズを入れるようにしました。

「maxresdefault.jpg」で『1280 × 720』の画像を取得しているので、以下の値を入れています。

img.width = 1280;
img.height = 720;

※レイアウトシフトとは、画像を読み込む影響でサイト上のコンテンツがずれてしまう(シフトする)現象です。
ボタンをクリックしようとしたら位置がいきなり下にずれてしまったなんて経験がありますよね?

以上できれいなサムネイルが表示されるようになりました。

修正前と比べても一目瞭然ですね。

きれいになったサムネイル

※記事で使用しているサムネイルはもちろんお客様のものではありません。
Trip Meditation様の動画を使わせていただきました。ありがとうございます^^
きれいな映像と荘厳な音楽に癒やされます。

ここから追記。

Youtubeから自動取得したサムネイルですが、再生ボタンが表示されていないため、パッと見たときに動画であることが分かりづらいという指摘がありました。

また、サムネイルをクリック(orタップ)してから、動画が読み込まれ、もう一度クリック(orタップ)して再生されるというのはユーザーに1アクション余計な操作を強要していることになります。

1.再生ボタンがないため動画だとわかりにくい

2.動画を再生するまでに2クリック(orタップ)が必要

この2点について解決策を模索していきます。

Youtubeからは再生ボタン付きのサムネイルを取得することはできなそうなので、自分で再生ボタンを入れる必要があります。

画像を加工するのは大変なので、HTMLらしく要素の上に再生ボタンを置いて、それっぽく見せてしまいましょう。

まず置くための再生ボタンですが、自分で用意してもよいですし、ネットから拾ってきても良いです。

ここで探せば簡単に見つかります。

再生ボタンをサムネイルに表示させるために、HTMLとCSSを以下のように変更します。

2行目のimgタグを追記しました。

<div class="youtube">
  <img class="play-button" src="img/play.webp" alt="再生ボタン"/>
  <iframe data-src="https://www.youtube.com/embed/~"~></iframe>
</div>
.youtube {
    position: relative;
    width: 560px;
    height: 315px;
    cursor: pointer;
}

.youtube .play-button {
    position: absolute;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
    width: 80px;
    height: 80px;
    background-size: contain;
    z-index: 1;
}

これでサムネイルの上下中央の位置に再生ボタンが表示されます。

自分で再生ボタンを配置したサムネイル

ただし、このままだとクリックして動画を再生しても、再生ボタンが残り続けます。

これを消すためにはJavascriptを使います。

以前のコードをベースにクリックと同時に再生ボタンとサムネイルが消える処理を追加しました。
※その他にもクリック要素であることを伝えるcursor: pointer;もひっそりと追加

document.addEventListener("DOMContentLoaded", function() {
    var youtubeElements = document.querySelectorAll('.youtube');

    youtubeElements.forEach(function(element) {
        var iframe = element.querySelector('iframe');
        var url = iframe.getAttribute('data-src');
        var id = url.match(/[\/?=]([a-zA-Z0-9_-]{11})[&\?]?/)[1];

        var img = document.createElement('img');
        img.src = 'https://img.youtube.com/vi/' + id + '/maxresdefault.jpg';
        img.width = 1280;
        img.height = 720;
        img.style.width = '100%';  // スケールを親要素に合わせる
        img.style.height = 'auto'; // アスペクト比を保持する
        img.style.cursor = 'pointer'; // クリック可能であることを示すカーソル
        element.insertBefore(img, iframe);
        element.removeChild(iframe);

        // 再生ボタンを作成
        var playButton = element.querySelector('.play-button');

        function loadVideo() {
            playButton.style.display = 'none'; // 再生ボタンを非表示にする
            img.style.display = 'none'; // サムネイル画像を非表示にする

            var newIframe = document.createElement('iframe');
            newIframe.src = 'https://www.youtube.com/embed/' + id + '?autoplay=1'; // 自動再生を有効にする
            newIframe.frameBorder = '0';
            newIframe.allow = 'accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture';
            newIframe.allowFullscreen = true;

            element.appendChild(newIframe);
        }

        // 再生ボタンとサムネイル画像の両方にクリックイベントを設定
        playButton.addEventListener('click', loadVideo);
        img.addEventListener('click', loadVideo);
    });
});

また、2つ目の問題である「動画を再生するまでに2クリック(orタップ)が必要」については、呼び出す際のURLのパラメーターに『?autoplay=1』を指定することで自動的再生されることがわかりました。

上記コードの27行目の部分がその対応です。

これでサムネイルに再生ボタンを表示し、サムネイルまたは再生ボタンをクリックすることで自動的に動画を再生する動きを実現することができました。

サイト制作に関するご相談・お見積りなどお気軽にご相談ください。

新規サイト制作では、提案・制作から公開後の保守・運用・更新までトータルで、あなたのお力になります。

既存のサイトでも、簡易な修正や機能追加、更新のお手伝いやレッスンなど、幅広く対応させていただきます。

まずは、お気軽に今お持ちのお悩みをお聞かせください。

コメント

タイトルとURLをコピーしました