YouTubeの再生リストには、動画の本数は表示されても「全部で何時間あるか」は表示されない。講座や解説シリーズを再生リストにまとめたとき、「これ全部見るのに何時間かかる?」を知りたくなることはよくある。外部サイトに再生リストのURLを貼り付けて計算するサービスもあるが、いま開いているページでワンクリックで済むほうが手軽だ。このブックマークレットは、各動画のサムネイル右下に出ている時間表記を読み取って合算し、合計・平均・倍速時の所要時間をまとめて表示する。
ブックマークレット
次のコードをブックマークのURL欄に設定する。
javascript:(function(){if(!location.href.includes('youtube.com')){alert('YouTubeの再生リストのページで実行してください');return;}function toSec(t){var p=t.trim().split(':').map(Number);if(p.some(isNaN))return 0;return p.length===3?p[0]*3600+p[1]*60+p[2]:p[0]*60+p[1];}function fmt(sec){sec=Math.round(sec);var h=Math.floor(sec/3600),m=Math.floor((sec-h*3600)/60),s=sec-h*3600-m*60;return (h?h+'時間':'')+(m?m+'分':'')+s+'秒';}var rows=document.querySelectorAll('ytd-playlist-video-renderer,ytd-playlist-panel-video-renderer');if(!rows.length)rows=document.querySelectorAll('yt-lockup-view-model,ytd-video-renderer,ytd-grid-video-renderer');var rt=/\d{1,2}:\d{2}(?::\d{2})?/,rtFull=/^\d{1,2}:\d{2}(?::\d{2})?$/;function rowTime(row){var b=row.querySelector('ytd-thumbnail-overlay-time-status-renderer,.badge-shape-wiz__text');if(b){var m=b.textContent.match(rt);if(m)return m[0];}var ns=row.querySelectorAll('span,div');for(var i=0;i<ns.length;i++){var x=ns[i].textContent.trim();if(rtFull.test(x))return x;}return null;}var total=0,count=0;rows.forEach(function(row){var t=rowTime(row);if(!t)return;total+=toSec(t);count++;});if(!count){var leaves=document.querySelectorAll('.badge-shape-wiz__text,ytd-thumbnail-overlay-time-status-renderer #text');leaves.forEach(function(el){if(el.children.length)return;var t=el.textContent.trim();if(rtFull.test(t)){total+=toSec(t);count++;}});}if(!count){alert('動画の長さが見つかりません。再生リストのページ(/playlist?list=...)を開き、リストを下までスクロールして読み込んでから実行してください。');return;}var lines=['本数: '+count+'本','合計: '+fmt(total),'平均: '+fmt(total/count),'1.25倍速: '+fmt(total/1.25),'1.5倍速: '+fmt(total/1.5),'2倍速: '+fmt(total/2)];var text=lines.join('\n');var o=document.getElementById('yt-pl-panel');if(o){o.remove();return;}var p=document.createElement('div');p.id='yt-pl-panel';p.style.cssText='position:fixed;top:60px;right:16px;width:300px;background:#fff;border:1px solid #ddd;border-top:3px solid #f00;border-radius:4px;z-index:99999;padding:12px 16px;font-size:14px;font-family:sans-serif;box-shadow:0 4px 16px rgba(0,0,0,.2)';var hdr=document.createElement('div');hdr.style.cssText='display:flex;justify-content:space-between;align-items:center;margin-bottom:10px';var ttl=document.createElement('span');ttl.style.cssText='color:#f00;font-weight:bold';ttl.textContent='再生リストの合計時間';var btns=document.createElement('div');var cp=document.createElement('button');cp.style.cssText='padding:3px 10px;background:#f00;color:#fff;border:none;border-radius:3px;cursor:pointer;font-size:12px;margin-right:6px';cp.textContent='コピー';var cl=document.createElement('button');cl.style.cssText='background:none;border:none;font-size:16px;cursor:pointer';cl.textContent='×';btns.appendChild(cp);btns.appendChild(cl);hdr.appendChild(ttl);hdr.appendChild(btns);p.appendChild(hdr);var body=document.createElement('div');body.style.cssText='line-height:1.9;color:#333';lines.forEach(function(l){var row=document.createElement('div');var i=l.indexOf(':');var k=document.createElement('span');k.style.cssText='color:#888;display:inline-block;min-width:84px';k.textContent=l.slice(0,i);var v=document.createElement('span');v.style.cssText='font-weight:bold';v.textContent=l.slice(i+1).trim();row.appendChild(k);row.appendChild(v);body.appendChild(row);});p.appendChild(body);document.body.appendChild(p);cl.onclick=function(){p.remove();};cp.onclick=function(){navigator.clipboard.writeText(text).then(function(){cp.textContent='コピーしました';setTimeout(function(){cp.textContent='コピー';},2000);}).catch(function(){cp.textContent='失敗';setTimeout(function(){cp.textContent='コピー';},2000);});};})(); 登録手順
- ブックマークバーを右クリックして、新しいブックマークを作る
- 名前を「合計時間」など分かりやすいものにする
- URL欄に上のコードを貼り付けて保存する
使い方
- 再生リストのページ(
youtube.com/playlist?list=...)を開く - リストの最後までスクロールして、すべての動画を読み込む
- ブックマークレットをクリックする
- 右側に本数・合計時間・平均・倍速時の所要時間が表示される
- コピーボタンで結果をクリップボードに取得できる
- もう一度クリックするとパネルが閉じる
動画ページ右側に出る再生リストのパネル上でも動くが、読み込まれている動画だけが対象になる。正確に出したいときは再生リスト専用ページで最後までスクロールしてから実行するとよい。
どう動いているか
まず、再生時間の文字列(12:34 や 1:02:03)を秒数に変換する関数を用意する。コロンで分割して、時・分・秒に重み付けして足すだけだ。
// "12:34" や "1:02:03" を秒数に変換する
function toSec(t) {
const p = t.trim().split(':').map(Number);
if (p.some(isNaN)) return 0;
return p.length === 3 ? p[0] * 3600 + p[1] * 60 + p[2] : p[0] * 60 + p[1];
}
次に、各動画の行(ytd-playlist-video-renderer など)を取得し、その行の中から再生時間を探す。YouTubeはレイアウトを段階的に新しいWebコンポーネントへ移行していて、再生時間バッジの要素名やクラスがページによって違う。そこで、よく使われるバッジ要素(旧来の ytd-thumbnail-overlay-time-status-renderer と、新レイアウトの .badge-shape-wiz__text)をまず試し、見つからなければ行内から「12:34」のような時刻だけのテキストを拾う二段構えにしている。1行につき時間は1つだけ取るので二重カウントを防げて、ライブ配信中(「ライブ」表示)や公開予定の動画は時間が取れずに自然と除外される。
// 各動画の行を取得する(再生リストページ/視聴ページ右側の両方に対応)
let rows = document.querySelectorAll(
'ytd-playlist-video-renderer, ytd-playlist-panel-video-renderer'
);
// 新レイアウト(lockup)などで見つからなければ汎用の動画カードを使う
if (!rows.length) {
rows = document.querySelectorAll('yt-lockup-view-model, ytd-video-renderer');
}
const reTime = /\d{1,2}:\d{2}(?::\d{2})?/; // 文字列の中の「12:34」を拾う
const reTimeFull = /^\d{1,2}:\d{2}(?::\d{2})?$/; // 「12:34」だけのテキスト
// 1行から再生時間を1つだけ取り出す(二重カウントを防ぐ)
function rowTime(row) {
// よく使われるバッジ要素を優先(旧/新レイアウト両対応)
const badge = row.querySelector(
'ytd-thumbnail-overlay-time-status-renderer, .badge-shape-wiz__text'
);
if (badge) {
const m = badge.textContent.match(reTime);
if (m) return m[0];
}
// 見つからなければ行内から「12:34」だけのテキストを探す
for (const el of row.querySelectorAll('span, div')) {
const t = el.textContent.trim();
if (reTimeFull.test(t)) return t;
}
return null; // ライブ配信中・公開予定などは時間がないので除外される
}
let total = 0, count = 0;
rows.forEach((row) => {
const t = rowTime(row);
if (!t) return;
total += toSec(t);
count++;
}); 万一どの行も拾えなかったときの保険として、ページ全体から「時刻だけ」の要素を直接集めるフォールバックも入れてある。これで再生リストページでも視聴ページ右側のリストでも、レイアウトが新旧どちらでも合算できる。
最後に、合計秒数を「◯時間◯分◯秒」の形に整え、平均と倍速時の所要時間を並べて表示する。倍速で見る人向けに、1.25倍・1.5倍・2倍で再生した場合の所要時間も計算している。
// 秒数を「3時間12分5秒」の形に整える
// ※ ブックマークレット(javascript: URL)は実行前にURLデコードされるため、
// 剰余演算子 % を書くと %36 などのエスケープと誤読されて壊れる。
// そのため % を使わず引き算で分・秒を求めている。
function fmt(sec) {
sec = Math.round(sec);
const h = Math.floor(sec / 3600);
const m = Math.floor((sec - h * 3600) / 60);
const s = sec - h * 3600 - m * 60;
return (h ? h + '時間' : '') + (m ? m + '分' : '') + s + '秒';
}
const lines = [
'本数: ' + count + '本',
'合計: ' + fmt(total),
'平均: ' + fmt(total / count),
'1.25倍速: ' + fmt(total / 1.25),
'1.5倍速: ' + fmt(total / 1.5),
'2倍速: ' + fmt(total / 2),
]; 注意
- 画面に読み込まれた動画だけが対象。リストが長い場合は最後までスクロールしてから実行する。
- 非公開・削除された動画は時間バッジが出ないため合算されない。
- ライブ配信中の動画は時間が確定しないため除外される。
- YouTubeのDOM構造が変わると動作しなくなる可能性がある。
関連記事
- YouTubeのコメントからタイムスタンプを抽出するブックマークレット
- YouTubeでもっとも再生された部分の時刻を取り出すブックマークレット
- YouTube動画の再生速度を自由に変更する方法(Chrome)
- YouTubeのサムネイル画像を取得・保存する方法
- ページ内の画像を一覧表示・一括取得するブックマークレット
よくある質問
- YouTubeの再生リストの合計時間を調べるには?
- ブックマークレットを使うと、再生リストのページで各動画の長さを合算して合計再生時間を表示できる。すべての動画を読み込んでからクリックするだけで、本数や平均の長さも分かる。
- 合計時間が実際より短く出るのはなぜ?
- YouTubeは画面に表示された分の動画だけを読み込む。リストが長いと下のほうが未読み込みのことがあるので、最後までスクロールしてから実行すると全件が合算される。
- 倍速で見たときの所要時間も分かる?
- 合計時間に加えて1.25倍・1.5倍・2倍で再生した場合の所要時間も表示する。講座やまとめ再生リストを倍速で消化するときの目安に使える。