YouTube動画が埋め込まれているページは、読み込みが遅いです。
それは、以下のようにiframeが埋め込まれてYouTube動画が読み込まれるからです。
今回は、そのiframeをページ読み込み時は表示しないで、最初はサムネイル画像を表示させておき、クリックした時に初めてiframeを読み込むことで高速化を図る方法の紹介です。
こんな感じに。
目次
カスタマイズ方法
カスタマイズの主な手順はこちら。
- functions.phpにコードをコピペ
- style.cssにコードをコピペ
- 画像をテーマフォルダ直下に配置
基本コピペでカスタマイズできます。
functions.phpにコードをコピペ
テーマ(子テーマ)のfunctions.phpに以下のコードを追記します。
//Jetpackとの競合対応 remove_action( 'init', 'wpcom_youtube_embed_crazy_url_init' ); //YouTube動画表示の高速化 add_filter('embed_oembed_html', 'youtube_embed_oembed_html', 1, 3); if ( !function_exists( 'youtube_embed_oembed_html' ) ): function youtube_embed_oembed_html ($cache, $url, $attr) { // data-youtubeチェック if (strpos($cache, 'data-youtube')) { preg_match( '/(?<=data-youtube=")(.+?)(?=")/', $cache, $match_cache); $MATCH_CACHE = $match_cache[0]; }; //* YouTubeキャッシュが空のときYouTubeビデオとプレイリストのためにこれらを作成する ( video_id, title, picprefix and etc for schema.org ) if (empty($MATCH_CACHE)) { // YouTubeキャッシュを無視する if (!strpos($cache, 'youtube')) { return $cache; } // curlの存在確認 if (!function_exists('curl_version')) { return $cache; } // 古いデータの除去 $cache = preg_replace('/data-picprefix=\\"(.+?)\\"/s', "", $cache); // プレイリストIDがある場合 if( preg_match_all( '/videoseries|list=/i', $cache, $m )){ // プレイリストIDの抽出 preg_match( '/(?<=list=)(.+?)(?=")/', $cache, $list ); // ビデオIDの取得 $json = json_decode(file_get_contents('https://www.youtube.com/oembed?url=http://www.youtube.com/playlist?list='.$list[1]), true); // ビデオIDの抽出 preg_match( '/(?<=vi\/)(.+?)(?=\/)/', $json['thumbnail_url'], $video_id ); } else { preg_match( '/(?<=embed\/)(.+?)(?=\?)/', $cache, $video_id ); } // もしビデオIDないまだ空ならおそらくYouTubeがオフライン if (!$video_id[0]) { return $cache; } $ch = curl_init(); $headers = array( 'Accept-language: en', 'User-Agent: Mozilla/5.0 (iPad; CPU OS 7_0_4 like Mac OS X) AppleWebKit/537.51.1 (KHTML, like Gecko) Version/7.0 Mobile/11B554a Safari', ); curl_setopt($ch, CURLOPT_HTTPHEADER, $headers); curl_setopt($ch, CURLOPT_HEADER, 0); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0); curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0); curl_setopt($ch, CURLOPT_URL, "https://www.youtube.com/oembed?url=http://www.youtube.com/watch?v=" . $video_id[0] . "&format=json"); $data = curl_exec($ch); $info = curl_getinfo($ch); curl_close($ch); if ($info['http_code'] != 200){ return $cache; } // YouTubeからデータが取得できなかった場合 if (empty($data)) { return $cache; } // コード処理 $data = str_replace("\\U",'\\u', $data); $json = json_decode($data,JSON_UNESCAPED_SLASHES); // JSONが無効な場合 if (empty($json)) { return $cache; } $youtube_cache = []; $youtube_cache['title'] = htmlentities( $json['title'], ENT_QUOTES, 'UTF-8' ); $youtube_cache['video_id'] = $video_id[0]; $youtube_cache = base64_encode(json_encode($youtube_cache)); if(isset($attr['discover']) && $attr['discover'] == 1){ unset($attr['discover']); } $cachekey = '_oembed_' . md5( $url . serialize( $attr ) ); // $cache変数のアップデート $cache = str_replace('src', ' data-youtube="'.$youtube_cache.'" src', $cache); // 新しいキャッシュを保存 update_post_meta( get_the_ID(), $cachekey, $cache ); $MATCH_CACHE = $youtube_cache; } $json = json_decode(base64_decode($MATCH_CACHE), true); $youtube = preg_replace("/data-youtube=\"(.+?)\"/", "", $cache); $youtube = htmlentities(str_replace( '=oembed','=oembed&autoplay=1', $youtube )); $thumb_url = "https://i.ytimg.com/vi/{$json['video_id']}/hqdefault.jpg"; $wrap_start = '<div class="video-container">'; $wrap_end = '</div>'; //タグの生成 $html = $wrap_start . "<div class='video-click video' data-iframe='$youtube' style='position:relative;background: url($thumb_url) no-repeat scroll center center / cover' ><div class='video-title-grad'><div class='video-title-text'>{$json['title']}</div></div><div class='video-play'></div></div>" . $wrap_end; return $html; }; endif; //クリックしたときにiframe読み込む add_filter( 'wp_footer', 'youtube_embed_oembed_script' ); if ( !function_exists( 'youtube_embed_oembed_script' ) ): function youtube_embed_oembed_script(){ ?> <script> (function(){ var f = document.querySelectorAll(".video-click"); for (var i = 0; i < f.length; ++i) { f[i].onclick = function () { var iframe = this.getAttribute("data-iframe"); this.parentElement.innerHTML = '<div class="video">' + iframe + '</div>'; } } })(); </script> <?php } endif;
全ての内容を説明するわけにもいかないので、簡単に書きますが、上記コードでは以下のようなことを行っています。
- URL埋め込みを検知して高速表示用のHTMLに置き換える処理
- フッターにクリック動作用のJavaScriptを挿入する処理
YouTube URLの埋め込み処理を検知して動作するものなので、YouTubeが生成するiframeで埋め込んでいる場合は、通常表示されます。
style.cssにコードをコピペ
次に、高速表示用のファイルをテーマ(子テーマ)のstyle.cssに追記します。
/*!動画の最大幅を指定する*/ .video-container{ max-width:640px; } /*!動画の大きさを調整*/ .video-container .video { position: relative; padding-bottom: 56.25%; margin-top: 30px; height: 0; overflow: hidden; max-width: 100%; } .video iframe { position: absolute; top: 0; left: 0; width: 100%; height: 100%; } .video-click { cursor: pointer; } .video-click:hover .video-play { background: url("youtube-play.png") no-repeat scroll -101px -13px rgba(0, 0, 0, 0); } .video-play { background: url("youtube-play.png") no-repeat scroll 2px -13px rgba(0, 0, 0, 0); height: 62px; left: 50%; margin-left: -45px; margin-top: -33px; position: absolute; top: 50%; width: 100px; opacity: 0.8; } .video-title-grad { position: absolute; top: 0; left: 0; right: 0; background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAABiCAQAAAA7fHH2AAAAQUlEQVQYV22KQQoAIAzDyv7/Et/oVlGZVCfkkIYamsENXESyi8vc0u/PKZ6o8+7fZ0h8ShRYnD+BFKToRJkHFpkM2hZSxuyWpEYAAAAASUVORK5CYII="); background-position: center top; } .video-title-text { color: #eeeeee; font-family: Roboto,Arial,Helvetica,sans-serif; font-size: 17px; overflow: hidden; padding: 12px 16px 4px; text-overflow: ellipsis; white-space: nowrap; }
動画を格納するコンテナの最大幅は640pxになっています。デフォルト表示サイズを調整したい場合は、数値を変更してください。
画像をテーマフォルダ直下に配置
最後に以下の画像をダウンロードし、名前を変更しないでテーマ(子テーマ)フォルダー直下に配置します。
テーマ(子テーマ)直下とは、style.cssがあるファイルと同じ階層です。
使い方
このカスタマイズを利用するには、WordPressの「URL埋め込み形式」でYouTube URLをエディターに書き込む必要があります。
「URL埋め込み形式」といっても、簡単で単にURLをテキストでエディターの一行に対して書き込むだけです。
動作確認
エディターにURLのみを書き込んだら、以下のように表示されます。
実写系だとこんな感じ。
注意点
今回のカスタマイズは、WordPressのURL埋め込みのみに対応しています。
通常のiframeで埋め込んだYouTube動画には対応していません。また対応させる方法の質問にはお答え致しかねますのでご了承ください。
また、すべての動画に対応できるかの保証も致しかねます。JavaScriptが無効になっているブラウザではクリックしても再生しません。
参考
このカスタマイズは、Alexufo氏が作成したWordPressプラグイン「Youtube SpeedLoad」のコードを参考にさせていただきました。
まとめ
とこんな感じで、かなりYouTube動画の読み込み表示時間を短縮できるかと思います。
YouTube動画iframe風の見た目を維持しつつ、表示も高速化するという、一挙両得的なカスタマイズかと思います。
特に、動画などを多く掲載しているサイトには重宝するのではないかと。
Youtube SpeedLoadのソースコードを見たとき、いろいろな面において「なるほどそんな手があったか」と目からうろこでございました。
わいひらさん、こんばんわ。
早速、二つをコピーして画像も子テーマにアップロードしました。
ですが、記事のように画像の右▸マークが表示されていません。
これは、既存の記事には対応してないと考えて良いでしょうか?
https://chan-bike.com/tourofbritain8
それと、新規にurlをテキストで貼りつけると、リンクカードの形式になります。
何か、ヒントをいただけると幸いです。