@danything/arib 0.0.0-stage → 0.1.0

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.
@@ -0,0 +1,143 @@
1
+ /**
2
+ * データ放送の通知の形式。**デコードする側 ([bml.ts](bml.ts)) と描く側の取り決め。**
3
+ *
4
+ * もとは web-bml の `protocol` (`ws_api.ts`) を借りていた。形式はそのまま写してある —
5
+ * 録画の隣に置いた `.bml.jsonl` はこの形式の JSON を1行ずつ持っているので、
6
+ * **形式を変えると前に録ったものが読めなくなる**。足すのはよいが、名前や意味は変えない。
7
+ *
8
+ * 載せるのは denpa が実際に作るものだけ (PMT・モジュール一覧・揃ったモジュール・
9
+ * ストリーム記述子のイベント・番組の名乗り・放送の時刻)。web-bml が自前の
10
+ * TS 解析のために持っていた PCR・PES・BIT・映像の URL は作らないので持たない。
11
+ */
12
+ /** PMT の ES 1本。**部品タグ (`componentId`) を持つものだけ**並ぶ (bml.ts の `parsePmt`) */
13
+ export interface ComponentPMT {
14
+ pid: number;
15
+ componentId: number;
16
+ bxmlInfo?: AdditionalAribBXMLInfo;
17
+ streamType: number;
18
+ dataComponentId?: number;
19
+ }
20
+ /** データ符号化方式記述子の後半 (bml.ts の `parseBxmlInfo`) */
21
+ export interface AdditionalAribBXMLInfo {
22
+ transmissionFormat: number;
23
+ entryPointFlag: boolean;
24
+ entryPointInfo?: AdditionalAribBXMLEntryPointInfo;
25
+ additionalAribCarouselInfo?: AdditionalAribCarouselInfo;
26
+ }
27
+ export interface AdditionalAribBXMLEntryPointInfo {
28
+ autoStartFlag: boolean;
29
+ documentResolution: number;
30
+ useXML: boolean;
31
+ defaultVersionFlag: boolean;
32
+ independentFlag: boolean;
33
+ styleForTVFlag: boolean;
34
+ bmlMajorVersion: number;
35
+ bmlMinorVersion: number;
36
+ bxmlMajorVersion?: number;
37
+ bxmlMinorVersion?: number;
38
+ }
39
+ export interface AdditionalAribCarouselInfo {
40
+ dataEventId: number;
41
+ eventSectionFlag: boolean;
42
+ ondemandRetrievalFlag: boolean;
43
+ fileStorableFlag: boolean;
44
+ startPriority: number;
45
+ }
46
+ /**
47
+ * `Content-Type` を読んだもの。名前は小文字にそろえ、元の綴りも持つ
48
+ * ([multipart.ts](multipart.ts) の `parseMediaType`)
49
+ */
50
+ export interface MediaType {
51
+ type: string;
52
+ originalType: string;
53
+ subtype: string;
54
+ originalSubtype: string;
55
+ parameters: MediaTypeParameter[];
56
+ }
57
+ export interface MediaTypeParameter {
58
+ attribute: string;
59
+ originalAttribute: string;
60
+ value: string;
61
+ }
62
+ /** モジュールの中のファイル1つ。中身は base64 (JSON で運ぶため) */
63
+ export interface ModuleFile {
64
+ contentLocation: string | null;
65
+ contentType: MediaType;
66
+ dataBase64: string;
67
+ }
68
+ export interface PMTMessage {
69
+ type: "pmt";
70
+ components: ComponentPMT[];
71
+ }
72
+ export interface ModuleDownloadedMessage {
73
+ type: "moduleDownloaded";
74
+ componentId: number;
75
+ moduleId: number;
76
+ files: ModuleFile[];
77
+ version: number;
78
+ dataEventId: number;
79
+ }
80
+ export interface ModuleListEntry {
81
+ id: number;
82
+ version: number;
83
+ size: number;
84
+ }
85
+ export interface ModuleListUpdatedMessage {
86
+ type: "moduleListUpdated";
87
+ componentId: number;
88
+ modules: ModuleListEntry[];
89
+ dataEventId: number;
90
+ returnToEntryFlag?: boolean;
91
+ }
92
+ export type ESEvent = ESImmediateEvent | ESNPTEvent | NPTReference;
93
+ export interface ESImmediateEvent {
94
+ type: "immediateEvent";
95
+ eventMessageGroupId: number;
96
+ timeMode: 0;
97
+ eventMessageType: number;
98
+ eventMessageId: number;
99
+ privateDataByte: number[];
100
+ }
101
+ export interface ESNPTEvent {
102
+ type: "nptEvent";
103
+ eventMessageGroupId: number;
104
+ timeMode: 2;
105
+ eventMessageNPT: number;
106
+ eventMessageType: number;
107
+ eventMessageId: number;
108
+ privateDataByte: number[];
109
+ }
110
+ export interface NPTReference {
111
+ type: "nptReference";
112
+ postDiscontinuityIndicator: boolean;
113
+ dsmContentId: number;
114
+ STCReference: number;
115
+ NPTReference: number;
116
+ scaleNumerator: number;
117
+ scaleDenominator: number;
118
+ }
119
+ export interface ESEventUpdatedMessage {
120
+ type: "esEventUpdated";
121
+ componentId: number;
122
+ events: ESEvent[];
123
+ dataEventId: number;
124
+ }
125
+ /** 番組の名乗り。TS からではなく DB から組む (`server/live.ts`・`server/recorded-bml.ts`) */
126
+ export interface ProgramInfoMessage {
127
+ type: "programInfo";
128
+ originalNetworkId: number | null;
129
+ transportStreamId: number | null;
130
+ serviceId: number | null;
131
+ eventId: number | null;
132
+ eventName: string | null;
133
+ startTimeUnixMillis: number | null;
134
+ durationSeconds: number | null;
135
+ indefiniteDuration: boolean | null;
136
+ networkId: number | null;
137
+ }
138
+ /** 放送の時刻 (TDT/TOT) */
139
+ export interface CurrentTime {
140
+ type: "currentTime";
141
+ timeUnixMillis: number;
142
+ }
143
+ export type ResponseMessage = PMTMessage | ModuleDownloadedMessage | ModuleListUpdatedMessage | ESEventUpdatedMessage | ProgramInfoMessage | CurrentTime;
@@ -0,0 +1,12 @@
1
+ /**
2
+ * データ放送の通知の形式。**デコードする側 ([bml.ts](bml.ts)) と描く側の取り決め。**
3
+ *
4
+ * もとは web-bml の `protocol` (`ws_api.ts`) を借りていた。形式はそのまま写してある —
5
+ * 録画の隣に置いた `.bml.jsonl` はこの形式の JSON を1行ずつ持っているので、
6
+ * **形式を変えると前に録ったものが読めなくなる**。足すのはよいが、名前や意味は変えない。
7
+ *
8
+ * 載せるのは denpa が実際に作るものだけ (PMT・モジュール一覧・揃ったモジュール・
9
+ * ストリーム記述子のイベント・番組の名乗り・放送の時刻)。web-bml が自前の
10
+ * TS 解析のために持っていた PCR・PES・BIT・映像の URL は作らないので持たない。
11
+ */
12
+ export {};
package/dist/bml.d.ts ADDED
@@ -0,0 +1,87 @@
1
+ /**
2
+ * データ放送 (ARIB STD-B24 の BML) をデコードする。**1局に絞った TS を食わせると、
3
+ * 組み立て終わったファイルが出てくる。**
4
+ *
5
+ * TS → PAT → PMT → データ符号化方式記述子 (0xFD) の付いた ES
6
+ * → DII/DDB (カルーセル) → モジュール → ファイル
7
+ *
8
+ * ## なぜ自前なのか
9
+ *
10
+ * **運び方は衛星のロゴと同じ DSM-CC** で、denpa はそれを既に持っている
11
+ * ([dsmcc.ts](dsmcc.ts) / [logo-dsmcc.ts](https://github.com/danything/denpa/blob/main/src/lib/ts/logo-dsmcc.ts))。
12
+ * [web-bml](https://github.com/otya128/web-bml) の `decode_ts.ts` は使わない — 要るのは
13
+ * その一部だけで、残り (EIT/SDT/NIT・字幕の PES) は自前で読んでおり
14
+ * ([eit.ts](eit.ts) / [psi.ts](psi.ts) / ffmpeg)、`@chinachu/aribts` も抱えずに済む。
15
+ *
16
+ * **出す形式は web-bml の頃のまま** ([bml-protocol.ts](bml-protocol.ts))。録画の隣の
17
+ * `.bml.jsonl` がこの形式で残っているので、変えると前に録ったものが読めなくなる。
18
+ * モジュールの中身 (multipart) は [multipart.ts](multipart.ts) がデコードする。
19
+ */
20
+ import type { AdditionalAribBXMLInfo, ModuleFile, ResponseMessage } from "./bml-protocol.js";
21
+ /**
22
+ * データ符号化方式記述子の後半を読む。
23
+ *
24
+ * 地上波は TR-B14 第二分冊 2.1.4 表2-3、BS/CS は TR-B15 第一分冊 5.1.5 表5-4。
25
+ *
26
+ * **`data_component_id` は16ビット** (aribts は8ビットで読んでいる)。
27
+ */
28
+ export declare function parseBxmlInfo(data: Uint8Array): AdditionalAribBXMLInfo;
29
+ /**
30
+ * 1局に絞った TS を食わせると、データ放送の通知が出てくる。
31
+ *
32
+ * **1つの選局に1つ。** 局を変えたら作り直す — カルーセルは局ごとに別物で、
33
+ * 組み立て中のものを持ち越すと混ざる。
34
+ */
35
+ export declare class BmlDecoder {
36
+ private readonly send;
37
+ private readonly packets;
38
+ /** **1局に絞ったあとを食わせる前提。** 入っているサービスは1つなので、最初の局の PMT を追う */
39
+ private readonly pmt;
40
+ private readonly time;
41
+ /** カルーセルが流れている ES。PID ごと */
42
+ private readonly components;
43
+ /** 最後に配った PMT。**変わったときだけ配る** */
44
+ private sent;
45
+ constructor(send: (message: ResponseMessage) => void);
46
+ /** 1局に絞った TS を食わせる */
47
+ feed(chunk: Uint8Array): void;
48
+ /**
49
+ * 切り分け済みのパケットを1つ。ライブは同じ TS を時計や Hybridcast とも
50
+ * 分け合うので、切り分けは1回で済ませて配る (`server/live.ts` の `tap`)。
51
+ *
52
+ * **PID で行き先を引く。** 組み立て役を全部に回していた頃は、データ放送と
53
+ * 関係ない映像のパケットのたびにカルーセルの数だけ呼んでいた。
54
+ *
55
+ * `packet` は呼び手の塊の上の窓 (`psi.ts` の `PacketStream`)。**返ったあとまで
56
+ * 持つなら写すこと** — 塊の入れ物は使い回される
57
+ */
58
+ feedPacket(packet: Uint8Array): void;
59
+ private onPmt;
60
+ /** TDT / TOT。読み方は [eit.ts](eit.ts) にまとめてある */
61
+ private onTime;
62
+ private onCarousel;
63
+ private onDii;
64
+ /** 今の DII の一覧を配る。**諦めたモジュールは載せない** */
65
+ private sendList;
66
+ /**
67
+ * **来ないモジュールを諦める** (`GIVE_UP_ROUNDS`)。待っている受け側 (`Resources` の `wait`) は、
68
+ * DII に無いモジュールを「もう来ない」と決める (`gone`) ので、諦めたものを除いた一覧を配り直して
69
+ * 待ちを終わらせる。前の DII で配り終えた版のままのもの (受け側が持っている) は一覧から外さず、
70
+ * 組み立てるのをやめるだけ。次に DII の版が変われば、また待つ
71
+ */
72
+ private giveUp;
73
+ private onDdb;
74
+ /** 揃ったモジュールを配る */
75
+ private finish;
76
+ }
77
+ /**
78
+ * 揃ったモジュールをファイルに分ける。
79
+ *
80
+ * **多くは `multipart/mixed`** で、1つのモジュールに BML と画像がまとめて
81
+ * 入っている。Type 記述子が無いときも中身は multipart なので、同じ扱いにする。
82
+ */
83
+ export declare function moduleFiles(data: Uint8Array, contentType: string | null): ModuleFile[];
84
+ /** zlib で縮めてあれば伸ばす。伸ばせなければ諦めて null */
85
+ export declare function inflate(data: Uint8Array, compression: {
86
+ type: number;
87
+ } | null): Uint8Array | null;