[js]youtube埋め込みの高速化とか最適化とか

結論というよりは足がかりに。

youtubeの痒いところ

youtubeというかgoogle周りの埋め込み全般に言えるんだけど。

動画を扱いたいときに、無料動画サービスのお陰で自分のサーバーに負荷がかからないのはとても助かる。だけど埋め込みは表示(読み込み)に地味に時間がかかるので、ページの読み込み速度的に悪影響が出る。

あと、表示した際は最初にサムネが出たりするんだけども、サムネは嬉しいんだけど、コントロールバーやらアイコンやらがガチャガチャして、特にスマホだとタイトルとかがぶち抜かれてなんかよく分からんことになったりする。

タイトルが切れてる、文字が被ってるなど

恩恵はデカいけど欲張ってしまう。どうにかしていこうという試み。

解決案

サムネはサムネとして画像を表示して、youtube自体はポップアップ表示にする。

ポップアップ発火時にyoutubeの読み込みが行われるので、ページ読み込み完了自体は早くなるよねという考え。

参考として、シマノがやってる。

ボーダレス[BORDERLESS] | ボーダレス(ガイド付き) | フリースタイル | ロッド | 製品情報 | SHIMANO シマノ
フィールド・釣種・釣法を飛び越え“BORDERLESS”に遊べ!!

埋め込みは動画のidが分かればどうとでもなるし、idは動画urlから抽出できる。

ポップアップの内容をクリック時(=発火時)にjsで出力する(=HTMLで記述しない)ことで、クリックしない限りはyoutubeは読み込まれない。ユーザーに優しいページになる。

作るのは手間だけど作った後は楽なのでオススメ。

たたき台

埋め込みに必要な要素は「サムネイル」「動画」の2つになる。

サムネイル

Youtubeにアップした動画にはサムネイルがアップできる。これも、IDがわかれば引っ張ってくることができる。

【JS】YouTubeの動画IDからなるべく大きい解像度のサムネイルを取得する方法(API使わずに)

サムネイルだけ引っ張ってくればyoutube埋込時のアイコンやらなにやらは表示されないわけで、スッキリする。だけどまあ、画像の表示だけでも地味に読み込み時間が発生するのでだるいといえばだるい。自鯖で用意してもいいじゃん、という感じ。

埋め込み

Youtube上で埋め込みコードを入手することができるけど、これはsrc以外は使いまわし。

<iframe width="560" height="315" src="https://www.youtube.com/embed/tCYI6DjcXoU" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" allowfullscreen></iframe>

srcのURLは動画リンクになるわけで、末尾がidになるわけで、idは各所で使われる。リンクを取得したらこんな感じになる。

https://youtu.be/tCYI6DjcXoU

jsをかじってたらurlからid部分の取得は問題なくできるはずで、今回は掘り下げない。というか掘り下げようもないので参考を貼る。

URLからファイル名を取得する正規表現 - Qiita
これは便利。var url = window.location.href;// 拡張子付きでvar filename_ex = url.match(".+/(.+?)(.*)?$"…
https://nishimura.club/regexp-file-name

書式を理解してidが取得できるようになればなんとでもできる。

作例

埋め込みコードからidを取得してサムネイルを表示する。ポップアップ表示時に動画を再生し、閉じたときに流れっぱなしはおかしいので非表示時に合わせて再生を停止する。

こういうのを作る。当初から書いてた軽量化に反するアレだけど、まあ、叩きとしていいと思います。

<div class="youtube">
    <div class="thumb"><button><img src="" alt=""></button></div>
    <div class="popup">
        <div class="wrap">
            <div class="bg"></div>
            <div class="set">
                <div class="inner">
                    <div class="close"><button></button></div>
                    <iframe width="560" height="315" src="https://www.youtube.com/embed/5UXNXnkETZ0" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" allowfullscreen></iframe>
                </div>
            </div>
        </div>
    </div>
</div>

cssは割愛。装飾に難のない程度に入れ子にしてあるのでいい感じにしてください。

欠かせないのはポップアップ領域の非表示。

.youtube .popup{
    display: none;
}

.thumbのbuttonをクリックしたらポップアップ(.popup)を表示させる。閉じるボタン(.close button)または背景(.bg)をクリックしたらポップアップを非表示にする。youtube埋め込みのjs操作は「?enablejsapi=1」を入れておく必要がある。その他諸々。

$(function(){
    $('.youtube').each(function(){
        //youtubeのurlを取得
        var youtube_src = $(this).find('iframe').attr('src');
        //動画のidを取得
        var youtube_id = youtube_src.match(".+/(.+?)([\?#;].*)?$")[1];
        //サムネイル画像のurlを生成
        var youtube_thumb = 'https://img.youtube.com/vi/'+youtube_id+'/sddefault.jpg';
        //サムネイルのurlを画像に挿入
        $(this).find('button img').attr('src',youtube_thumb);
        //youtubeを操作するためのおまじない
        $(this).find('iframe').attr('src',youtube_src+'?enablejsapi=1');
    })
    $('.youtube .thumb button').on('click',function(){
        //ポップアップ表示
        $(this).parent('.thumb').next('.popup').fadeIn();
        //youtube再生
        var playerWindow = $(this).parents('.youtube').find('iframe')[0].contentWindow;
        playerWindow.postMessage('{"event":"command","func":"'+"playVideo"+'","args":""}', '*');
    })
    $('.youtube .close button, .youtube .bg').on('click',function(){
        //ポップアップ非表示
        $(this).parents('.youtube .popup').fadeOut();
        //youtube停止
        var playerWindow = $(this).parents('.youtube').find('iframe')[0].contentWindow;
        playerWindow.postMessage('{"event":"command","func":"'+"pauseVideo"+'","args":""}', '*');
    })
})

実用面

やっぱり実務面で考える必要はあるわけで。身近なところでwordpressに突っ込むことになる可能性が高い。それでもって、投稿するのは組み込んだ自分とは限らない。それを踏まえると、極力予備知識無しに扱える形にしないといけない。

サムネ画像を入れろと言っても入れない場合があるから、そしたら動画から引っ張ってくる手段は保険としてほしい。

動画のidがほしいと言ってもどこの何がidなのかを教えるのはだるいので、だったら埋め込みコードを入れてくれを最低限のお願いにするのが無難。動画リンクからも引っ張れるわけだけど、共有用のurlじゃないと、たとえばブラウザのURLからコピペされるとパラメータが色々くっついて来るわけで、素人考えだと「どっちも同じだろ」で処理される可能性がある。そうなると困るだけなんで、やっぱり埋め込みコード一択じゃないかと思う。

で、埋め込みコードはhtmlの塊なので扱いに困る。jsに文字列として格納したくても、そうするならjsを個別に出力する形に組まないといけない。URLをちゃんと登録してくれるならdata属性に放り込めるんだけど、属性の値にhtmlタグを突っ込むわけにはいかんので、無理じゃんってことになる。

快適なものを構想しても扱いにリスクを感じたら諦めなきゃいけない。落とし所を考えないといけない。

そんな感じで、どうぞ。

コメント

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