長いyoutubeにチャプターを付ける
youtubeに投稿する時は簡単にできるようですが見る側ではできないようなので作りました
1.お手本
プレーヤー右側のリストをクリックするとシークするようになっている
2.概要
数個のチャプターで区切る予定のためプレーヤーの上にタブを配置してシークする
シークは youtube APIを使う
3.コード
1)タグレイアウト
タブ用のラジオボタンとプレーヤーで構成してボタンが押されたらシークする
<body> <div class="entry-content"> <div class="iframe_tag"> <ul> <li><label> <input id="radio_name_w102si_0" name="radi_id_w102si_1_0" type="radio"> </input> <em>00:00:00<br>button text</em></label> </label></li> </ul> </div> <div> <iframe width="560" height="315" src="URL" name="iframe_window_name" frameborder="0" allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe> <div id="player_for_api_w102si_0"> </div> </body>
2)javascript
はてなブログに消されるタグがあるので全部javascriptで書いた
<script>// <![CDATA[ // // 定数定義 // play_list=[start time,text] videoID_for_api = 'JBDvKZxt3xo'; play_list = [ ['00:00:00','1日目 観光'], ['00:01:12','2日目 RCDEスタジアム'], ['00:02:58','3日目 5月15日 想唱就唱'] ]; div_class_name = 'iframe_tab'; // get uniqe entry ID elements_entry = document.getElementsByClassName("entry-content"); index_entry = elements_entry.length - 1; index_idp = '_' + index_entry; var player; // // function // radio button click コールバック関数 // cliclで player.seekTo function set_start_time(e) { var btn_id = e.target.id; // click button id var uids = btn_id.split( '_' ); var uid = uids[2]; // unique id for (var i = 0; i < play_list.length; i++) { // i番目のボタンが押されたかを判定 if ( btn_id == ('radiocl_' + i + '_' + uid) ) { break; } } start_time = Date.parse("1970-01-01T" + play_list[i][0]); var org_time = Date.parse("1970-01-01T00:00:00"); start_time = (start_time - org_time) / 1000; player.seekTo(start_time); document.getElementById(btn_id).checked = false; } // make iframe_radio_tabS LIST // 下記タブを展開 // // <div class="iframe_radio"> // <ul> // <li><label> // <input type="radio" id="seek_0"></button> // <em>00:00:00<br> button text</em> // </label></li> // // div tag を div class="entry-content" に配置 // var element_div_entry = document.getElementByClassName("entry-content"); var div_tag = document.createElement('div'); div_tag.className = div_class_name; div_tag.id = 'div_tag' + index_idp; elements_entry[index_entry].appendChild(div_tag); var element_div_tag = document.getElementById(div_tag.id); // ul tag var ul_tag = document.createElement('ul'); ul_tag.id = 'ul_tag' + index_idp; element_div_tag.appendChild(ul_tag); var element_ul_tag = document.getElementById(ul_tag.id); // li tag for (var i = 0; i < play_list.length; i++) { var li_tag = document.createElement('li'); li_tag.id = 'li_tag' + i + index_idp; element_ul_tag.appendChild(li_tag); var element_li_tag = document.getElementById(li_tag.id); // label tag var label_tag = document.createElement('label'); label_tag.id = 'label_tag' + i + index_idp; element_li_tag.appendChild(label_tag); var element_label_tag = document.getElementById(label_tag.id); // input tag radio button var input_radio = document.createElement('input'); input_radio.type = "radio"; input_radio.id = 'radiocl_' + i + index_idp; element_label_tag.appendChild(input_radio); // clickイベント定義 player seek input_radio.addEventListener("click", function (e) { set_start_time(e); }); var element_input_radio = document.getElementById(input_radio.id); // em tag radio buttonタグ表示テキストを設定 var em_tag = document.createElement('em'); em_tag.id = 'em_tag_id' + i + index_idp; element_label_tag.appendChild(em_tag); document.getElementById(em_tag.id).innerHTML=play_list[i][0] + '<br> ' + play_list[i][1]; var element_label_tag = document.getElementById(em_tag.id) } // ]]></script> <div id="player_for_api"> </div> <script>// <![CDATA[ // // 2. This code loads the IFrame Player API code asynchronously. var tag = document.createElement('script'); tag.src = "https://www.youtube.com/iframe_api"; var firstScriptTag = document.getElementsByTagName('script')[0]; firstScriptTag.parentNode.insertBefore(tag, firstScriptTag); // Functions // // プレーヤー API コードがダウンロードされると実行される // iframe をつくる // 各イベントに処理関数を割付けておく // 3. This function creates an <iframe> (and YouTube player) // after the API code downloads. //var player; function onYouTubeIframeAPIReady() { player = new YT.Player('player_for_api', { height: '315', width: '560', videoId: videoID_for_api, events: { 'onReady': onPlayerReady, //'onStateChange': onPlayerStateChange } }); } // API Event:onReady プレヤー準備完了 // 4. The API will call this function when the video player is ready. function onPlayerReady(event) { //event.target.playVideo(); // auto play } // API Event:onPlayerStateChange プレーヤーの状態変化イベント(再生、一時停止、終了など) // 5. The API calls this function when the player's state changes. // 未使用消去 // ]]></script> <script>// <![CDATA[ // // remove keyword link addEventListener( "DOMContentLoaded", function(){ var a=document.getElementsByClassName("iframe_tab"); if(a) for(var i=0;i<a.length;i++) for(var b=a[i].getElementsByClassName("keyword");b.length;) b[0].outerHTML=b[0].textContent}, !1); // ]]></script>
3)css
/* W102_ifram_tab.css ・class <div class="iframe_tag"> ・レイアウト 横並び 等間隔均等幅 ・width: 560px; ・color: #fff; background: #d80066; TAG LIST <body> <div class="iframe_tag"> <ul> <li><label><script> <input> </script> <em>TAG TITLE</em> </label></li> </ul> </div> </body> */ /* ul tag */ .iframe_tab ul{ display:flex; list-style: none; padding: 0; margin: 0; width: 560px; } /* li tag */ .iframe_tab li { list-style-type: none !important; padding: 0 !important; margin: 0 !important; width: 100%; } /* em(label) tag */ .iframe_tab em { display:block; margin-right: 1px; padding: 4px 4px 0; color: #d80066; background: #f7c0c0; text-align: left; font-size: 12px; font-style: normal; cursor: pointer; } /* radio button display */ .iframe_tab input[type="radio"] { display: none; } /* radio button checked */ .iframe_tab input[type="radio"]:checked + em { background: #d80066; color: #fff; } /* radio button hover */ .iframe_tab input[type="radio"] + em:hover { background: #d80066; color: #fff; }
4.完成
続く