node-aribtsを使ってみる

この記事は DTV Advent Calendar 2015 10日目の記事です。

前回、nodeでMPEG-2 TSを扱えるnode-aribts をつくったという話でしたが、実際にそれを使って何が出来るのか、サンプルを紹介したいと思います。

TSのドロップをチェックする

aribts.TsStreamは名前の通り、TSのストリームで、SIや情報などのイベントを発生させます。
ドロップはdropイベントで取得できます。
また、全体の情報はinfoイベントで取得できます。
以下のサンプルでは、ドロップの出力と、全体の情報の一覧を表示します。

"use strict";

const fs = require("fs");
const aribts = require("aribts");
const TsStream = aribts.TsStream;

const readStream = fs.createReadStream(process.argv[2]);
const tsStream = new TsStream();

readStream.pipe(tsStream);

tsStream.on("data", () => {});

tsStream.on("drop", pid => {
    console.log(pid: 0x${("000" + pid.toString(16)).slice(-4)});
});

tsStream.on("info", data => {
    console.log("");
    console.log("info:");
    Object.keys(data).forEach(key => {
        console.log(0x${("000" + parseInt(key, 10).toString(16)).slice(-4)}: packet: ${data[key].packet}, drop: ${data[key].drop}, scrambling: ${data[key].scrambling});
    });
});

現在の番組情報を取得する

時間や番組情報などはaribts.TsUtilを使うと簡単に処理できます。
tsUtil.add~を使うことによって、SIを追加し、それぞれ適切に処理してくれます。
例えば、時間はTDTまたはTOT、サービスはSDT、そして番組情報はEITを入力すると取得できるようになります。
以下のサンプルでは、最初から30秒後に現在の番組情報を出力します。

"use strict";

const fs = require("fs");
const util = require("util");
const aribts = require("aribts");
const TsStream = aribts.TsStream;
const TsUtil = aribts.TsUtil;

const readStream = fs.createReadStream(process.argv[2]);
const tsStream = new TsStream();

const tsUtil = new TsUtil();

var time = null;
var ids = null;

readStream.pipe(tsStream);

tsStream.on("data", () => {});

tsStream.on("eit", (pid, data) => {
    tsUtil.addEit(pid, data);

    if (time === null) {
        if (tsUtil.isTime()) {
            time = tsUtil.getTime();
        } else {
            return;
        }
    }

    if (ids === null) {
        if (tsUtil.isOriginalNetworkId() && tsUtil.isTransportStreamId() && tsUtil.isServiceIds()) {
            ids = {
                onid: tsUtil.getOriginalNetworkId(),
                tsid: tsUtil.getTransportStreamId(),
                sid: tsUtil.getServiceIds()[0]
            };
        } else {
            return;
        }
    }

    if (tsUtil.getTime().getTime() - time.getTime() < 30 * 1000) return;
    if (!tsUtil.isPresent(ids.onid, ids.tsid, ids.sid)) return;

    console.log(util.inspect(tsUtil.getPresent(ids.onid, ids.tsid, ids.sid), {depth: null}));

    tsStream.removeAllListeners();
    readStream.unpipe(tsStream);
    tsStream.end();
});

tsStream.on("sdt", (pid, data) => {
    tsUtil.addSdt(pid, data);
});

tsStream.on("tdt", (pid, data) => {
    tsUtil.addTdt(pid, data);
});

tsStream.on("tot", (pid, data) => {
    tsUtil.addTot(pid, data);
});

以下がサンプルの出力です。

{ table_id: 78,
  version_number: 29,
  event_id: 18974,
  start_time: Thu Jan 15 2015 02:45:00 GMT+0900 (東京 (標準時)),
  duration: 1800,
  running_status: 0,
  free_CA_mode: 0,
  short_event:
   { table_id: 78,
     version_number: 29,
     ISO_639_language_code: 'jpn',
     event_name: '[新]水曜アニメ・水もん ガールズ&パンツァー',
     text: ' ' },
  extended_event:
   { table_id: 78,
     version_number: 29,
     ISO_639_language_code: 'jpn',
     items:
      { '◇番組内容': ' ',
        '◇出演者': '西住 みほ: 渕上 舞rn武部 沙織: 茅野 愛衣rn五十鈴 華: 尾崎 真実rn秋山
優花里: 中上 育実rn冷泉 麻子: 井口 裕香',
        '◇監督・演出': '監督:水島 努/構成・脚本:吉田玲子/キャラクター原案:島田フミカネ/キャラ
クターデザイン・総作画監督:杉本 功',
        '◇制作': 'アニメーション制作:アクタス' },
     text: '' },
  component:
   { table_id: 78,
     version_number: 29,
     stream_content: 1,
     component_type: 179,
     component_tag: 0,
     ISO_639_language_code: 'jpn',
     text: '映像',
     component_text: '映像1080i(1125i)、アスペクト比16:9 パンベクトルなし' },
  content:
   { table_id: 78,
     version_number: 29,
     contents:
      [ { content_nibble_level_1: 7,
          content_nibble_level_2: 0,
          user_nibble_1: 15,
          user_nibble_2: 15,
          content_nibble_level_1_text: 'アニメ/特撮',
          content_nibble_level_2_text: '国内アニメ' } ] },
  audio_component:
   { table_id: 78,
     version_number: 29,
     stream_content: 2,
     component_type: 3,
     component_tag: 16,
     stream_type: 15,
     simulcast_group_tag: 255,
     ES_multi_lingual_flag: 0,
     main_component_flag: 1,
     quality_indicator: 1,
     sampling_rate: 7,
     ISO_639_language_code: 'jpn',
     text_char: '日本語',
     audio_mode_text: '2/0モード(ステレオ)',
     quality_indicator_text: 'モード1',
     sampling_rate_text: '48kHz' } }

まだまだですが…

まだ開発途中のため、バグがあったり、大幅な仕様変更もあるかもしれませんが、暖かい目で見ていただければと思います。
明日は、(私の大いなる圧力で)ろっとさんです。CATVの話らしいので気になる…

コメントを残す