Skip to content

Instantly share code, notes, and snippets.

@kazuki0824
Last active November 3, 2022 15:30
Show Gist options
  • Save kazuki0824/91bcaf2c03644b6f62a268c9878da721 to your computer and use it in GitHub Desktop.
Save kazuki0824/91bcaf2c03644b6f62a268c9878da721 to your computer and use it in GitHub Desktop.
Mirakurunを活用した番組追従の仕様(かり)

最近のMirakurunの仕様(たぶん)

  1. Mirakurunは各チャンネルを定期的に巡回しEIT[schedule]を収集している
  2. MirakurunがチャンネルAを開いている(≒ユーザの指令でチャンネルAに選局されている)ときは、常にそのチャンネルのTSに含まれるEIT[schedule]とEIT[p/f]を収集している。EIT[p/f]を発見したときクライアントに通知を送ることもできる
  3. 逆に、それ以外のときはEITを捉えられない
  4. Mirakurun の Program Stream APIは少し高度な機能を持っていて、 「引数に与えられた番組が始まるまでは何もデータを返さず、始まったらデータを返し、終わったらコネクションを終了」するという挙動をする。区間を見定めるとき、EIT[p/f]も読んでいる。 ただ、イベントリレーみたいな高等処理まではしてくれない
  5. つまりPrograms Stream APIを使えば(番組がその時ちゃんと始まっていさえすれば)勝手に番組の終端まで録画してくれます。 ※ただし、放送前に時間が変更していて、かつその事実をMirakurunが捉えられていなかった場合、しばらくデータを待ったあとコネクションがタイムアウトしてしまう!

Mirakurunを活用した番組追従の仕様

そこで、以下のロジックで対象の番組Xを確実に録画することを目指す。

  1. Mirakurunの持つ番組表をもとに、スケジューラSに番組Xの情報を格納する

  2. Mirakurunの持つ番組表が変更されると、スケジューラS内部の番組Xの情報もそれに合わせてリアルタイムに同期する

  3. Xの録画対象時間の10分前になったら、「仮録画A」を開始する(TRによると最大360秒ごとにEIT[schedule]が送られるらしいから、こうすることでMirakurunに確実に1つ以上のEIT[schedule]を読ませることができる)

  4. 「仮録画A」を開始してから1時間経過した場合、タイムアウトする。

  5. 「仮録画A」中に、スケジューラSの持つ番組Xの放送開始時間を過ぎた場合、「仮録画B1」へ移行する。

  6. 「仮録画A/B1」中に、EIT[following]がスケジューラSの持つ番組Xのevent_idと一致した場合、Sの持つ番組Xのstartとdurationを更新し「仮録画B2」へ移行する。

  7. 「仮録画B2」中に、EIT[following]がスケジューラSの持つ番組Xのevent_idと一致した場合、Sの持つ番組Xのstartとdurationを更新する。

  8. 「仮録画B1」の状態で3時間経過した場合、タイムアウトする。

  9. 「仮録画A/B1/B2」中に、EIT[present]がスケジューラSの持つ番組Xのevent_idと一致した場合、Sの持つ番組Xのstartとdurationを更新し「本録画」へ移行する。

  10. 「仮録画B2」中に、EIT[present]にもEIT[following]にもSの持つ番組Xのevent_idと一致する情報がない状態になった場合、エラー終了する。(基本起こりえない)

  11. 「仮録画B2」中に、Sの持つ番組Xの番組終了時間を過ぎた場合、タイムアウトする。(基本起こりえない)

  12. 「本録画」中にMirakurunとの接続が切断されたときに、Sの持つ番組Xにイベントリレーの情報が存在する場合は、録画対象をリレー先の番組Yに変更する。(イベントリレー処理)

仮録画状態の説明

仮録画では、Mirakurun Services Stream API(ただ単一サービスを垂れ流すAPI)から録画予約された番組と同じサービスIDのTSをもらう。その際、ストリーム中のEIT[p/f]を追跡し、それに応じた状態遷移を行う。

  • 仮録画Aでは、読み取ったTSは捨てる。
  • 仮録画B1/B2では、読み取ったTSをバックアップとして保存する(拡張子*.m2ts.tmp)。
  • 仮録画B1は「番組表では予定の時間だけど、EIT[following]を見ても放送予定が確認できない」状態。
  • 仮録画B2は「EIT[following]に予約対象がいる」状態。このとき次の番組が確実に予約対象の番組であることが確定している。

本録画状態の説明

  • 一方、本録画では、Mirakurun Programs Stream APIを利用してTSを本録画データとして保存する(拡張子*.m2ts)。本録画中のeventが終了するとMirakurun側が接続を切断してくるので、イベントリレーがあれば録画対象を切り替えて再試行し、なければ終了する。
  • 本録画中のeventが終了するとMirakurun側が接続を切断してくるので、このときイベントリレーがあれば録画対象を切り替えて同様の操作を再試行し、なければ終了する。

参考資料

https://twitter.com/TVRemotePlus/status/1556283315803815936?s=20&t=97zNX_DmylJ2VxGZovSWeQ 上記の先人の知恵をベースにMirakurunの機能をフル活用(=自前実装をサボる)した追従ロジックを考えてみました。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment