@danything/arib 1.2.0 → 1.2.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,17 +1,17 @@
1
1
  # @danything/arib
2
2
 
3
3
  日本のデジタル放送 (ISDB-T / ISDB-S、ARIB 規格) の MPEG-TS を TypeScript で読むライブラリです。
4
- 録画サーバー [denpa](https://github.com/danything/denpa) の中で使っているものを切り出しました。
5
-
6
- - **PSI** — パケットの切り出し、セクションの組み立て、PAT / PMT / SDT / NIT (`psi`)。衛星はネットワークの全部の TS の NIT と、ほかの TS の SDT もそろえて読む
7
- - **PES** — 映像・音声の PES と ADTS (`pes`)
8
- - **番組表** — EIT[p/f] と EIT[schedule]。ジャンル・音声・拡張形式イベント・シリーズ記述子まで (`eit`)
9
- - **ARIB の文字** — STD-B24 の8単位符号 (JIS X 0213 の1面・2面まで) と ARIB 外字 (`aribtext`、`aribtext-gaiji`)
10
- - **字幕** — STD-B24 の字幕文を、字の置き場所まで決めた JSON にする (`b24caption`、形式は `caption-text`)
11
- - **データ放送** — DSM-CC のカルーセルからモジュールとファイルを組み立てる (`dsmcc`、`multipart`、`bml`、形式は `bml-protocol`)
12
- - **Hybridcast の AIT** (`ait`)、**1つの局だけを抜き出す** (`service-filter`)
13
- - **試験用の TS を組み立てる** — PSI・EIT・字幕・カルーセル・映像と音声 (`synth`、`synth-caption`、`synth-av`)
14
- - 下で使う道具 — バイト列 (`bytes`)、言語の名前 (`language`)、文字の表 (`b24-tables`)、字幕の外字の画像をなめらかにする (`drcs-smooth`)
4
+ 録画サーバ [denpa](https://github.com/danything/denpa) の中で使っているものを切り出しました。
5
+
6
+ - PSI (`psi`): パケットの切り出し、セクションの組み立て、PAT / PMT / SDT / NIT。衛星はネットワークの全部の TS の NIT と、ほかの TS の SDT もそろえて読む
7
+ - 映像・音声の PES と ADTS を取り出す (`pes`)
8
+ - 番組表の EIT[p/f] と EIT[schedule] を、ジャンル・音声・拡張形式イベント・シリーズ記述子まで読む。放送の時刻 (TDT / TOT) もここ (`eit`)
9
+ - ARIB STD-B24 の 8 単位符号 (JIS X 0213 の 1 面・2 面まで) と ARIB 外字を文字列にする (`aribtext`、`aribtext-gaiji`)
10
+ - 字幕は STD-B24 の字幕文を、字の置き場所まで決めた JSON にする (`b24caption`、形式は `caption-text`)
11
+ - データ放送は DSM-CC のカルーセルからモジュールとファイルを組み立てる (`dsmcc`、`multipart`、`bml`、形式は `bml-protocol`)
12
+ - Hybridcast の AIT を読む (`ait`)。1 つの局だけを抜き出す (`service-filter`)
13
+ - 試験用の TS (PSI・EIT・字幕・カルーセル・映像と音声) を組み立てる (`synth`、`synth-caption`、`synth-av`)
14
+ - ほかのモジュールが使う道具として、バイト列 (`bytes`)、言語の名前 (`language`)、文字の表 (`b24-tables`)、字幕の外字の画像をなめらかにする処理 (`drcs-smooth`)
15
15
 
16
16
  依存するパッケージはありません。
17
17
 
@@ -35,7 +35,7 @@ const epg = new EpgReader();
35
35
  for await (const chunk of stream) {
36
36
  // 長さはそろっていなくてよい
37
37
  if (epg.feed(chunk)) {
38
- // 返るのは開始時刻の決まった番組だけ
38
+ // 返るのは開始時刻と尺の決まった番組だけ
39
39
  for (const event of epg.takeChanged()) {
40
40
  console.log(event.serviceId, new Date(event.startAt!), event.name);
41
41
  }
@@ -53,7 +53,7 @@ decodeAribText(bytes); // "🈟ニュース"
53
53
  import { B24CaptionDecoder } from "@danything/arib/b24caption";
54
54
 
55
55
  const captions = new B24CaptionDecoder();
56
- // 字幕の PES の中身 (データ識別 0x80 から) を1つずつ渡す
56
+ // 字幕の PES の中身 (データ識別 0x80 から) を 1 つずつ渡す
57
57
  const page = captions.decode(pesPayload);
58
58
  if (page !== null) draw(page); // 形式は caption-text.ts の CaptionPage
59
59
  ```
package/dist/ait.d.ts CHANGED
@@ -8,7 +8,7 @@
8
8
  * ```
9
9
  * PMT ─ ES に application_signalling_descriptor (0x6F) ─→ その PID に AIT
10
10
  * AIT ─ transport_protocol_descriptor (URL の頭)
11
- * └ simple_application_location_descriptor (その先のパス) → アプリのURL
11
+ * └ simple_application_location_descriptor (その先のパス) → アプリの URL
12
12
  * ```
13
13
  *
14
14
  * ここは読んで在ることを言うだけです。開くのはデータ放送が起動を求めたときで
@@ -59,39 +59,39 @@ export interface Ait {
59
59
  /**
60
60
  * PMT から「AIT が流れている PID」を読み取る。
61
61
  *
62
- * **記述子が付いている ES を見るだけ。** `stream_type` では決められません —
62
+ * **記述子が付いている ES を見るだけ。** `stream_type` では決められません。
63
63
  * AIT は DSM-CC セクション (0x0D) で運ばれ、データ放送のカルーセルと同じ型を
64
64
  * 名乗るので、型だけでは見分けが付きません
65
65
  */
66
66
  export declare function aitPidsFromPmt(section: Uint8Array): number[];
67
67
  /**
68
- * AIT のセクションを1つ読む。**壊れていたら `null`** (放送は途中から読むので、
68
+ * AIT のセクションを 1 つ読む。**壊れていたら `null`** (放送は途中から読むので、
69
69
  * 読めないものが来るのは普通のこと)
70
70
  */
71
71
  export declare function parseAit(section: Uint8Array): Ait | null;
72
72
  /**
73
73
  * TS から Hybridcast のアプリを見つける。
74
74
  *
75
- * **PMT を見てから AIT を読む** という2段なので、繋いだ直後は何も返しません。
75
+ * **PMT を見てから AIT を読む** という 2 段なので、繋いだ直後は何も返しません。
76
76
  * 局を変えたら作り直します。
77
77
  *
78
- * 局に Hybridcast が無ければ、**PMT に印が無い**ので AIT を待つこともしません
79
- * — その局では永久に何も返さないのが正しい振る舞いです。
78
+ * 局に Hybridcast が無ければ、**PMT に印が無い**ので AIT を待つこともしません。
79
+ * その局では永久に何も返さないのが正しい振る舞いです。
80
80
  */
81
81
  export declare class AitReader {
82
82
  private readonly packets;
83
83
  private readonly pmt;
84
- /** AIT を組み立てるもの。PID ごとに1つ */
84
+ /** AIT を組み立てるもの。PID ごとに 1 つ */
85
85
  private aits;
86
86
  constructor(serviceId: number);
87
87
  /**
88
- * TS を食べて、見つかったものを返す。**見つからない間は空**。
88
+ * TS を読んで、見つかったものを返す。**見つからない間は空**。
89
89
  *
90
- * 同じものが何度も返るのは呼ぶ側で畳んでください — 放送は同じ表を
90
+ * 同じものが何度も返るのは呼ぶ側で畳んでください。放送は同じ表を
91
91
  * 繰り返し流すので、ここで覚えると「局を変えても消えない」になります
92
92
  */
93
93
  feed(chunk: Uint8Array): Ait[];
94
- /** 切り分け済みのパケットを1つ。見つかったものは `found` に足す (`BmlDecoder.feedPacket` と同じ事情) */
94
+ /** 切り分け済みのパケットを 1 つ。見つかったものは `found` に足す (`BmlDecoder.feedPacket` と同じ事情) */
95
95
  feedPacket(packet: Uint8Array, found: Ait[]): void;
96
96
  }
97
97
  export {};
package/dist/ait.js CHANGED
@@ -8,7 +8,7 @@
8
8
  * ```
9
9
  * PMT ─ ES に application_signalling_descriptor (0x6F) ─→ その PID に AIT
10
10
  * AIT ─ transport_protocol_descriptor (URL の頭)
11
- * └ simple_application_location_descriptor (その先のパス) → アプリのURL
11
+ * └ simple_application_location_descriptor (その先のパス) → アプリの URL
12
12
  * ```
13
13
  *
14
14
  * ここは読んで在ることを言うだけです。開くのはデータ放送が起動を求めたときで
@@ -56,7 +56,7 @@ export const CONTROL = {
56
56
  /**
57
57
  * PMT から「AIT が流れている PID」を読み取る。
58
58
  *
59
- * **記述子が付いている ES を見るだけ。** `stream_type` では決められません —
59
+ * **記述子が付いている ES を見るだけ。** `stream_type` では決められません。
60
60
  * AIT は DSM-CC セクション (0x0D) で運ばれ、データ放送のカルーセルと同じ型を
61
61
  * 名乗るので、型だけでは見分けが付きません
62
62
  */
@@ -92,8 +92,8 @@ function transportUrl(body) {
92
92
  /**
93
93
  * 名前を取り出す (application_name_descriptor)。
94
94
  *
95
- * 言語ごとに何本も入っていることがあるので**最初の1本**を採ります。中身は
96
- * ARIB の8単位符号なので、番組名と同じ方法で読みます (`aribtext.ts`)
95
+ * 言語ごとに何本も入っていることがあるので**最初の 1 本**を採ります。中身は
96
+ * ARIB の 8 単位符号なので、番組名と同じ方法で読みます (`aribtext.ts`)
97
97
  */
98
98
  function applicationName(body) {
99
99
  // [0..2] ISO_639_language_code, [3] application_name_length
@@ -105,7 +105,7 @@ function applicationName(body) {
105
105
  return decodeAribText(body.subarray(4, 4 + length)).trim();
106
106
  }
107
107
  /**
108
- * AIT のセクションを1つ読む。**壊れていたら `null`** (放送は途中から読むので、
108
+ * AIT のセクションを 1 つ読む。**壊れていたら `null`** (放送は途中から読むので、
109
109
  * 読めないものが来るのは普通のこと)
110
110
  */
111
111
  export function parseAit(section) {
@@ -159,24 +159,24 @@ export function parseAit(section) {
159
159
  /**
160
160
  * TS から Hybridcast のアプリを見つける。
161
161
  *
162
- * **PMT を見てから AIT を読む** という2段なので、繋いだ直後は何も返しません。
162
+ * **PMT を見てから AIT を読む** という 2 段なので、繋いだ直後は何も返しません。
163
163
  * 局を変えたら作り直します。
164
164
  *
165
- * 局に Hybridcast が無ければ、**PMT に印が無い**ので AIT を待つこともしません
166
- * — その局では永久に何も返さないのが正しい振る舞いです。
165
+ * 局に Hybridcast が無ければ、**PMT に印が無い**ので AIT を待つこともしません。
166
+ * その局では永久に何も返さないのが正しい振る舞いです。
167
167
  */
168
168
  export class AitReader {
169
169
  packets = new PacketStream();
170
170
  pmt;
171
- /** AIT を組み立てるもの。PID ごとに1つ */
171
+ /** AIT を組み立てるもの。PID ごとに 1 つ */
172
172
  aits = new Map();
173
173
  constructor(serviceId) {
174
174
  this.pmt = new PmtTracker(serviceId);
175
175
  }
176
176
  /**
177
- * TS を食べて、見つかったものを返す。**見つからない間は空**。
177
+ * TS を読んで、見つかったものを返す。**見つからない間は空**。
178
178
  *
179
- * 同じものが何度も返るのは呼ぶ側で畳んでください — 放送は同じ表を
179
+ * 同じものが何度も返るのは呼ぶ側で畳んでください。放送は同じ表を
180
180
  * 繰り返し流すので、ここで覚えると「局を変えても消えない」になります
181
181
  */
182
182
  feed(chunk) {
@@ -185,7 +185,7 @@ export class AitReader {
185
185
  this.feedPacket(packet, found);
186
186
  return found;
187
187
  }
188
- /** 切り分け済みのパケットを1つ。見つかったものは `found` に足す (`BmlDecoder.feedPacket` と同じ事情) */
188
+ /** 切り分け済みのパケットを 1 つ。見つかったものは `found` に足す (`BmlDecoder.feedPacket` と同じ事情) */
189
189
  feedPacket(packet, found) {
190
190
  const pid = packetPid(packet);
191
191
  const before = this.pmt.pid;
@@ -1,5 +1,5 @@
1
1
  /**
2
- * ARIB 外字。放送で使われる、JIS X 0208 の外にある文字の対応表 (85区から先)。
2
+ * ARIB 外字。放送で使われる、JIS X 0208 の外にある文字の対応表 (85 区から先)。
3
3
  *
4
4
  * 番組名の「🈟」「🈑」「🈞」([新][字][再]) はここにある。読めないと、番組表から
5
5
  * その印が丸ごと消えるか、化けた文字が並ぶ。
@@ -9,16 +9,16 @@
9
9
  * ([fold.ts](https://github.com/danything/denpa/blob/main/src/lib/fold.ts))。
10
10
  *
11
11
  * **字は字幕と同じ表を引く** ([b24-tables.ts](b24-tables.ts) の `ADDITIONAL`。ARIB STD-B24 表 7-19 /
12
- * STD-B62 表 5-2)。番組表で違えるのは下の `EPG_ONLY` だけ:
12
+ * STD-B62 表 5-2)。番組表で違えるのは下の `EPG_ONLY` だけで、次の 2 つ。
13
13
  *
14
- * - 92区56〜85点 (楽器の略号) は規格でも私用領域 (U+E2A5〜) にしか字が無い。どこでも読めるよう
14
+ * - 92 区 56〜85 点 (楽器の略号) は規格でも私用領域 (U+E2A5〜) にしか字が無い。どこでも読めるよう
15
15
  * 「(vn)」のような文字列に開く (字幕は私用領域のまま。フォントがその字形を持つ)
16
- * - 93区46・47点と87点は規格で空き。昔の表 (epgdump_py から ariblib に引き継がれた表) のとおり
16
+ * - 93 区 46・47 点と 87 点は規格で空き。昔の表 (epgdump_py から ariblib に引き継がれた表) のとおり
17
17
  * 中黒と全角の空白で埋める (字幕では空きのまま)
18
18
  *
19
19
  * 表で空き (U+FFFD) の点は持たない。`aribtext.ts` が「□」にする。
20
20
  *
21
- * 鍵は区点そのまま — 第1バイトが 0x20+区、第2バイトが 0x20+点。
21
+ * 鍵は区点そのまま (第 1 バイトが 0x20+区、第 2 バイトが 0x20+点)。
22
22
  */
23
23
  /** 番組表だけで違える字。区点 → 字 (上の説明) */
24
24
  export declare const EPG_ONLY: Map<number, string>;
@@ -1,5 +1,5 @@
1
1
  /**
2
- * ARIB 外字。放送で使われる、JIS X 0208 の外にある文字の対応表 (85区から先)。
2
+ * ARIB 外字。放送で使われる、JIS X 0208 の外にある文字の対応表 (85 区から先)。
3
3
  *
4
4
  * 番組名の「🈟」「🈑」「🈞」([新][字][再]) はここにある。読めないと、番組表から
5
5
  * その印が丸ごと消えるか、化けた文字が並ぶ。
@@ -9,21 +9,21 @@
9
9
  * ([fold.ts](https://github.com/danything/denpa/blob/main/src/lib/fold.ts))。
10
10
  *
11
11
  * **字は字幕と同じ表を引く** ([b24-tables.ts](b24-tables.ts) の `ADDITIONAL`。ARIB STD-B24 表 7-19 /
12
- * STD-B62 表 5-2)。番組表で違えるのは下の `EPG_ONLY` だけ:
12
+ * STD-B62 表 5-2)。番組表で違えるのは下の `EPG_ONLY` だけで、次の 2 つ。
13
13
  *
14
- * - 92区56〜85点 (楽器の略号) は規格でも私用領域 (U+E2A5〜) にしか字が無い。どこでも読めるよう
14
+ * - 92 区 56〜85 点 (楽器の略号) は規格でも私用領域 (U+E2A5〜) にしか字が無い。どこでも読めるよう
15
15
  * 「(vn)」のような文字列に開く (字幕は私用領域のまま。フォントがその字形を持つ)
16
- * - 93区46・47点と87点は規格で空き。昔の表 (epgdump_py から ariblib に引き継がれた表) のとおり
16
+ * - 93 区 46・47 点と 87 点は規格で空き。昔の表 (epgdump_py から ariblib に引き継がれた表) のとおり
17
17
  * 中黒と全角の空白で埋める (字幕では空きのまま)
18
18
  *
19
19
  * 表で空き (U+FFFD) の点は持たない。`aribtext.ts` が「□」にする。
20
20
  *
21
- * 鍵は区点そのまま — 第1バイトが 0x20+区、第2バイトが 0x20+点。
21
+ * 鍵は区点そのまま (第 1 バイトが 0x20+区、第 2 バイトが 0x20+点)。
22
22
  */
23
23
  import { ADDITIONAL } from "./b24-tables.js";
24
24
  /** 番組表だけで違える字。区点 → 字 (上の説明) */
25
25
  export const EPG_ONLY = new Map([
26
- // 92区56〜85点。規格でも私用領域
26
+ // 92 区 56〜85 点。規格でも私用領域
27
27
  [0x7c58, "(vn)"],
28
28
  [0x7c59, "(ob)"],
29
29
  [0x7c5a, "(cb)"],
@@ -54,7 +54,7 @@ export const EPG_ONLY = new Map([
54
54
  [0x7c73, "g)"],
55
55
  [0x7c74, "(pe"],
56
56
  [0x7c75, "r)"],
57
- // 93区46・47点・87点。規格で空き
57
+ // 93 区 46・47 点・87 点。規格で空き
58
58
  [0x7d4e, "・"],
59
59
  [0x7d4f, "・"],
60
60
  [0x7d77, " "],
@@ -1,9 +1,9 @@
1
1
  /**
2
- * ARIB STD-B24 の8単位符号を読む。番組名・概要・局名はこの形式で流れてくる。
2
+ * ARIB STD-B24 の 8 単位符号を読む。番組名・概要・局名はこの形式で流れてくる。
3
3
  *
4
4
  * ## 仕組み
5
5
  *
6
- * 符号表を4つ (G0〜G3) 持ち、**どの表を今使うか**を切り替えながら読む。
6
+ * 符号表を 4 つ (G0〜G3) 持ち、**どの表を今使うか**を切り替えながら読む。
7
7
  * 0x21〜0x7E は GL に、0xA1〜0xFE は GR に割り当てられた表で引く。
8
8
  * SI の初期状態は G0=漢字 / G1=英数 / G2=ひらがな / G3=カタカナ、GL=G0・GR=G2。
9
9
  *
@@ -11,24 +11,24 @@
11
11
  *
12
12
  * 英数集合 (と空白) は**いまの文字の大きさ**で描く。SI の初期状態は標準 (NSZ) で、
13
13
  * テレビはこれを全角で描く。半角にしたい局は中型 (MSZ) を挟んでくる (ARIB TR-B14)。
14
- * 番組名の「Venue101」は英数集合を標準のまま送ったもの。**放送のとおりに出す** —
14
+ * 番組名の「Venue101」は英数集合を標準のまま送ったもの。**放送のとおりに出す。**
15
15
  * 探すときや比べるときに半角へ寄せるのは使う側 (denpa なら `fold.toHalfWidth` / `title.searchable`)。
16
16
  * 全角は `toHalfWidth` でそのまま戻る字 (U+FF01〜U+FF5E) にする (0x5C は \、0x7E は ~)
17
17
  *
18
- * ## 漢字は EUC-JP に押し付ける
18
+ * ## 漢字は EUC-JP として読む
19
19
  *
20
- * 2バイトの漢字集合は JIS X 0208 の並びで、区点は (第1-0x20, 第2-0x20)。
20
+ * 2 バイトの漢字集合は JIS X 0208 の並びで、区点は (第 1-0x20, 第 2-0x20)。
21
21
  * **各バイトの最上位を立てれば EUC-JP になる**ので、ほとんどの字は
22
- * `TextDecoder('euc-jp')` に渡せる。自前の表を引くのは:
22
+ * `TextDecoder('euc-jp')` に渡せる。自前の表を引くのは次の字だけ。
23
23
  *
24
- * - 85区から先の外字 ([aribtext-gaiji.ts](aribtext-gaiji.ts))
25
- * - EUC-JP に無い JIS X 0213 の1面の字 (字幕と同じ表。▷ や ⓐ、か゚ のような2つのコードポイントの字も)
26
- * - JIS互換漢字1面 (終端 0x39) の 85〜94区と、2面 (0x3A) 全部 (`PLANE1_HIGH`・`PLANE2`)
24
+ * - 85 区から先の外字 ([aribtext-gaiji.ts](aribtext-gaiji.ts))
25
+ * - EUC-JP に無い JIS X 0213 の 1 面の字 (字幕と同じ表。▷ や ⓐ、か゚ のような 2 つのコードポイントの字も)
26
+ * - JIS 互換漢字 1 面 (終端 0x39) の 85〜94 区と、2 面 (0x3A) 全部 (`PLANE1_HIGH`・`PLANE2`)
27
27
  */
28
28
  /**
29
- * 8単位符号を読んで文字列にする。
29
+ * 8 単位符号を読んで文字列にする。
30
30
  *
31
- * 壊れた並びで例外を投げない。放送波は落ちるもので、1つの記述子が読めなくても
31
+ * 壊れた並びで例外を投げない。放送波は落ちるもので、1 つの記述子が読めなくても
32
32
  * 番組表全体を落とすほうが害が大きい。**読めたところまで返す。**
33
33
  */
34
34
  export declare function decodeAribText(data: Uint8Array): string;
package/dist/aribtext.js CHANGED
@@ -1,9 +1,9 @@
1
1
  /**
2
- * ARIB STD-B24 の8単位符号を読む。番組名・概要・局名はこの形式で流れてくる。
2
+ * ARIB STD-B24 の 8 単位符号を読む。番組名・概要・局名はこの形式で流れてくる。
3
3
  *
4
4
  * ## 仕組み
5
5
  *
6
- * 符号表を4つ (G0〜G3) 持ち、**どの表を今使うか**を切り替えながら読む。
6
+ * 符号表を 4 つ (G0〜G3) 持ち、**どの表を今使うか**を切り替えながら読む。
7
7
  * 0x21〜0x7E は GL に、0xA1〜0xFE は GR に割り当てられた表で引く。
8
8
  * SI の初期状態は G0=漢字 / G1=英数 / G2=ひらがな / G3=カタカナ、GL=G0・GR=G2。
9
9
  *
@@ -11,19 +11,19 @@
11
11
  *
12
12
  * 英数集合 (と空白) は**いまの文字の大きさ**で描く。SI の初期状態は標準 (NSZ) で、
13
13
  * テレビはこれを全角で描く。半角にしたい局は中型 (MSZ) を挟んでくる (ARIB TR-B14)。
14
- * 番組名の「Venue101」は英数集合を標準のまま送ったもの。**放送のとおりに出す** —
14
+ * 番組名の「Venue101」は英数集合を標準のまま送ったもの。**放送のとおりに出す。**
15
15
  * 探すときや比べるときに半角へ寄せるのは使う側 (denpa なら `fold.toHalfWidth` / `title.searchable`)。
16
16
  * 全角は `toHalfWidth` でそのまま戻る字 (U+FF01〜U+FF5E) にする (0x5C は \、0x7E は ~)
17
17
  *
18
- * ## 漢字は EUC-JP に押し付ける
18
+ * ## 漢字は EUC-JP として読む
19
19
  *
20
- * 2バイトの漢字集合は JIS X 0208 の並びで、区点は (第1-0x20, 第2-0x20)。
20
+ * 2 バイトの漢字集合は JIS X 0208 の並びで、区点は (第 1-0x20, 第 2-0x20)。
21
21
  * **各バイトの最上位を立てれば EUC-JP になる**ので、ほとんどの字は
22
- * `TextDecoder('euc-jp')` に渡せる。自前の表を引くのは:
22
+ * `TextDecoder('euc-jp')` に渡せる。自前の表を引くのは次の字だけ。
23
23
  *
24
- * - 85区から先の外字 ([aribtext-gaiji.ts](aribtext-gaiji.ts))
25
- * - EUC-JP に無い JIS X 0213 の1面の字 (字幕と同じ表。▷ や ⓐ、か゚ のような2つのコードポイントの字も)
26
- * - JIS互換漢字1面 (終端 0x39) の 85〜94区と、2面 (0x3A) 全部 (`PLANE1_HIGH`・`PLANE2`)
24
+ * - 85 区から先の外字 ([aribtext-gaiji.ts](aribtext-gaiji.ts))
25
+ * - EUC-JP に無い JIS X 0213 の 1 面の字 (字幕と同じ表。▷ や ⓐ、か゚ のような 2 つのコードポイントの字も)
26
+ * - JIS 互換漢字 1 面 (終端 0x39) の 85〜94 区と、2 面 (0x3A) 全部 (`PLANE1_HIGH`・`PLANE2`)
27
27
  */
28
28
  import { GAIJI } from "./aribtext-gaiji.js";
29
29
  import { HIRAGANA as HIRAGANA_TABLE, JISX0201_HALF, KANJI_DIFF, KANJI_SEQUENCES, KATAKANA as KATAKANA_TABLE, PLANE1_HIGH, PLANE2, } from "./b24-tables.js";
@@ -37,15 +37,15 @@ const MOSAIC = { bytes: 1, kind: "blank" };
37
37
  * 終端バイト → 符号表。ESC の指示で使う。
38
38
  *
39
39
  * モザイク (0x32〜0x35) は図形なので読めるものが無い。**捨てずに空へ倒す**のは、
40
- * 1バイト表として字数を数え続けないと以降がずれるため。
40
+ * 1 バイト表として字数を数え続けないと以降がずれるため。
41
41
  *
42
- * **オブジェクトではなく Map。** 数値のキーは書式が10進に直されてしまい、
42
+ * **オブジェクトではなく Map。** 数値のキーは書式が 10 進に直されてしまい、
43
43
  * 規格に載っている終端バイトと突き合わせられなくなる (この下も同じ)。
44
44
  */
45
45
  const CHARSETS = new Map([
46
46
  [0x42, KANJI],
47
- [0x39, { bytes: 2, kind: "plane1" }], // JIS互換漢字1面
48
- [0x3a, { bytes: 2, kind: "plane2" }], // JIS互換漢字2面
47
+ [0x39, { bytes: 2, kind: "plane1" }], // JIS 互換漢字 1 面
48
+ [0x3a, { bytes: 2, kind: "plane2" }], // JIS 互換漢字 2 面
49
49
  [0x3b, KANJI], // 追加記号 (漢字集合と同じ表を引く)
50
50
  [0x4a, ALNUM],
51
51
  [0x30, HIRAGANA],
@@ -59,22 +59,22 @@ const CHARSETS = new Map([
59
59
  [0x34, MOSAIC],
60
60
  [0x35, MOSAIC],
61
61
  ]);
62
- /** 外字にも JIS にも無い文字を出すときの印。消すとタイトルから1文字黙って落ちる */
62
+ /** 外字にも JIS にも無い文字を出すときの印。消すとタイトルから 1 文字黙って落ちる */
63
63
  const UNKNOWN = "□";
64
64
  /**
65
- * 1バイトの集合は字幕と同じ表 ([b24-tables.ts](b24-tables.ts)) を引く。**番組表で違えるところ**:
65
+ * 1 バイトの集合は字幕と同じ表 ([b24-tables.ts](b24-tables.ts)) を引く。**字幕と違えるところは次のとおり。**
66
66
  *
67
67
  * - ひらがなの 0x74〜0x76 は規格で空き。字幕は全角の空白で埋めるが、番組表では何も出さない
68
68
  * - JIS X 0201 カタカナはいつも半角 (字幕は大きさで全角と半角を描き分ける)
69
69
  * - 英数は大きさに従って全角か ASCII (字幕の半角の表は 0x5C が ¥、0x7E が ‾。番組表は検索で打つ字に合わせる)
70
- * - 漢字は EUC-JP のまま読む (字幕は 1区33点の 〜・34点の ‖・61点の − などを差し替える。`KANJI_DIFF`)。
70
+ * - 漢字は EUC-JP のまま読む (字幕は 1 区 33 点の 〜・34 点の ‖・61 点の − などを差し替える。`KANJI_DIFF`)。
71
71
  * EUC-JP に無い点だけ字幕と同じ JIS X 0213 の字を引く
72
72
  */
73
73
  const HIRA = [...HIRAGANA_TABLE];
74
74
  const KATA = [...KATAKANA_TABLE];
75
75
  const ANK = [...JISX0201_HALF];
76
76
  const eucjp = new TextDecoder("euc-jp");
77
- /** EUC-JP に無い JIS X 0213 の1面の字 (区×94+点 → 字)。字幕と同じ表 */
77
+ /** EUC-JP に無い JIS X 0213 の 1 面の字 (区×94+点 → 字)。字幕と同じ表 */
78
78
  const x0213 = new Map(KANJI_SEQUENCES);
79
79
  for (const [start, chars] of KANJI_DIFF) {
80
80
  let i = start;
@@ -85,17 +85,17 @@ for (const [start, chars] of KANJI_DIFF) {
85
85
  }
86
86
  }
87
87
  const PLANE1_HIGH_CHARS = [...PLANE1_HIGH];
88
- /** 2面の区 (1〜94) → 94 字 */
88
+ /** 2 面の区 (1〜94) → 94 字 */
89
89
  const PLANE2_ROWS = new Map(PLANE2.map(([ku, row]) => [ku, [...row]]));
90
90
  /**
91
- * 2バイト文字の変換結果を覚えておく。
91
+ * 2 バイト文字の変換結果を覚えておく。
92
92
  *
93
- * 番組表は同じ字が何万回も出てくるので、1文字ごとに `TextDecoder` を
93
+ * 番組表は同じ字が何万回も出てくるので、1 文字ごとに `TextDecoder` を
94
94
  * 呼び直すと配列の確保だけで効いてくる。
95
95
  */
96
96
  const cache = new Map();
97
97
  function twoByte(code, kind) {
98
- // 2面と、1面の 85区から先は同じ区点でも別の字。覚えるときも漢字集合と混ぜない
98
+ // 2 面と、1 面の 85 区から先は同じ区点でも別の字。覚えるときも漢字集合と混ぜない
99
99
  const high = code >> 8;
100
100
  const low = code & 0xff;
101
101
  const key = kind === "plane2"
@@ -116,7 +116,7 @@ function twoByte(code, kind) {
116
116
  decoded = PLANE2_ROWS.get(ku)?.[low - 0x21] ?? "";
117
117
  }
118
118
  else if (ku >= 85) {
119
- // 85区から先は自前の表だけで引く。EUC-JP に渡すと 89〜92区が IBM 拡張の漢字になる
119
+ // 85 区から先は自前の表だけで引く。EUC-JP に渡すと 89〜92 区が IBM 拡張の漢字になる
120
120
  decoded =
121
121
  kind === "plane1"
122
122
  ? (PLANE1_HIGH_CHARS[cell - 84 * 94] ?? "")
@@ -147,7 +147,7 @@ const SZX = 0x8b;
147
147
  const SZX_TINY = 0x60;
148
148
  /** 標準の大きさの空白 (U+3000) */
149
149
  const WIDE_SPACE = String.fromCharCode(0x3000);
150
- /** C1 も同じ。COL/CDC は最初の引数が 0x20 のときだけもう1つ増える */
150
+ /** C1 も同じ。COL/CDC は最初の引数が 0x20 のときだけもう 1 つ増える */
151
151
  const C1_PARAMS = new Map([
152
152
  [0x8b, 1], // SZX
153
153
  [0x90, 1], // COL
@@ -160,16 +160,16 @@ const C1_PARAMS = new Map([
160
160
  [0x9d, 2], // TIME
161
161
  ]);
162
162
  /**
163
- * 8単位符号を読んで文字列にする。
163
+ * 8 単位符号を読んで文字列にする。
164
164
  *
165
- * 壊れた並びで例外を投げない。放送波は落ちるもので、1つの記述子が読めなくても
165
+ * 壊れた並びで例外を投げない。放送波は落ちるもので、1 つの記述子が読めなくても
166
166
  * 番組表全体を落とすほうが害が大きい。**読めたところまで返す。**
167
167
  */
168
168
  export function decodeAribText(data) {
169
169
  const g = [KANJI, ALNUM, HIRAGANA, KATAKANA];
170
170
  let gl = 0;
171
171
  let gr = 2;
172
- /** 単発シフト (SS2/SS3)。1文字だけ別の表を使ったら元に戻す */
172
+ /** 単発シフト (SS2/SS3)。1 文字だけ別の表を使ったら元に戻す */
173
173
  let single = null;
174
174
  /** 英数と空白を半角で描く大きさか (MSZ/SSZ)。SI の初期状態は標準 (NSZ) で全角 */
175
175
  let half = false;
@@ -186,7 +186,7 @@ export function decodeAribText(data) {
186
186
  if (byte <= 0x20 || byte === 0x7f || byte === 0xa0 || byte === 0xff) {
187
187
  at++;
188
188
  switch (byte) {
189
- case 0x0d: // APR。改行。直後の LF は同じ1回として畳む
189
+ case 0x0d: // APR。改行。直後の LF は同じ 1 回として畳む
190
190
  out += "\n";
191
191
  if (data[at] === 0x0a)
192
192
  at++;
@@ -248,7 +248,7 @@ export function decodeAribText(data) {
248
248
  else if (byte === SZX)
249
249
  half = data[at] === SZX_TINY;
250
250
  let params = C1_PARAMS.get(byte) ?? 0;
251
- // COL と CDC は「色を直に指定する」形式のときだけ引数が1つ増える
251
+ // COL と CDC は「色を直に指定する」形式のときだけ引数が 1 つ増える
252
252
  if ((byte === 0x90 || byte === 0x92) && data[at] === 0x20)
253
253
  params = 2;
254
254
  at += params;
@@ -302,7 +302,7 @@ const LOCKING = new Map([
302
302
  ]);
303
303
  /**
304
304
  * ESC のあとを読む。**指示 (どの表を G0〜G3 に載せるか) と
305
- * 呼び出し (どの G を GL/GR に出すか) の2種類がある。**
305
+ * 呼び出し (どの G を GL/GR に出すか) の 2 種類がある。**
306
306
  *
307
307
  * @returns 次に読むべき位置
308
308
  */
@@ -315,13 +315,13 @@ function afterEscape(data, at, designate, invoke) {
315
315
  invoke(shift[0], shift[1]);
316
316
  return at + 1;
317
317
  }
318
- // 2バイト集合の指示。ESC 0x24 F は G0 への指示の略記
318
+ // 2 バイト集合の指示。ESC 0x24 F は G0 への指示の略記
319
319
  if (byte === 0x24) {
320
320
  const next = data[at + 1];
321
321
  if (next === undefined)
322
322
  return at + 2;
323
323
  if (next >= 0x28 && next <= 0x2b) {
324
- // ESC 0x24 0x2x 0x20 F は2バイトDRCS。読めないので空へ倒す
324
+ // ESC 0x24 0x2x 0x20 F は 2 バイト DRCS。読めないので空へ倒す
325
325
  if (data[at + 2] === 0x20) {
326
326
  designate(next - 0x28, { bytes: 2, kind: "blank" });
327
327
  return at + 4;
@@ -332,17 +332,17 @@ function afterEscape(data, at, designate, invoke) {
332
332
  designate(0, CHARSETS.get(next));
333
333
  return at + 2;
334
334
  }
335
- // 1バイト集合の指示
335
+ // 1 バイト集合の指示
336
336
  if (byte >= 0x28 && byte <= 0x2b) {
337
337
  const target = byte - 0x28;
338
338
  if (data[at + 1] === 0x20) {
339
- // 1バイトDRCS
339
+ // 1 バイト DRCS
340
340
  designate(target, MOSAIC);
341
341
  return at + 3;
342
342
  }
343
343
  designate(target, CHARSETS.get(data[at + 1]));
344
344
  return at + 2;
345
345
  }
346
- // 知らない指示。1バイトだけ飛ばして読み進める (止めるより取り返しがつく)
346
+ // 知らない指示。1 バイトだけ飛ばして読み進める (止めるより取り返しがつく)
347
347
  return at + 1;
348
348
  }
@@ -10,17 +10,17 @@
10
10
  * **表の名前と `export const` の形は変えない。** danything/denpa-font の道具がこのファイルを
11
11
  * 名前で読んでフォントに入れる字を決める (`ADDITIONAL_ROWS`・`PLANE1_HIGH_ROWS` も。`aribtext-gaiji.ts`・`fold.ts` も同じ)。
12
12
  *
13
- * - 漢字は EUC-JP で読んだものと違うところだけ持つ (`KANJI_DIFF`。番組表は EUC-JP のまま読む —
14
- * 1区33点の 〜 / ~ などは字幕と番組表で違えてある。aribtext.ts の説明)。1〜84区は JIS X 0213:2004 の1面と
15
- * 同じ字 (全角の形を選んだ点と、1区17点の  ̄ など libaribcaption のとおりの数点を除く)
16
- * - JIS X 0213 の表 (2つのコードポイントの字・1面の 85〜94区・2面) は [scripts/jisx0213.ts](../scripts/jisx0213.ts) が
13
+ * - 漢字は EUC-JP で読んだものと違うところだけ持つ (`KANJI_DIFF`。番組表は EUC-JP のまま読むので、
14
+ * 1 区 33 点の 〜 / ~ などは字幕と番組表で違えてある。aribtext.ts の説明)。1〜84 区は JIS X 0213:2004 の 1 面と
15
+ * 同じ字 (全角の形を選んだ点と、1 区 17 点の  ̄ など libaribcaption のとおりの数点を除く)
16
+ * - JIS X 0213 の表 (2 つのコードポイントの字・1 面の 85〜94 区・2 面) は [scripts/jisx0213.ts](../scripts/jisx0213.ts) が
17
17
  * x0213.org の対応表から書く。手で直さない
18
18
  * - U+FFFD は規格で空いているところ
19
19
  *
20
20
  * ## 外字 (DRCS) の置き換えを足す
21
21
  *
22
22
  * 放送は字幕の外字を小さな画像で送ってくる。画像の MD5 (`b24caption.ts` が中身の画素から取る) が
23
- * `DRCS_REPLACE` にあれば、その字に置き換えて描く (無ければ画像のまま)。足すときは:
23
+ * `DRCS_REPLACE` にあれば、その字に置き換えて描く (無ければ画像のまま)。足すときは次の手順。
24
24
  *
25
25
  * 1. 字幕の JSON (`/api/recordings/<id>/captions.json` の `drcs`) の `md5` を読み取る。`data` の画像は送るために
26
26
  * なめらかにしたもの (drcs-smooth.ts) なので、`data` から MD5 を取っても表と合わない
@@ -41,11 +41,11 @@ export declare const JISX0201_HALF = "\uFF61\uFF62\uFF63\uFF64\uFF65\uFF66\uFF67
41
41
  export declare const ALNUM_FULL = "\uFF01\uFF02\uFF03\uFF04\uFF05\uFF06\uFF07\uFF08\uFF09\uFF0A\uFF0B\uFF0C\uFF0D\uFF0E\uFF0F\uFF10\uFF11\uFF12\uFF13\uFF14\uFF15\uFF16\uFF17\uFF18\uFF19\uFF1A\uFF1B\uFF1C\uFF1D\uFF1E\uFF1F\uFF20\uFF21\uFF22\uFF23\uFF24\uFF25\uFF26\uFF27\uFF28\uFF29\uFF2A\uFF2B\uFF2C\uFF2D\uFF2E\uFF2F\uFF30\uFF31\uFF32\uFF33\uFF34\uFF35\uFF36\uFF37\uFF38\uFF39\uFF3A\uFF3B\uFFE5\uFF3D\uFF3E\uFF3F\uFF40\uFF41\uFF42\uFF43\uFF44\uFF45\uFF46\uFF47\uFF48\uFF49\uFF4A\uFF4B\uFF4C\uFF4D\uFF4E\uFF4F\uFF50\uFF51\uFF52\uFF53\uFF54\uFF55\uFF56\uFF57\uFF58\uFF59\uFF5A\uFF5B\uFF5C\uFF5D\uFFE3";
42
42
  /** 同じものの半角 (中くらいのとき)。0x5C は ¥、0x7E は ‾ (番組表は ASCII のまま。バックスラッシュとチルダ) */
43
43
  export declare const ALNUM_HALF = "!\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\u00A5]^_`abcdefghijklmnopqrstuvwxyz{|}\u203E";
44
- /** 漢字の表の1・2区を、中くらいのときに半角へ寄せたもの */
44
+ /** 漢字の表の 1・2 区を、中くらいのときに半角へ寄せたもの */
45
45
  export declare const KANJI_SYMBOLS_HALF = " \uFF64\uFF61,.\uFF65:;?!\uFF9E\uFF9F\u00B4`\u00A8^\u00AF_\u30FD\u30FE\u309D\u309E\u3003\u4EDD\u3005\u3006\u3007\uFF70\u2015\u2010/\\~\u2016|\u2026\u2025\u2018\u2019\u201C\u201D()\u3014\u3015[]{}\u3008\u3009\u300A\u300B\uFF62\uFF63\u300E\u300F\u3010\u3011+\u2212\u00B1\u00D7\u00F7=\u2260<>\u2266\u2267\u221E\u2234\u2642\u2640\u00B0\u2032\u2033\u2103\u00A5$\u00A2\u00A3%#&*@\u00A7\u2606\u2605\uFFEE\u25CF\u25CE\u25C7\u25C6\u25A1\uFFED\u25B3\u25B2\u25BD\u25BC\u203B\u3012\uFFEB\uFFE9\uFFEA\uFFEC\u3013'\"-~\u3033\u3034\u3035\u303B\u303C\u30FF\u309F\u2208\u220B\u2286\u2287\u2282\u2283\u222A\u2229\u2284\u2285\u228A\u228B\u2209\u2205\u2305\u2306\u2227\u2228\u00AC\u21D2\u21D4\u2200\u2203\u2295\u2296\u2297\u2225\u2226\u2985\u2986\u3018\u3019\u3016\u3017\u2220\u22A5\u2312\u2202\u2207\u2261\u2252\u226A\u226B\u221A\u223D\u221D\u2235\u222B\u222C\u2262\u2243\u2245\u2248\u2276\u2277\u2194\u212B\u2030\u266F\u266D\u266A\u2020\u2021\u00B6\u266E\u266B\u266C\u2669\u25EF";
46
- /** 漢字の表 (1〜84区) のうち、EUC-JP で読んだものと違うところ。[区×94+点 (0 から), そこから続く字] の並び。85区から先は `ADDITIONAL` */
46
+ /** 漢字の表 (1〜84 区) のうち、EUC-JP で読んだものと違うところ。[区×94+点 (0 から), そこから続く字] の並び。85 区から先は `ADDITIONAL` */
47
47
  export declare const KANJI_DIFF: [number, string][];
48
- /** 追加記号・追加漢字を1つの文字列にしたもの。(区 − 85) × 94 + (点 − 1) 番目のコードポイント */
48
+ /** 追加記号・追加漢字を 1 つの文字列にしたもの。(区 − 85) × 94 + (点 − 1) 番目のコードポイント */
49
49
  export declare const ADDITIONAL: string;
50
50
  /**
51
51
  * JIS X 0213:2004 の1面で、2つのコードポイントで表す字 (半濁点の付いたかな・発音記号と、声調の組)。
@@ -59,7 +59,7 @@ export declare const PLANE1_HIGH: string;
59
59
  */
60
60
  export declare const PLANE2: [number, string][];
61
61
  /**
62
- * 色の表 (CLUT)。8つの組 × 16色、RGBA の16進。後ろの4組 (65〜127) は 64 を引いた番号の色を半分透かしたもの (65〜72 だけは 0〜7 番の基本の色)。
62
+ * 色の表 (CLUT)。8 つの組 × 16 色、RGBA の 16 進。後ろの 4 組 (65〜127) は 64 を引いた番号の色を半分透かしたもの (65〜72 だけは 0〜7 番の基本の色)。
63
63
  * libaribcaption の表は 101 番と 119 番の青が `09` になっていたが、
64
64
  * 元の 37 番・55 番 (`55ff00`・`ff5500`) を透かしたものなので `00`
65
65
  */