【JavaScript】YouTubeの字幕を時間指定リンク付きhtmlで出力

この記事は最新更新日から、1年以上経過しています。

概要

YouTubeで適当な動画を開き、ブラウザのconsoleで実行すると字幕がリンク付きで取れるスクリプトです。
GoogleChromeで動作確認しました。

下記のようなhtmlが取れます。まともな字幕のある動画などでそこそこ便利です。

<hr />
<h4>2010/05/05 サイモン シネック: 優れたリーダーはどうやって行動を促すか</h4><br />
<a rel="noopener" href="https://www.youtube.com/watch?v=qp0HIF3SfI4&amp;t=0" target="_blank">00:00</a><br />
<a rel="noopener" href="https://www.youtube.com/watch?v=qp0HIF3SfI4&amp;t=NaN" target="_blank">翻訳: Natsuhiko Mizutani 校正: Yasushi Aoki</a><br />
<a rel="noopener" href="https://www.youtube.com/watch?v=qp0HIF3SfI4&amp;t=16" target="_blank">00:16</a><br />
物事がうまく行かなかったときに<br />
<br />
<a rel="noopener" href="https://www.youtube.com/watch?v=qp0HIF3SfI4&amp;t=18" target="_blank">00:18</a><br />
それをどう説明しますか?<br />

コード

// 字幕を開く
document.querySelectorAll('ytd-engagement-panel-section-list-renderer.style-scope.ytd-watch-flexy')[0].visibility = 'ENGAGEMENT_PANEL_VISIBILITY_EXPANDED';
let log = function(){
    // html作成
    let sep = '<br />\n';
    let loc = location.href;
    let video_id = loc.split('v=')[1].split('&list')[0];
    let jimaku = document.getElementsByTagName('ytd-transcript-body-renderer')[0].innerText.split('\n');
    let info = document.querySelectorAll('yt-formatted-string.style-scope.ytd-video-primary-info-renderer');
    let title = info[1].innerText;
    let date = info[2].innerText;

    let text = '<hr />\n<h4>'+ date +' '+ title +'</h4>' + sep;
    let titleTag = '<title>'+ date +' '+ title +'</title>';

    for(let i=0; i<jimaku.length; i++){
        if(jimaku[i].indexOf(':') > -1){
            // タイムスタンプ
            let timeStampCode = jimaku[i];

            let time = (function(){
                let time = jimaku[i].split(':');
                let h = 0;
                let m = 0;
                let s = time;
                if(time.length === 3){
                    h = parseInt(time[0]) * 60 * 60;
                    m = parseInt(time[1]) * 60;
                    s = parseInt(time[2]);
                }else if(time.length === 2){
                    m = parseInt(time[0]) * 60;
                    s = parseInt(time[1]);
                }else {
                    s = parseInt(time);
                }
                return h + m + s;
            }());
            text += '<a rel="noopener" href="https://www.youtube.com/watch?v='+ video_id +'&amp;t='+time+'" target="_blank">'+ timeStampCode +'</a>' + sep;

        }else{
            // 字幕
            text += jimaku[i] + sep + sep;
        }
    }
    console.log(text);
    console.log(titleTag);
};
// 1.5秒後に字幕回収(これがないと字幕パネルを開く前に回収しようとしてエラーになります)
setTimeout(log, 1500);

おまけ

生成されたhtmlを貼り付ける用のhtmlです。

<!DOCTYPE html>
<html lang="ja">
<head>
  <meta charset="UTF-8" />
  <title>字幕からリンク</title>
</head>
<body>

</body>
</html>

おわり