srt.js開発用ドキュメント


facebookの開発者コミュニティはこちらです: https://www.facebook.com/groups/srtjsdev/
srt.js自体のソースコードはこちらで公開しています: https://github.com/qurihara/srt.js
srt.jsのサンプル集はこちらで随時追加していきます: https://github.com/qurihara/examples.srt.js

srt.jsとは?

srt.jsは、動画の字幕ファイルとして広く流通しているsrt形式テキストファイルの流儀で、実行時刻を指定したJavaScriptを記述したものです。動画再生に連動した任意のJavaScriptの実行を扱えるので、たとえばIoT機器やWebサービスと連携した動画鑑賞体験を実現することができます。特別なソフトウェアのインストールは必要ありません。ブラウザさえあれば、どんなデバイスでもすぐに実行可能です。どんなことができるかをまず知りたいかたはこちらを参照ください

主に対象として扱うのはYouTubeです。YouTubeは公式にsrt形式の字幕ファイルのアップロードをサポートしているので、あなたの投稿したYouTube動画に対し、srt.jsをアップロードすることができます。

また、第三者の公開しているYouTube動画に連動させたsrt.jsを実行させる仕組みも用意されています。

以下、JavaScriptの知識のある方を前提に、説明を進めていきます。
なお、もしご意見やご質問ある場合は@quriharaまでよろしくお願いします。私としてもsrt.jsの普及に取り組んでいきたいので、可能な範囲でサポートしたいと思います。

srt.jsの実行方法

srt.jsはYouTube公式サイト上で実行することはできません。(chrome拡張などの技術を使えば可能ですが、ドキュメントはまだありません。) そこで私が準備したwebサイト上で実行することをおすすめします。このwebサイトでは、YouTube動画とsrt.jsを読み込み、動画の再生と同期させてJavaScriptを実行していきます。その実行方法は以下の通りです。

(1)自分の投稿したYouTube動画にsrt.jsをアップロードした、もしくはYouTubeの字幕エディタでJavaScriptを記述した場合

↑XXXXXXXXXXXのところにYouTubeの11桁の動画IDを入れればすぐ使えます。

この場合、動画内に字幕としてJavaScriptが表示されないよう、YouTube側で設定を変更してください。(本ページ末尾「その他」を参照)

(2)誰かの投稿したYouTube動画に自分の作成したsrt.jsを組み合わせて実行したい場合

まず、DropBoxやGoogleDrive、github、自分のサーバなどを用いて、作成したsrt.jsをインターネットに公開し、URLを得てください。
そして、
のように動画IDとsrt.jsのURLを記述すれば実行できます。(上記はDropBoxを用いた例です。)

この場合、実行時に「このスクリプトは動画とは関係ない第三者の作成したものです。危険かもしれません」と表示されます。自己責任でお楽しみください。

上記実行サイトはiframeなどでご自身のサイトに組み込んだりできると思います。

2017/05/17追記:(2)の実行方法で、surlパラメータでsrt.jsを指定しなかった場合、動画プレイヤーの下部に、手元のコンピュータ内にあるsrt.jsをドラッグアンドドロップできる場所が表れます。ちょっとした開発にご活用ください。

srt.jsの書式

srt形式の字幕は、下記のように(1)通し番号 (2)字幕表示開始時刻 (3)字幕表示終了時刻 (4)表示する字幕テキスト(複数行にわたっても可) (5)字幕と字幕の区切りに使われる空行 の要素からなっています。この4つの要素のひとセットを「字幕区間」と呼ぶことにします。srt形式のファイルは1個以上の字幕区間を羅列した構造をしています。

srt形式の例:

1
00:00:05,000 --> 00:00:06,000
これは昔々の物語である。

2
00:02:51,000 --> 00:03:00,000
あるところにおじいさんとおばあさんが住んでいた。
おじいさんは山に芝刈りに行った。
おばあさんは川で洗濯をした。


srt.jsは、下記のようにsrt形式にのっとり、(4)の字幕テキストの代わりにその時刻で実行すべきスクリプトを記述します。

srt.js形式の例:

1
00:00:05,000 --> 00:00:06,000
// say hello
alert("hello!");

2
00:02:51,000 --> 00:03:00,000
// close browser tab at 2:51
window.open('about:blank','_self').close();


スクリプトは複数行にわたっても問題ありませんが、空行だけは使えません。(5)として扱われてしまうからです。どうしても空行を使いたい場合は、「//」のようにダブルスラッシュのみの行を使うなどして対応してください。(私がsrt.jsで実行時エラーを出すほとんどの理由が、この意図しない空行の存在によるものです。)

また、通常のスクリプトは時刻情報として(2)の開始時間だけが重要で、(3)の終了時間にはあまり意味はありません。あまり短くない、適当な時刻を指定してください。 ただし、後述するindexedFunctionを使うと、「ある関数呼び出しに対して字幕区間ごとに実行されるコードを切り替える」のような処理を行うことができます。その際は(3)の終了時間にも意味が出てきます。

2017/5/17追記:もし終了時刻に興味がない場合は、 たとえば「00:00:05,000 --> 00:00:06,000」に対して「00:00:05,000」のように、終了時刻を省略するかたちで記述する略記法をとることができるようにしました。その場合、暗黙に0.1秒の区間であると内部では解釈されます。また、この略記法を行うともはやsrt形式ではなくなるので、YouTubeにアップロードすることができなくなります。

ちなみに(1)の通し番号は、「実はほとんど意味はなくだいたいの場合どんな数字でも良い」ようです。途中で違うコードを挿入しようとした場合、通し番号を全部付け替えるのは苦痛ですよね。srt.jsの実行系では、通し番号はどんなテキストでも問題ありませんが、YouTube側がどのくらいゆるく許容してくれるかはよくわかりません。いろいろ試してみてください。



YouTubeの公式字幕エディタを用いたJavaScriptの記述方法

YouTubeであなたが投稿した動画には、下記のようにブラウザ上でYouTube公式のグラフィカルなエディタで字幕テキストを付与できます。これを用いて、字幕テキストの代わりに実行したいJavaScriptを記述し、保存することができます。こちらも合わせてご活用ください。




srt.js特有の記法、オブジェクト、ビルトイン関数

まず、前提としてsrt.jsは一つ一つの字幕要素ごとにスコープが独立しています。
たとえば

0
00:00:00,000 --> 00:00:01,000
var a=0;

1
00:00:26,000 --> 00:00:26,500
console.log(a);


などとしても、字幕要素0内で定義したaを字幕要素1内で用いることはできません。


0
00:00:00,000 --> 00:00:01,000
a=0;

1
00:00:26,000 --> 00:00:26,500
console.log(a);


とすることで、aはグローバル変数になるため、字幕要素間で共有することができます。
関数定義についても、


0
00:00:00,000 --> 00:00:01,000
f = function(a){
    alert(a);
}

1
00:00:26,000 --> 00:00:26,500
f("hello");


とすることで、fはどこからでもアクセスできる関数になるため、字幕要素間で共有することができます。

player

これはYouTubeのiframe埋め込みAPIの動画プレイヤーを参照するオブジェクトです。動画の再生制御、動画に関する情報取得等を行えます。
詳しくは
を参照ください。

使用例:

player.pauseVideo(); // 動画の一時停止
player.playVideo(); // 動画の再生
player.seekTo(22,true); // 再生位置の指定


index

これはsrt.jsの先頭からかぞえてどこの字幕区間にいるかを表すオブジェクトです。-1の場合、どの区間にも入っていません。
また、これはsrt形式の各字幕区間の冒頭の通し番号とは無関係に、srt.jsファイルの先頭から数えてゼロから始まる整数で、1ずつカウントアップします。

doOnce[index] = true;

この記述があった場合、その字幕要素は一度だけ実行されます。動画プレイヤーは時にユーザがシークバーによって巻き戻したりするため、初期設定等の複数回実行しない字幕要素はこの記述をしておきます。

使用例:

0
00:00:00,000 --> 00:00:01,000
//initialize
doOnce[index] = true;
console.log("initialized!");



この例では、何度動画を巻きもどしても、initialized!と表示されるのは最初の1回だけです。
doOnce[index] = true; の記述がなければ、何度でも表示されます。

なお、doOnce[4] = true; などと指定すれば、5番目の字幕区間に関する設定になります。

loadScript

これは外部Javascriptを読み込む組み込み関数です。第一引数に外部JavascriptへのURL、第二引数に読み込み完了時に実行するコールバック関数を指定します。下記はjqueryを読み込む例です。

使用例:

loadScript('//ajax.googleapis.com/ajax/libs/jquery/2.1.3/jquery.min.js',function(e){
    console.log("jquery loaded.");
});



indexedFunction

ある関数呼び出しに関して、字幕区間に応じて実行されるスクリプトを切り替える組み込み関数です。たとえばスマホのシェイクジェスチャ入力のイベントハンドラを、動画の再生区間に応じて切り替えることができます。

下記の使用例では、複数の本の紹介をする動画に対し、スマホのシェイクジェスチャがあった場合に再生位置に応じて異なる本のamazon購入サイトにナビゲートするsrt.jsです。

使用例:

1
00:00:00,000 --> 00:00:01,000
//bibliobattle
doOnce[index] = true;
vars.myfunc = {};
loadScript('//ajax.googleapis.com/ajax/libs/jquery/2.1.3/jquery.min.js',function(e){
loadScript('//rawgit.com/GerManson/gShake/master/lib/gShake.js',function(e2){
  $(document).ready(function() {
    $(this).gShake(function() {
      var fn = indexedFunction(vars.myfunc);
      if (fn != null) {
        fn.call(null);
      }
    });
  });
});
});

2
00:00:10,001 --> 00:08:06,000
//1st book
vars.myfunc[index] = function(){
  window.location.href ='https://www.amazon.co.jp/dp/4591132374';
}

3
00:08:06,001 --> 00:47:56,000
//2nd book
vars.myfunc[index] = function(){
  window.location.href ='https://www.amazon.co.jp/dp/4847093399/';
}


スクリプト例

の下の方で公開しているコンテンツ例では、私の書いた外部srt.jsを読み込んでいます。それでどのようなコンテンツがどのように動くかがわかると思います。ご参照ください。

また、webmoをつかう、milkcocoaでIoTする等、srt.jsのサンプル集はこちらで随時追加しています: https://github.com/qurihara/examples.srt.js

その他

YouTube公式webサイトを見ていて、この動画をsrt.jsサイトで開きたい!と思った時にワンクリックでできるブックマークレットがあります。よろしければご活用ください。https://github.com/qurihara/examples.srt.js/blob/master/youtube2srtjs_bookmarklet.js

埋め込んだJavaScriptが動画再生時に字幕テキストとして表示されてしまう設定になっている方は、以下の設定で切り替えることができます。