akari-video 0.1.33 → 0.1.34
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/package.json +1 -1
- package/vendor/.akari-capability-sources.json +7 -0
- package/vendor/docs/contract-2026-07-14-edit-json-v1-audio.md +4 -0
- package/vendor/docs/contract-2026-07-20-edit-json-v1-narration.md +3 -0
- package/vendor/docs/contract-2026-08-02-creator-root-v1.md +2 -1
- package/vendor/docs/contract-2026-08-02-preview-parity.md +8 -0
- package/vendor/docs/contract-2026-08-28-v2-audio-roles-v0.md +16 -11
- package/vendor/docs/contract-2026-08-29-media-inspect-cli-v0.md +2 -1
- package/vendor/docs/contract-2026-09-02-audio-clip-fx-v1.md +56 -0
- package/vendor/docs/contract-2026-09-02-audio-envelope-v1.md +91 -0
- package/vendor/docs/contract-2026-09-02-audio-insert-level-v1.md +110 -0
- package/vendor/docs/contract-2026-09-02-item-caption-anchor-v0.md +9 -5
- package/vendor/docs/contract-2026-09-02-transcript-unrecognized-spans-v0.md +21 -0
- package/vendor/docs/contract-2026-09-02-word-book-v0.md +402 -0
- package/vendor/packages/akari-launcher/package.json +1 -1
- package/vendor/packages/akari-tools/README.md +21 -0
- package/vendor/packages/akari-tools/package.json +3 -2
- package/vendor/packages/audio-library-setup/README.md +11 -0
- package/vendor/packages/audio-library-setup/shared/insert-level.mjs +105 -0
- package/vendor/packages/audio-library-setup/test/insert-level.test.mjs +110 -0
- package/vendor/packages/edit-lint/src/edit-lint.mjs +208 -14
- package/vendor/packages/edit-store/lib/audio-schedule.d.ts +17 -3
- package/vendor/packages/edit-store/lib/audio-schedule.js +98 -33
- package/vendor/packages/edit-store/lib/caption-clock.d.ts +56 -0
- package/vendor/packages/edit-store/lib/caption-clock.js +80 -0
- package/vendor/packages/edit-store/lib/caption-store.d.ts +8 -0
- package/vendor/packages/edit-store/lib/caption-store.js +39 -2
- package/vendor/packages/edit-store/lib/ducking.d.ts +1 -6
- package/vendor/packages/edit-store/lib/ducking.js +3 -12
- package/vendor/packages/edit-store/lib/edit-store.d.ts +38 -0
- package/vendor/packages/edit-store/lib/edit-v2.d.ts +15 -1
- package/vendor/packages/edit-store/lib/edit-v2.js +52 -5
- package/vendor/packages/edit-store/lib/envelope.d.ts +34 -0
- package/vendor/packages/edit-store/lib/envelope.js +289 -0
- package/vendor/packages/edit-store/lib/generated/edit-v2-keys.d.ts +5 -5
- package/vendor/packages/edit-store/lib/generated/edit-v2-keys.js +13 -4
- package/vendor/packages/edit-store/lib/index.d.ts +2 -0
- package/vendor/packages/edit-store/lib/index.js +2 -0
- package/vendor/packages/edit-store/lib/internal-model.d.ts +3 -0
- package/vendor/packages/edit-store/lib/internal-model.js +71 -7
- package/vendor/packages/edit-store/lib/item-anchor.d.ts +2 -0
- package/vendor/packages/edit-store/lib/item-anchor.js +25 -0
- package/vendor/packages/edit-store/lib/legacy-audio-view.js +16 -4
- package/vendor/packages/edit-store/lib/migrate/index.js +96 -12
- package/vendor/packages/edit-store/lib/timeline-map.d.ts +16 -0
- package/vendor/packages/edit-store/lib/timeline-map.js +43 -0
- package/vendor/packages/edit-store/lib/webview-kernel.d.ts +2 -0
- package/vendor/packages/edit-store/lib/webview-kernel.js +577 -57
- package/vendor/packages/media-bin/README.ja.md +19 -0
- package/vendor/packages/media-bin/README.md +19 -0
- package/vendor/packages/media-bin/bin/audio-measure.mjs +64 -0
- package/vendor/packages/media-bin/package.json +3 -0
- package/vendor/packages/media-bin/src/audio-measure.mjs +119 -0
- package/vendor/packages/media-bin/src/preview-audio-sidecar.mjs +436 -123
- package/vendor/packages/media-bin/test/audio-clip-fx.test.mjs +103 -0
- package/vendor/packages/media-bin/test/audio-measure.test.mjs +123 -0
- package/vendor/packages/media-bin/test/fixtures/audio-measure/click-300ms.stderr +15 -0
- package/vendor/packages/media-bin/test/fixtures/audio-measure/silence-3s.stderr +12 -0
- package/vendor/packages/media-bin/test/fixtures/audio-measure/tone-1k-minus20db.stderr +15 -0
- package/vendor/packages/media-bin/test/preview-audio-sidecar-async.test.mjs +257 -0
- package/vendor/packages/overlay-runtime/README.md +29 -2
- package/vendor/packages/schemas/bin/validate-edit.mjs +85 -0
- package/vendor/packages/schemas/bin/validate-word-book.mjs +165 -0
- package/vendor/packages/schemas/edit.schema.json +81 -3
- package/vendor/packages/schemas/engine-capabilities.json +8 -0
- package/vendor/packages/schemas/examples/edit-audio-clip-fx-invalid/edit.json +17 -0
- package/vendor/packages/schemas/examples/edit-audio-clip-fx-valid/edit.json +47 -0
- package/vendor/packages/schemas/examples/edit-audio-keyframes-t-order-invalid/edit.json +16 -0
- package/vendor/packages/schemas/examples/edit-audio-keyframes-valid/edit.json +19 -0
- package/vendor/packages/schemas/examples/edit-duck-db-out-of-range/edit.json +14 -0
- package/vendor/packages/schemas/examples/edit-sfx-ducking-valid/edit.json +19 -0
- package/vendor/packages/schemas/examples/word-book-v0-invalid-reading-only-variants/word-book.json +6 -0
- package/vendor/packages/schemas/examples/word-book-v0-invalid-variant-conflict/word-book.json +7 -0
- package/vendor/packages/schemas/examples/word-book-v0-invalid-version-1/word-book.json +4 -0
- package/vendor/packages/schemas/examples/word-book-v0-valid/word-book.json +27 -0
- package/vendor/packages/schemas/test/audio-clip-fx.test.mjs +39 -0
- package/vendor/packages/schemas/test/engine-capabilities.test.mjs +2 -2
- package/vendor/packages/schemas/test/validate-edit.test.mjs +22 -0
- package/vendor/packages/schemas/test/validate-word-book.test.mjs +83 -0
- package/vendor/packages/schemas/word-book.schema.json +33 -0
- package/vendor/packages/word-book/package.json +11 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "akari-video",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.34",
|
|
4
4
|
"description": "AKARI Video launcher CLI — start an AI-edited video project from any directory: scaffold, connection check, then hand over to Claude Code (or opencode). AKARI Video を opencode や Claude Code で、どのディレクトリからでも始めるための `akari` ランチャー CLI。接続確認(doctor)→ 未セットアップならプロジェクト雛形を作成 → AI エージェントを起動する。外部 npm 依存ゼロ(Node.js 組み込みモジュールのみ)。",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -51,10 +51,14 @@
|
|
|
51
51
|
"docs/contract-2026-08-29-media-inspect-cli-v0.md",
|
|
52
52
|
"docs/contract-2026-08-30-edit-json-v2-object-tree-v0.md",
|
|
53
53
|
"docs/contract-2026-08-30-motion-and-keyframes-v0.md",
|
|
54
|
+
"docs/contract-2026-09-02-audio-clip-fx-v1.md",
|
|
55
|
+
"docs/contract-2026-09-02-audio-envelope-v1.md",
|
|
56
|
+
"docs/contract-2026-09-02-audio-insert-level-v1.md",
|
|
54
57
|
"docs/contract-2026-09-02-captions-style-preset-v0.md",
|
|
55
58
|
"docs/contract-2026-09-02-export-verify-declared-vs-measured-v0.md",
|
|
56
59
|
"docs/contract-2026-09-02-item-caption-anchor-v0.md",
|
|
57
60
|
"docs/contract-2026-09-02-transcript-unrecognized-spans-v0.md",
|
|
61
|
+
"docs/contract-2026-09-02-word-book-v0.md",
|
|
58
62
|
"packages/akari-launcher/package.json",
|
|
59
63
|
"packages/akari-launcher/README.md",
|
|
60
64
|
"packages/akari-tools/package.json",
|
|
@@ -88,6 +92,8 @@
|
|
|
88
92
|
"packages/intake-form/README.md",
|
|
89
93
|
"packages/matte-rvm/package.json",
|
|
90
94
|
"packages/media-bin/package.json",
|
|
95
|
+
"packages/media-bin/README.ja.md",
|
|
96
|
+
"packages/media-bin/README.md",
|
|
91
97
|
"packages/osr-export/package.json",
|
|
92
98
|
"packages/osr-export/README.md",
|
|
93
99
|
"packages/overlay-runtime/package.json",
|
|
@@ -100,6 +106,7 @@
|
|
|
100
106
|
"packages/template-render/package.json",
|
|
101
107
|
"packages/template-render/README.ja.md",
|
|
102
108
|
"packages/template-render/README.md",
|
|
109
|
+
"packages/word-book/package.json",
|
|
103
110
|
"skills/address-review/SKILL.md",
|
|
104
111
|
"skills/analyze-footage/analysis-json.md",
|
|
105
112
|
"skills/analyze-footage/bin/face-expression/vendor/tasks-vision-0.10.17/README-AKARI.md",
|
|
@@ -87,6 +87,10 @@ edit.json の親ディレクトリを基準にした相対パス(絶対パス
|
|
|
87
87
|
|
|
88
88
|
## 4. ducking の v1 定義
|
|
89
89
|
|
|
90
|
+
> 2026-09-02 更新: `sidechaincompress` 方式は廃止した。現在は narration と speech の宣言区間を鍵に、
|
|
91
|
+
> attack / release を持つ共通決定論エンベロープをプレビューと書き出しの両方で使う。
|
|
92
|
+
> 以下は当初 v1 の設計記録として残す。
|
|
93
|
+
|
|
90
94
|
**採用: `sidechaincompress`(書き出し側のみ、ffmpeg 標準フィルタ)。**
|
|
91
95
|
「字幕/発話区間ベースの単純 gain」は不採用。
|
|
92
96
|
|
|
@@ -99,6 +99,9 @@ edit.json の親ディレクトリを基準にした相対パス(絶対パス
|
|
|
99
99
|
|
|
100
100
|
## 3. ducking の主従
|
|
101
101
|
|
|
102
|
+
2026-09-02 契約により sidechain 方式を廃止し、鍵を narration と speech の宣言区間の和集合とする
|
|
103
|
+
決定論エンベロープ方式へ移行した。既定の鍵は両方であり、対象は `ducking:true` の bgm / sfx である。
|
|
104
|
+
|
|
102
105
|
`contract-2026-07-14-edit-json-v1-audio.md` §4 は `audio.bgm.ducking: true` のサイドチェイン
|
|
103
106
|
入力(トリガー)を「ダイアログ音声(source 由来の音声トラックそのもの)」と定義していた。
|
|
104
107
|
本契約でナレーションが第一級データになったことに伴い、この入力の**主従**を以下のとおり正文化する:
|
|
@@ -61,6 +61,7 @@ AKARI Video がマシン上に持ってよい場所は次の 3 つ**だけ**で
|
|
|
61
61
|
├── AGENTS.md # 橋渡し(akari.md / design.md へ誘導)。初回はスタブ生成
|
|
62
62
|
├── channels/
|
|
63
63
|
│ └── <channel>/
|
|
64
|
+
│ ├── .akari/memory/word-book.json # 任意。チャンネル単語帳(word book v0 契約)
|
|
64
65
|
│ ├── design.md # チャンネル設計書(任意。生成工程は非スコープ)
|
|
65
66
|
│ └── videos/
|
|
66
67
|
│ └── <project>/ # 動画プロジェクト(内部は project-structure-v0 のまま)
|
|
@@ -69,7 +70,7 @@ AKARI Video がマシン上に持ってよい場所は次の 3 つ**だけ**で
|
|
|
69
70
|
└── .akari/
|
|
70
71
|
├── root.json # 作業場マニフェスト(版数・チャンネル一覧・生成日)
|
|
71
72
|
├── connections.json # provider・モデル・コスト承認ポリシーの作業場既定
|
|
72
|
-
├── memory/ # スタイル学習・記憶(memory-connection の既定接続先 §7)
|
|
73
|
+
├── memory/ # スタイル学習・記憶(memory-connection の既定接続先 §7、word-book.json)
|
|
73
74
|
└── cache/ # 再生成可能物
|
|
74
75
|
```
|
|
75
76
|
|
|
@@ -11,6 +11,7 @@
|
|
|
11
11
|
| 2026-08-02 | v0 | Web UI と shell の挙動仕様を統合 |
|
|
12
12
|
| 2026-08-28 | v2 | `packages/frame-engine` の意味論へ統合し、検収をゴールデンフレームへ一本化。出口を OSR と GPU 直結の 2 本に固定し、互換経路を退役節へ移動 |
|
|
13
13
|
| 2026-08-31 | v2.1 | §5.2 に断片 CSS の `vw` / `vh` 系単位の出力サイズ基準化(`viewport-units.js`。プレビューがウィンドウ幅基準で解いていた実機報告の修正)を追記 |
|
|
14
|
+
| 2026-09-02 | v2.2 | §2.8 に字幕時計の規約(active cue の判定は両プレビューとも出力秒。共有カーネル `caption-clock`)を追記。Web UI を shell に揃えた 4 点(字幕時計・字幕フォント名・`slot-params.js` の差し込み・最下段 cut の track 規則)の記録 |
|
|
14
15
|
|
|
15
16
|
## 1. 役割分担
|
|
16
17
|
|
|
@@ -128,6 +129,12 @@ finalFrameNumber **239**、lookahead hits **8**を要求する。
|
|
|
128
129
|
shell のプレビューでは DOM 層として提示し、書き出しでは同じ DOM 規約から overlay sheet を構成する。
|
|
129
130
|
器専用の字幕 HTML や出口専用の再レイアウトを持たない。
|
|
130
131
|
|
|
132
|
+
active cue の判定は両プレビューとも**出力秒**で行う。source 秒の cue(`time_domain: "source"` と未宣言の
|
|
133
|
+
legacy)は共有カーネル `packages/edit-store/src/caption-clock.ts` の `normalizeCaptionClock` が cut map
|
|
134
|
+
で出力秒へ射影し、削除区間をまたぐ cue は 1 本ずつに分割する(`<id>-output-<n>`、元 id は
|
|
135
|
+
`sourceCueId`)。shell は `normalizePreviewCaptionClock`、Web UI は `updateCaption` がこの正規化済み表を
|
|
136
|
+
読み、描画層は domain 判定を行わない(2026-09-02。それまで Web UI は source 秒で判定していた)。
|
|
137
|
+
|
|
131
138
|
**検収:** OSR ソフト描画の同一 fixture 2 走について、字幕を含む全コマ raw BGRA の SHA-256 一致を要求する。
|
|
132
139
|
|
|
133
140
|
### 2.9 overlays
|
|
@@ -161,6 +168,7 @@ SHA-256 一致を要求する。GPU は同一マシン一致率を診断値と
|
|
|
161
168
|
| cuts の perspective | 🟡 未適用・warning のみ(issue #39) | 🟡 同左 | ✅ DOM 層 | 🟡 warning を run.json へ(seek の warning を回収) | 🟡 warning を run.json へ |
|
|
162
169
|
| 5 transitions | ✅ 評価 | ✅ 完成 frame を提示 | ✅ 完成 frame を提示 | ✅ 完成 frame を捕捉 | ✅ canvas を直結 |
|
|
163
170
|
| matte / chroma key | ✅ 評価 | ✅ stamp 同期 | ✅ stamp 同期 | ✅ stamp 同期・捕捉 | ✅ 同一 frame 評価 |
|
|
171
|
+
| アルファ層の取り込み(`.webm` / `.mov` → color + mask mp4) | — 入力境界の外(media-bin `alpha-intake` が正本) | ✅ サーバ側 `prepareAlphaLayers`(`frameEngine.intake`) | ✅ node RPC `prepareAlphaIntake`(同一 media-bin・同一派生物、2026-09-02) | ✅ page-builder | ✅ page-builder |
|
|
164
172
|
| LUT / `bt709-limited` | ✅ 評価 | ✅ 提示 | ✅ 提示 | ✅ 捕捉・encode | ✅ LUT 後 canvas を直結 |
|
|
165
173
|
| 字幕 | — DOM 規約へ active state を供給 | ✅ DOM 層 | ✅ DOM 層 | ✅ 同規約の overlay sheet | 🟡 適格 cue を sprite 化 |
|
|
166
174
|
| overlays / 3D | — DOM 規約へ時刻を供給 | ✅ DOM 層 | ✅ DOM 層 | ✅ 同規約の overlay sheet | 🟡 static / 宣言型 3D のみ |
|
|
@@ -25,7 +25,7 @@ render-cut は最終成果物の音声品質を決める唯一の正である。
|
|
|
25
25
|
|
|
26
26
|
| 項目 | プレビュー(Web Audio) | 書き出し(ffmpeg) | 差の性質 |
|
|
27
27
|
|---|---|---|---|
|
|
28
|
-
| ducking |
|
|
28
|
+
| ducking | 共通決定論エンベロープを `exponentialRampToValueAtTime` で適用する | 同じエンベロープを f32le 化して `amultiply` する | デコーダとサンプル境界の差だけを許容する |
|
|
29
29
|
| BGM fade | タイムライン上の `fadeIn` / `fadeOut` を線形 `AudioParam` automation にする | `afade` をマスター音声チェーン内で適用する | master 無しの実測差は ±0.034 dB 以内(§3.2)。後段処理後の振幅は一致しない場合がある |
|
|
30
30
|
| SFX fade | クリップ実効尺に対する `fade_in` / `fade_out` を線形 automation にする | trim 後の実効尺へ `afade` を適用する | 基本形状は同じ。後段マスター処理の影響は書き出しだけに生じる |
|
|
31
31
|
| ラウドネス | 個別 gain と fade / ducking の合成のみ。番組全体の規格化はしない | EBU R128 計測とマスター処理を適用する | I / LRA / TP は一致を保証しない |
|
|
@@ -105,7 +105,7 @@ ms へ換算し、絶対値で集計する。全 59 点の最大は 16.667 ms、
|
|
|
105
105
|
|
|
106
106
|
**G3 裁定(2026-08-28):**
|
|
107
107
|
|
|
108
|
-
1.
|
|
108
|
+
1. 2026-09-02 契約で共通決定論エンベロープ化した。`sidechaincompress` は廃止した。
|
|
109
109
|
2. fade は時刻が一致しているため近似として残す。
|
|
110
110
|
3. ループ境界 / trim 境界の追加測定は別票とする。
|
|
111
111
|
4. SFX の true peak は書き出し確認必須のままとし、プレビューに保護を入れない。
|
|
@@ -115,8 +115,7 @@ ms へ換算し、絶対値で集計する。全 59 点の最大は 16.667 ms、
|
|
|
115
115
|
|
|
116
116
|
- Web Audio と ffmpeg のデコーダ、サンプル境界、出力デバイスの差
|
|
117
117
|
- プレビューで afftdn / loudnorm / true peak guard を実行しないこと
|
|
118
|
-
-
|
|
119
|
-
§4.1 の共通エンベロープ案を採用してから G3 へ進む
|
|
118
|
+
- ducking の共通エンベロープは両経路で同じで、デコーダとサンプル境界の差だけを残すこと
|
|
120
119
|
- 聴感確認の即時性を優先し、プレビューでは最終マスター処理の計算コストを負わないこと
|
|
121
120
|
|
|
122
121
|
これらの近似を残しても、タイムライン上の開始、trim、loop、gain、fade、ducking 対象区間は
|
|
@@ -124,10 +123,10 @@ ms へ換算し、絶対値で集計する。全 59 点の最大は 16.667 ms、
|
|
|
124
123
|
|
|
125
124
|
## 6. 撮影素材の台詞と ducking 側鎖
|
|
126
125
|
|
|
127
|
-
`speech` は cuts[] の撮影素材に含まれる音声を表し、各カットの trim / speed
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
126
|
+
`speech` は cuts[] の撮影素材に含まれる音声を表し、各カットの trim / speed を出力タイムラインへ
|
|
127
|
+
投影する。2026-09-02 契約では `analysis.json` の transcript 区間を同じ写像で ducking 鍵へ加える。
|
|
128
|
+
書き出しはこの speech 鍵を消費する。プレビューサーバーへ speech 鍵を渡す配線は同契約の範囲外で、
|
|
129
|
+
配線されるまでは narration 鍵だけへ劣化する。
|
|
131
130
|
|
|
132
131
|
## 7. 速度変更した台詞のピッチ保持サイドカー
|
|
133
132
|
|
|
@@ -157,6 +156,12 @@ FLAC(compression level 5)へ一度だけ切り出す。`transition_out` 境
|
|
|
157
156
|
|
|
158
157
|
BGM / SFX / narration は、元ファイルが WAV かつ 8 MB 超のとき同じ FLAC サイドカーを使う。
|
|
159
158
|
frame-engine は映像の ready を先に成立させ、その直後から予定表上の初回使用時刻順・同時 2 本で
|
|
160
|
-
全音声を非同期にデコードする。デコード済み PCM
|
|
161
|
-
|
|
162
|
-
|
|
159
|
+
全音声を非同期にデコードする。デコード済み PCM は合計バイトで管理し、既定予算は 256 MiB。
|
|
160
|
+
予算を超えても buffer は捨てない(2026-09-02 改訂。以前は次に使う時刻が最も遠い項目から黙って
|
|
161
|
+
退避し、その音源が予定表から消えて無音になっていた)。超過は警告 1 行と `debug().prefetch.overBudget`
|
|
162
|
+
で示す。展開後のサイズが 64 MiB(48 kHz ステレオ約 2.9 分)を超えると見積もられる音源は、
|
|
163
|
+
`OfflineAudioContext` で 24 kHz に落として decode しモノラルへ畳んで保持する(compact。
|
|
164
|
+
プレビュー専用の近似で、納品マスターには影響しない)。見積もりは WAV / FLAC のヘッダから、
|
|
165
|
+
他の圧縮音声は符号化サイズの 16 倍で行う。再生開始は先読み済みの項目を再利用し、未着の項目だけを
|
|
166
|
+
待つため、先読み処理は初期フレームの描画を止めない。decode に失敗した項目は 5 秒空けて再試行し、
|
|
167
|
+
それまで `debug().prefetch.failed` に載る。
|
|
@@ -126,7 +126,7 @@ ffmpeg / ffprobe / whisper.cpp を直接叩いている。本契約はそれを
|
|
|
126
126
|
transcribe の要否を決めるゲートに使い、字幕の根拠にはしない
|
|
127
127
|
- 目安コスト: 秒。帳面には `tracks.waveform` として追記(§3)
|
|
128
128
|
|
|
129
|
-
### 2.5 `akari media transcribe <target> [--in <time> --out <time>] [--backend <name>] [--lang <code>] [--no-unrecognized] [--unrecognized-min-gap <sec>] [--unrecognized-min-voiced <sec>]`
|
|
129
|
+
### 2.5 `akari media transcribe <target> [--in <time> --out <time>] [--backend <name>] [--lang <code>] [--no-unrecognized] [--unrecognized-min-gap <sec>] [--unrecognized-min-voiced <sec>] [--no-word-book] [--word-book <path>]`
|
|
130
130
|
|
|
131
131
|
何を喋っているかを、語ごとの時刻つきで返す。
|
|
132
132
|
|
|
@@ -144,6 +144,7 @@ ffmpeg / ffprobe / whisper.cpp を直接叩いている。本契約はそれを
|
|
|
144
144
|
|
|
145
145
|
- `segments[]` の形は analysis.json v0 の `transcript[]` と同一(そのまま写せる)。時刻は **source 秒**
|
|
146
146
|
- 各 segment は任意の `unrecognized: [{ start, end }]` に「音はあるが文字にできなかった区間」を持てる。既定は語の隙間 0.45 秒以上から無音を引いた残り 0.3 秒以上を採用し、`--unrecognized-min-gap` / `--unrecognized-min-voiced` で閾値を変え、`--no-unrecognized` で検出を止める。キャッシュ key は従来どおりで、古い cache hit に `unrecognized` が無い場合は仕様どおりそのまま返し、再 transcribe で付与する
|
|
147
|
+
- 既定では STT 直後に作業場基底の単語帳を語境界で適用する。`--no-word-book` で無効化し、`--word-book <path>` で project より近い検証用の層を追加できる。文字起こしキャッシュは置換前の生出力を保存し、単語帳プリパスは cache hit / miss ともキャッシュ読み出し後・analysis.json 記録前に毎回適用する
|
|
147
148
|
- バックエンドは analyze-footage の 3 層と同じ優先順: macOS SpeechAnalyzer(26+・swiftc 可)→ whisper.cpp → クラウド。
|
|
148
149
|
**クラウドは `--backend cloud:<connection-id>` を明示したときだけ**で、`.akari/connections.json` に doctor `ok` で
|
|
149
150
|
登録済みの接続に限る。既定で外部に音声を送らない。キーの値を stdout / stderr / 出力ファイルに出さない
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
# 音声クリップ FX v1
|
|
2
|
+
|
|
3
|
+
- 日付: 2026-09-02
|
|
4
|
+
- 状態: 実装契約
|
|
5
|
+
- 対象: legacy `audio.*`、v2 audio item、render-cut、preview-audio sidecar
|
|
6
|
+
|
|
7
|
+
## 1. 宣言
|
|
8
|
+
|
|
9
|
+
| キー | 対象 | 型・範囲 | 既定 | v2 の位置 |
|
|
10
|
+
|---|---|---|---|---|
|
|
11
|
+
| `speed` | sfx / bgm | number `(0.25, 4]` | `1` | `item.source` |
|
|
12
|
+
| `pitch_semitones` | sfx / bgm | number `[-24, 24]` | `0` | `item.source` |
|
|
13
|
+
| `formant` | sfx / bgm | `preserve \| shift` | `preserve` | `item.source` |
|
|
14
|
+
| `denoise` | sfx / bgm / narration | `{ method: fft \| nlm, strength: 0..1 }` | なし | item |
|
|
15
|
+
| `lowcut_hz` | sfx / bgm / narration | number `[0, 400]` | `0` | item |
|
|
16
|
+
|
|
17
|
+
`speed` はタイムライン上の `t` を変えず、実効尺を素材窓の尺 / `speed` とする。
|
|
18
|
+
`pitch_semitones` は速度を変えない。narration の `speed` / `pitch_semitones` は TTS 側の責務なので
|
|
19
|
+
lint warning として無視する。legacy と v2 の投影は上表の値を往復で保持する。
|
|
20
|
+
|
|
21
|
+
## 2. フィルタチェーン
|
|
22
|
+
|
|
23
|
+
クリップごとの順序は次で固定する。
|
|
24
|
+
|
|
25
|
+
`atrim(in/out)` → `highpass=f=<lowcut_hz>:p=2` → `highpass=f=<lowcut_hz>:p=2` → denoise →
|
|
26
|
+
`rubberband=tempo=<speed>:pitch=<2^(pitch_semitones/12)>:formant=<preserved|shifted>:pitchq=quality` →
|
|
27
|
+
`volume` → `afade` → envelope `amultiply` → `adelay`
|
|
28
|
+
|
|
29
|
+
lowcut は同一の 2 次 highpass を 2 段カスケードし、24 dB/oct の減衰特性で L1 ゲート
|
|
30
|
+
(1 oct 下で 15 dB 以上の減衰)を満たすための裁定逸脱とする。
|
|
31
|
+
|
|
32
|
+
denoise は `fft` なら `afftdn=nr=<12+strength*76>:nf=-30`、`nlm` なら
|
|
33
|
+
`anlmdn=s=<0.00001+strength*0.0002>` とする。rubberband は `speed != 1` または
|
|
34
|
+
`pitch_semitones != 0` のときだけ作る。全キーが既定なら入力もフィルタも追加せず、従来の
|
|
35
|
+
filtergraph をバイト単位で維持する。
|
|
36
|
+
|
|
37
|
+
fade、envelope、duck のクリップ窓は speed 適用後の実効尺を使う。BGM は素材先頭へ戻る既存の
|
|
38
|
+
ループ意味論を保ち、ループした入力に同じ clip FX を適用してタイムライン尺へ切る。
|
|
39
|
+
|
|
40
|
+
## 3. プレビューサイドカー
|
|
41
|
+
|
|
42
|
+
recipe は `preview-audio-flac-v2`。対象クリップの `[in,out)` を `atrim` し、上記と同じ
|
|
43
|
+
clip-FX フィルタ生成関数で処理して 48 kHz FLAC へ焼く。cache key は source の絶対パス・size・
|
|
44
|
+
mtime・in/out・pad・recipe に加え、`atrim` を含む完全なフィルタ列を含む。同一入力・同一列は
|
|
45
|
+
同じ FLAC を再利用し、列が変われば別 key にする。掃除は従来どおり keep key 以外の FLAC と
|
|
46
|
+
旧 `speech-atempo/*.wav` を除く。
|
|
47
|
+
|
|
48
|
+
サイドカー化された sfx / bgm / narration は Web Audio で `playbackRate = 1` とし、FLAC の実尺を
|
|
49
|
+
予定表の実効尺にする。生成失敗時はプレビューを停止せず元ファイルへ退避し、書き出しとの近似が
|
|
50
|
+
崩れる旨を warning 1 行で報告する。
|
|
51
|
+
|
|
52
|
+
## 4. provenance と残す近似
|
|
53
|
+
|
|
54
|
+
receipt の `provenance.audio.clip_fx` は `processed_items` と `filters` の件数を持つ。
|
|
55
|
+
プレビューと書き出しで意図的に残す近似は、サイドカー FLAC の再圧縮とデコーダ/サンプル境界の
|
|
56
|
+
差だけとする。
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
# 音声エンベロープ・カーネル v1
|
|
2
|
+
|
|
3
|
+
- 日付: 2026-09-02
|
|
4
|
+
- 状態: 実装契約
|
|
5
|
+
- 対象: legacy `audio.*`、v2 audio item、Web Audio プレビュー、render-cut
|
|
6
|
+
|
|
7
|
+
## 1. 共通 primitive
|
|
8
|
+
|
|
9
|
+
`EnvelopePoint` は `{ t, gainDb, easing? }` とし、`t` はクリップ先頭を 0 とする秒、`gainDb` は
|
|
10
|
+
基準ゲインへ加える dB である。点の前後は端点値を保持し、点間は overlay keyframe と同じ easing
|
|
11
|
+
係数で dB 補間する。`hold` は前値保持、既定は `linear` とする。
|
|
12
|
+
|
|
13
|
+
エンベロープ同士は dB 加算する。非線形区間は最大 20 ms 間隔の折線へ展開する。Web Audio では
|
|
14
|
+
dB 線形区間を `exponentialRampToValueAtTime` へ変換し、線形ゲインの下限を `1e-4`(-80 dB)とする。
|
|
15
|
+
書き出しでは同じ評価関数を 48 kHz の mono f32le に標本化する。
|
|
16
|
+
|
|
17
|
+
## 2. 音量キーフレーム
|
|
18
|
+
|
|
19
|
+
| 形式 | 宣言 | 時刻 | 範囲 |
|
|
20
|
+
|---|---|---|---|
|
|
21
|
+
| v2 audio item | `keyframes[].gain_db` | item 相対の整数フレーム | `[-60, 12]` dB |
|
|
22
|
+
| legacy bgm / sfx / narration | `keyframes[].gain_db` | クリップ相対秒 | `[-60, 12]` dB |
|
|
23
|
+
|
|
24
|
+
v2 の visual 用キーは audio item では無視し、lint warning を出す。legacy view は v2 のフレームを
|
|
25
|
+
`output.fps` で秒へ変換する。キーフレーム値はクリップの `gain_db` に加算し、fade と ducking とは
|
|
26
|
+
独立に線形領域で乗算する。
|
|
27
|
+
|
|
28
|
+
## 3. ダッキング
|
|
29
|
+
|
|
30
|
+
| キー | 型・範囲 | 既定 | 意味 |
|
|
31
|
+
|---|---|---|---|
|
|
32
|
+
| `ducking` | boolean | `false` | bgm / sfx を対象にする |
|
|
33
|
+
| `duck_db` | `[-40, 0]` dB | `-12` | 減衰量 |
|
|
34
|
+
| `duck_attack` | `[0, 2]` 秒 | `0.3` | 鍵開始前の下降時間 |
|
|
35
|
+
| `duck_release` | `[0, 5]` 秒 | `0.8` | 鍵終了後の復帰時間 |
|
|
36
|
+
| `audio.duck_keys` | `narration` / `speech` の配列 | 両方 | 鍵の選択 |
|
|
37
|
+
|
|
38
|
+
2026-09-02 のオーナー実機フィードバック「切り替わりが急」を受け、既定の attack / release をよりなだらかに変更した。
|
|
39
|
+
|
|
40
|
+
`narration` 鍵は配置時刻とデコード/probe 実尺から作る。`speech` 鍵はプロジェクト直下の
|
|
41
|
+
`analysis.json` にある source 秒の transcript を、cut の in / out / speed と timeline map で写像する。
|
|
42
|
+
source は analysis.json の所在ディレクトリ基準で正規化し、`sources[].path` と一致する cut だけを使う。
|
|
43
|
+
350 ms 未満の発話間隔は結合し、150 ms 未満の孤立区間は捨てる。analysis 不在・空・source 不一致は
|
|
44
|
+
空の鍵と warning 1 行へ劣化する。
|
|
45
|
+
|
|
46
|
+
鍵区間の隙間が `attack + release` 未満なら結合する。各区間 `[s,e)` は `s-attack` の 0 dB から
|
|
47
|
+
`s` の `duck_db` へ下降し、`e` まで保持して `e+release` で 0 dB に戻る。負時刻は 0 に固定し、
|
|
48
|
+
対象クリップへ相対化して範囲外を切り詰める。実効ゲインは
|
|
49
|
+
`gain_db + keyframes(t) + duck(t)` を線形化した値に fade を掛けたものとする。
|
|
50
|
+
|
|
51
|
+
## 4. プレビュー
|
|
52
|
+
|
|
53
|
+
`audio-schedule` は全音声 kind に `envelopeEvents` を出す。frame-engine はイベントがある場合だけ
|
|
54
|
+
第 2 GainNode を作り、`setValueAtTime` または `exponentialRampToValueAtTime` で適用する。
|
|
55
|
+
`duckIntervals` は UI 表示互換のため残す。
|
|
56
|
+
|
|
57
|
+
現版では preview-server へ speech interval を供給する配線はスコープ外である。入力が無い場合は
|
|
58
|
+
narration 鍵だけで動作し、共通カーネル自体と render-cut の speech 写像を正とする。
|
|
59
|
+
|
|
60
|
+
## 5. 書き出し
|
|
61
|
+
|
|
62
|
+
`sidechaincompress` と narration 分岐用 `asplit` は使用しない。keyframe または実際の duck 区間を持つ
|
|
63
|
+
対象だけに `env-<label>.f32` を作り、48 kHz mono f32le 入力として読む。対象音声は `amultiply` の直前に
|
|
64
|
+
`aformat=sample_fmts=fltp:sample_rates=48000:channel_layouts=stereo` で stereo/fltp に揃え、mono 素材には
|
|
65
|
+
既定 rematrix の mono→stereo 係数を適用する。env は
|
|
66
|
+
`aformat=sample_fmts=fltp:sample_rates=48000,pan=stereo|c0=c0|c1=c0` で左右へ単位ゲインの等倍複製を行う。
|
|
67
|
+
これにより `amultiply` は素材のチャンネル数によらず常に stereo×stereo になる。挿入位置は `volume` と
|
|
68
|
+
`afade` の後、`adelay` の前とする。全区間 0 dB なら envelope 入力を作らず、従来 filtergraph を維持する。
|
|
69
|
+
|
|
70
|
+
音声クリップ FX v1 を持つ入力では、チェーンを `atrim` → `highpass` → `afftdn` / `anlmdn` →
|
|
71
|
+
`rubberband` → `volume` → `afade` → envelope `amultiply` → `adelay` の順に固定する。したがって
|
|
72
|
+
clip FX は envelope の前段に入り、speed 適用後の実効尺を envelope と duck のクリップ窓に使う。
|
|
73
|
+
|
|
74
|
+
run / receipt の provenance は `audio.envelope` に `duck_keys`、`speech_intervals`、`ducked_items`、
|
|
75
|
+
`keyframed_items` を記録する。plan は配列そのものを保持せず、path と点数だけを JSON 化する。
|
|
76
|
+
|
|
77
|
+
## 6. 検証と互換
|
|
78
|
+
|
|
79
|
+
schema と reader は型・範囲・時刻順を error にする。lint は実効尺超過、narration の
|
|
80
|
+
`ducking:true`、v2 audio keyframe の visual キーを warning にする。legacy の
|
|
81
|
+
`STATIC_DUCK_GAIN_DB`、`computeDuckIntervals`、`isWithinDuckInterval` は既存 shell 消費者の移行まで
|
|
82
|
+
互換面として残す。
|
|
83
|
+
|
|
84
|
+
| 処理 | プレビュー | 書き出し |
|
|
85
|
+
|---|---|---|
|
|
86
|
+
| keyframe / duck 補間 | 共通 dB envelope → exponential automation | 共通 dB envelope → f32le → `amultiply` |
|
|
87
|
+
| fade | base GainNode | `afade` |
|
|
88
|
+
| 鍵実尺 | decode 実尺 | ffprobe 実尺 |
|
|
89
|
+
| 許容する差 | デコーダとサンプル境界 | デコーダとサンプル境界 |
|
|
90
|
+
|
|
91
|
+
afftdn、loudnorm、true peak guard は最終マスターだけの責務であり、プレビューには実装しない。
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
# 音声素材の挿入時レベル契約 v1
|
|
2
|
+
|
|
3
|
+
- 日付: 2026-09-02
|
|
4
|
+
- 状態: 実装済み(S1)
|
|
5
|
+
- 前提: `contract-2026-07-14-edit-json-v1-audio.md`、
|
|
6
|
+
`contract-2026-07-20-edit-json-v1-narration.md`、
|
|
7
|
+
`contract-2026-08-28-v2-audio-roles-v0.md`
|
|
8
|
+
- スコープ: 音声素材単体の決定論的なレベル計測、役割別挿入値の計算、
|
|
9
|
+
`akari media audio-level` による dry-run と edit.json への明示値保存
|
|
10
|
+
|
|
11
|
+
## 1. 原則
|
|
12
|
+
|
|
13
|
+
自動レベル合わせは再生中の追従処理ではない。素材を挿入するときに測定し、同じ入力から同じ
|
|
14
|
+
`gain_db` と既定 fade を導出して edit.json に数値として残す。以後のプレビューと書き出しは
|
|
15
|
+
その宣言値を消費する。素材カタログの既存ラウドネス値は使わず、外部素材と同じ実体計測を行う。
|
|
16
|
+
|
|
17
|
+
## 2. 計測契約
|
|
18
|
+
|
|
19
|
+
計測器の metric は `akari-audio-measure-v1` とし、次を返す。
|
|
20
|
+
|
|
21
|
+
| フィールド | 単位 | 定義 |
|
|
22
|
+
|---|---:|---|
|
|
23
|
+
| `integrated_lufs` | LUFS | EBU R128 Summary の I。-70.0 LUFS 以下または解析不能は `null` |
|
|
24
|
+
| `loudness_range_lu` | LU | EBU R128 Summary の LRA。I が無効なら `null` 可 |
|
|
25
|
+
| `true_peak_dbtp` | dBTP | EBU R128 Summary の Peak。無音の `-inf` は `null` |
|
|
26
|
+
| `sample_peak_dbfs` | dBFS | astats Overall の Peak level。無音の `-inf` は `null` |
|
|
27
|
+
| `rms_dbfs` | dBFS | astats Overall の RMS level。無音の `-inf` は `null` |
|
|
28
|
+
| `duration_sec` | 秒 | ffprobe format duration |
|
|
29
|
+
| `sample_rate` | Hz | ffprobe の先頭 audio stream |
|
|
30
|
+
| `channels` | — | ffprobe の先頭 audio stream |
|
|
31
|
+
|
|
32
|
+
ffmpeg は音声ごとに 1 パスだけ実行し、次の引数を使う。
|
|
33
|
+
|
|
34
|
+
```text
|
|
35
|
+
-vn -sn -dn -af ebur128=peak=true:framelog=verbose,astats=measure_perchannel=none:measure_overall=Peak_level+RMS_level -f null -
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
duration / sample rate / channels は ffprobe で決定論的に取得する。パーサは最後の ebur128
|
|
39
|
+
`Summary:` と astats `Overall` を読み、映像・字幕・data stream は計測対象にしない。
|
|
40
|
+
|
|
41
|
+
### 2.1 キャッシュ
|
|
42
|
+
|
|
43
|
+
素材の realpath、byte size、`mtimeMs`、metric を `|` で連結し、
|
|
44
|
+
`sha1(realpath|size|mtimeMs|metric)` を key とする。保存先は
|
|
45
|
+
`<cacheDir>/<key>.json`。`akari media audio-level` の cacheDir は
|
|
46
|
+
`<projectRoot>/.akari/cache/audio-measure/` である。単体の `akari-audio-measure` CLI も素材の
|
|
47
|
+
親から上へ辿って最初に `.akari` ディレクトリを持つ projectRoot を使い、見つからない場合だけ
|
|
48
|
+
素材の親を projectRoot とみなす。`--no-cache` または `useCache: false` は
|
|
49
|
+
必ず再計測し、同じ key の JSON を上書きする。
|
|
50
|
+
|
|
51
|
+
## 3. 役割別の目標
|
|
52
|
+
|
|
53
|
+
| role | integrated target (LUFS) | fade in (s) | fade out (s) |
|
|
54
|
+
|---|---:|---:|---:|
|
|
55
|
+
| narration | -16 | 0 | 0 |
|
|
56
|
+
| sfx | -18 | 0 | 0 |
|
|
57
|
+
| jingle | -18 | 0 | 0.3 |
|
|
58
|
+
| music | -20 | 0.2 | 1.0 |
|
|
59
|
+
| ambience | -26 | 0.5 | 0.5 |
|
|
60
|
+
| bgm | -26 | 0 | 0 |
|
|
61
|
+
|
|
62
|
+
true peak ceiling は -1.0 dBTP、短尺境界は 1.0 秒、短尺 sample peak target は -3.0 dBFS。
|
|
63
|
+
未知 role は目標と fade の両方で sfx として扱う。
|
|
64
|
+
|
|
65
|
+
## 4. 挿入値の式
|
|
66
|
+
|
|
67
|
+
`computeInsertLevel` は次の順序で 1 回だけ値を決める。
|
|
68
|
+
|
|
69
|
+
1. 計測値が無ければ `basis: none`、`gain_db: 0` と役割既定 fade を返す。
|
|
70
|
+
2. `duration_sec < 1.0` または `integrated_lufs == null` なら `basis: peak` とし、
|
|
71
|
+
`gain = -3.0 - sample_peak_dbfs`。sample peak も無ければ 1 と同じ。
|
|
72
|
+
3. それ以外は `basis: lufs` とし、`gain = role target - integrated_lufs`。
|
|
73
|
+
4. true peak があれば `gain = min(gain, ceilingDbtp - true_peak_dbtp)` とする。
|
|
74
|
+
実際に gain を下げた場合だけ `peak_guard_applied: true`。
|
|
75
|
+
5. gain を `[-60, 12]` へクランプした後、`Math.round(x * 10) / 10` で 0.1 dB に丸める。
|
|
76
|
+
`-0` は `0` に正規化する。
|
|
77
|
+
|
|
78
|
+
`detail` は採用 target、計測値、peak guard 適用有無、クランプ有無を保持する。
|
|
79
|
+
|
|
80
|
+
## 5. 役割判定
|
|
81
|
+
|
|
82
|
+
v2 の明示 `role` が narration / bgm / jingle / music / ambience なら最優先し、そのまま使う。
|
|
83
|
+
それ以外(sfx、未知、未指定)は legacy collection の bgm / narration を優先した後、SFX
|
|
84
|
+
ヒューリスティクスへ進む。パスを小文字化し、`jingle` / `sting` を含めば jingle、
|
|
85
|
+
`ambien` / `room` / `env` を含めば ambience、計測尺が 20 秒以上なら music、それ以外は sfx とする。
|
|
86
|
+
|
|
87
|
+
## 6. CLI
|
|
88
|
+
|
|
89
|
+
```text
|
|
90
|
+
akari media audio-level <projectDir> [--write] [--targets '<json>'] [--ceiling <dBTP>] [--json] [--no-cache]
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
v2 の audio lane items と legacy `audio.bgm` / `audio.sfx[]` / `audio.narration[]` を読み、
|
|
94
|
+
`gain_db` 未指定の項目だけを対象とする。素材パスは edit.json の親ディレクトリ基準。
|
|
95
|
+
dry-run の標準出力は header と 1 クリップ 1 行の表で、path / role / basis / I / TP /
|
|
96
|
+
`gain_db` / `fade_in` / `fade_out` を含む。`--json` は同じ結果の JSON 配列 1 つだけを返す。
|
|
97
|
+
素材不在または計測不能は stderr の warning 1 行でその項目だけを省く。対象 0 件は exit 0。
|
|
98
|
+
|
|
99
|
+
`--write` は `gain_db` と、未指定の `fade_in` / `fade_out` だけを書く。v2 は Project API の
|
|
100
|
+
item patch、legacy は edit-store の既存書き込み API を使う。保存後に edit-lint を実行し、
|
|
101
|
+
severity `error` が 1 件でもあれば退避した edit.json 全文を戻す。成功後の再実行は対象 0 件で
|
|
102
|
+
あり、冪等である。
|
|
103
|
+
|
|
104
|
+
legacy 形(version 0/1)は現行 edit-lint が「古い形式」として error にするため、`--write` は
|
|
105
|
+
常に巻き戻される(dry-run / `--json` は利用できる)。書き込む場合は `akari migrate` で v2 にしてから実行する。
|
|
106
|
+
|
|
107
|
+
## 7. 次段
|
|
108
|
+
|
|
109
|
+
設定(`audio.level_targets` / アプリ設定)と shell 挿入フックは S2 / 別票とする。
|
|
110
|
+
本契約では schema、設定画面、実行時追従、shell UI を追加しない。
|
|
@@ -69,9 +69,15 @@ duration(own) = item.duration
|
|
|
69
69
|
`resolveItemAnchors` を通してから内部モデルを構築する。渡されない場合は `at` / `duration` の
|
|
70
70
|
キャッシュを従来どおり読み、アンカー導入前の挙動を変えない。
|
|
71
71
|
|
|
72
|
-
|
|
73
|
-
`options.captions`
|
|
74
|
-
|
|
72
|
+
render-cut / gpu / osr / shell preview / preview-server の各出口は、captions.json を
|
|
73
|
+
`toAnchorCaptions` で正規化して `readInternalEdit` の `options.captions` へ渡し、読込時にアンカーを
|
|
74
|
+
再解決する。captions.json が無い場合は従来どおり `at` / `duration` のキャッシュを読む。
|
|
75
|
+
|
|
76
|
+
字幕の時刻・参照集合を変える `setCaptionTiming` / `shiftCaption` / `insertCaption` /
|
|
77
|
+
`removeCaption` は、captions.json の書き込み後に `refreshItemAnchors` でキャッシュを更新する。
|
|
78
|
+
`writeEditSnapshot` と preview-server の captions PUT は呼び出し側が再解決の責務を持つ。
|
|
79
|
+
captions.json と edit.json の 2 ファイル間に原子性はなく、途中で停止してキャッシュが古くなった場合は
|
|
80
|
+
lint `v2.item-anchor-stale` が検出する。
|
|
75
81
|
|
|
76
82
|
## 4. mutation
|
|
77
83
|
|
|
@@ -94,8 +100,6 @@ duration(own) = item.duration
|
|
|
94
100
|
## 6. 非スコープ
|
|
95
101
|
|
|
96
102
|
- 台本パネルの単語範囲ドラッグ、🎬 ボタンその他の UI
|
|
97
|
-
- annotations の RPC / mutation wrapper
|
|
98
|
-
- 出口側への `options.captions` 配線と字幕保存時の自動再解決
|
|
99
103
|
- `itemAtV2` の string 拡張
|
|
100
104
|
- 単語 index アンカー
|
|
101
105
|
- `captions` / `caption` item へのアンカー
|
|
@@ -55,3 +55,24 @@ schema と validator は配列、要素の exact keys、有限・非負の `star
|
|
|
55
55
|
|
|
56
56
|
confidence、低確信の認識語を示すマーカー、未認識区間の自動置換・自動カットは本契約に含めない。
|
|
57
57
|
SpeechAnalyzer や cloud バックエンド固有の非発話マーカー解釈も追加せず、語間隙からの検出だけを共通適用する。
|
|
58
|
+
|
|
59
|
+
## 7. パネル側の約束(T5b)
|
|
60
|
+
|
|
61
|
+
台本パネルは各未認識区間を `??` 固定で時刻順に表示する。表示位置は `span.start >= words[i].end` を
|
|
62
|
+
満たす最後の語の直後とし、該当語が無ければ行頭、最後の語より後なら行末へ置く。`words[]` が無い行では
|
|
63
|
+
本文の末尾へ並べる。`??` は字幕語やカラオケの語 index には含めない。
|
|
64
|
+
|
|
65
|
+
聞き取った文字への置換は、`setCaptionFields` の `text` と `unrecognized` を 1 回の書き戻しで更新する。
|
|
66
|
+
本文では `??` の直前にある語の直後へ文字を挿入し、対象区間だけを `unrecognized[]` から除く。新しい語の
|
|
67
|
+
時刻は共通カーネル `rederiveCaptionWords` が前後の保持語の間へ配分し、既存の他語は変更しない。
|
|
68
|
+
|
|
69
|
+
映像ごとのカットは対象の `[start, end]` をパディングせず、`kind: 'unrecognized'` として
|
|
70
|
+
`applyCutRanges` へ渡す。カット成功後に対象区間を `unrecognized[]` から除き、字幕側の更新に失敗した場合は
|
|
71
|
+
カット前の edit.json を復元する。
|
|
72
|
+
|
|
73
|
+
文字起こしタブの再生成直列化器と edit-store の `insertCaptionLine` 直列化器は、どちらも非空の
|
|
74
|
+
`unrecognized[]` を保全する。再生成では `edited: true` の行と対応 segment が無い行の既存値をそのまま保ち、
|
|
75
|
+
`edited: false` の再生成行と新規行は analysis segment の区間を字幕の `[start, end]` へミリ秒単位で
|
|
76
|
+
切り詰め、時刻順に並べて隣接・重複区間を結合して持ち越す。空になった配列は書かない。
|
|
77
|
+
|
|
78
|
+
低確信の認識語を示すマーカー、1 個の `?`、および `???` の使い分けは T5b の非スコープとする。
|