akari-video 0.1.52 → 0.1.53
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/packages/akari-launcher/package.json +1 -1
- package/vendor/packages/media-bin/package.json +1 -1
- package/vendor/packages/media-bin/src/binary-manifest.mjs +12 -0
- package/vendor/packages/media-bin/src/index.mjs +13 -6
- package/vendor/packages/media-bin/test/media-bin.test.mjs +37 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "akari-video",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.53",
|
|
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": {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "akari-video",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.53",
|
|
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 組み込みモジュールのみ)。 [akari-video npm vendor: bin/akari.mjs is reference-only. These CLI entrypoints are not included in the akari-video npm package. Use `akari doctor --json` and run the path reported in `render_cut.path`. Full installations provide it in a monorepo checkout, ~/.akari/app, /Applications/AKARI Video.app/Contents/Resources/packages, or %LOCALAPPDATA%\\Programs\\@akari-videoshell\\resources\\packages.]",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"files": [
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
"version": "0.1.0",
|
|
4
4
|
"private": true,
|
|
5
5
|
"type": "module",
|
|
6
|
-
"description": "ffmpeg / ffprobe / whisper-cli バイナリ解決の一元化。ffmpeg/ffprobe の探索順: AKARI_FFMPEG_BIN / AKARI_FFPROBE_BIN(明示指定) → FFMPEG_PATH(ffmpeg の既存互換) → PATH → 同梱バイナリ(vendor/ 配下。binary-manifest.mjs でピン留めした GPL-only
|
|
6
|
+
"description": "ffmpeg / ffprobe / whisper-cli バイナリ解決の一元化。ffmpeg/ffprobe の探索順: AKARI_FFMPEG_BIN / AKARI_FFPROBE_BIN(明示指定) → FFMPEG_PATH(ffmpeg の既存互換) → PATH → 同梱バイナリ(vendor/ 配下。binary-manifest.mjs でピン留めした GPL-only・真ネイティブビルド) → パッケージ版同梱(extraResources の media-bin/ 配下)。whisper-cli の探索順は AKARI_WHISPER_BIN → vendor 同梱 → PATH → パッケージ版同梱(win32 は公式リリース zip、macOS は release CI のソースビルド)。",
|
|
7
7
|
"main": "src/index.mjs",
|
|
8
8
|
"exports": {
|
|
9
9
|
".": "./src/index.mjs"
|
|
@@ -78,6 +78,18 @@ export function vendorBinaryPath(name, target = currentTarget()) {
|
|
|
78
78
|
return path.join(VENDOR_ROOT, target, exeName);
|
|
79
79
|
}
|
|
80
80
|
|
|
81
|
+
/**
|
|
82
|
+
* extraResources の packages/media-bin と media-bin の相対配置から同梱候補を返す。
|
|
83
|
+
* ELECTRON_RUN_AS_NODE の子プロセスにも対応するため process.resourcesPath は使わない。
|
|
84
|
+
* 存在するとは限らないため、呼び出し側が existsSync で確認する。
|
|
85
|
+
* @param {"ffmpeg"|"ffprobe"|"whisper-cli"} name
|
|
86
|
+
* @param {string} [target]
|
|
87
|
+
*/
|
|
88
|
+
export function packagedBinaryPath(name, target = currentTarget()) {
|
|
89
|
+
const exeName = target.startsWith("win32-") ? `${name}.exe` : name;
|
|
90
|
+
return path.resolve(packageRoot, "../..", "media-bin", exeName);
|
|
91
|
+
}
|
|
92
|
+
|
|
81
93
|
const MARTIN_RIEDL_LICENSE =
|
|
82
94
|
"GPL-3.0-or-later build (--enable-gpl, no --enable-nonfree; libx264/libx265 dual-licensed under GPL). " +
|
|
83
95
|
"Source: https://git.martin-riedl.de/ffmpeg/build-script — codec/library list: https://ffmpeg.martin-riedl.de/#info";
|
|
@@ -3,10 +3,12 @@
|
|
|
3
3
|
// ffmpeg/ffprobe の探索順: 明示指定(AKARI_FFMPEG_BIN / AKARI_FFPROBE_BIN。パス区切りのない
|
|
4
4
|
// 値は PATH で解決) → 既存互換(FFMPEG_PATH、ffmpeg のみ。同じ規則) → PATH → 同梱バイナリ
|
|
5
5
|
// (vendor/ 配下。binary-manifest.mjs でピン留めした GPL-only・真ネイティブビルドを
|
|
6
|
-
// postinstall で取得済み — task/2026-08-01-gpl-only-ffmpeg-swap
|
|
6
|
+
// postinstall で取得済み — task/2026-08-01-gpl-only-ffmpeg-swap) → パッケージ版同梱
|
|
7
|
+
// (extraResources の media-bin/ 配下。packageRoot からの相対配置で解決)。
|
|
7
8
|
//
|
|
8
9
|
// whisper-cli の探索順は意図的に異なる(task/2026-08-17-media-bin-whisper 契約どおり):
|
|
9
|
-
// 明示指定(AKARI_WHISPER_BIN) →
|
|
10
|
+
// 明示指定(AKARI_WHISPER_BIN) → vendor 同梱 → PATH → パッケージ版同梱。
|
|
11
|
+
// ffmpeg は「PATH 優先」が既存
|
|
10
12
|
// システムインストールとの互換性のための既定だが、whisper-cli は事前の既存インストール
|
|
11
13
|
// 慣行が無く、PATH 上に無関係な古い whisper.cpp(CLI 引数の互換性が保証されない)が
|
|
12
14
|
// 入っている可能性の方がリスクなので、アプリが版固定でピン留めした同梱バイナリを優先する。
|
|
@@ -18,7 +20,7 @@ import { spawnSync } from "node:child_process";
|
|
|
18
20
|
import { existsSync } from "node:fs";
|
|
19
21
|
import { platform } from "node:os";
|
|
20
22
|
|
|
21
|
-
import { vendorBinaryPath } from "./binary-manifest.mjs";
|
|
23
|
+
import { vendorBinaryPath, packagedBinaryPath } from "./binary-manifest.mjs";
|
|
22
24
|
|
|
23
25
|
const FFMPEG_INSTALL_HINT = {
|
|
24
26
|
darwin: " brew install ffmpeg",
|
|
@@ -66,7 +68,7 @@ function resolveExplicit(envVar, value, env) {
|
|
|
66
68
|
);
|
|
67
69
|
}
|
|
68
70
|
|
|
69
|
-
function notFoundMessage({ label, envVar, legacyEnvVar, vendorPath, installHint, preferVendorOverPath }) {
|
|
71
|
+
function notFoundMessage({ label, envVar, legacyEnvVar, vendorPath, packagedPath, installHint, preferVendorOverPath }) {
|
|
70
72
|
const legacyStep = legacyEnvVar ? ` → ${legacyEnvVar}(既存互換・同じ規則)` : "";
|
|
71
73
|
const searchOrder = preferVendorOverPath
|
|
72
74
|
? `${envVar}(明示指定: 絶対パス / PATH 上のコマンド名)${legacyStep} → 同梱バイナリ(${vendorPath}) → PATH`
|
|
@@ -75,6 +77,7 @@ function notFoundMessage({ label, envVar, legacyEnvVar, vendorPath, installHint,
|
|
|
75
77
|
`${label} が見つかりませんでした。`,
|
|
76
78
|
"",
|
|
77
79
|
`探索順: ${searchOrder}`,
|
|
80
|
+
` → パッケージ版同梱バイナリ(${packagedPath})`,
|
|
78
81
|
"",
|
|
79
82
|
"同梱バイナリは packages/media-bin の npm install(postinstall)で取得されるはずですが、",
|
|
80
83
|
"見つかりませんでした。npm install をやり直すか、対応プラットフォームが無い場合は",
|
|
@@ -114,7 +117,10 @@ function resolveBinary({
|
|
|
114
117
|
|
|
115
118
|
if (vendorExists) return vendorPath;
|
|
116
119
|
|
|
117
|
-
|
|
120
|
+
const packagedPath = packagedBinaryPath(vendorName);
|
|
121
|
+
if (existsSync(packagedPath)) return packagedPath;
|
|
122
|
+
|
|
123
|
+
throw new Error(notFoundMessage({ label, envVar, legacyEnvVar, vendorPath, packagedPath, installHint, preferVendorOverPath }));
|
|
118
124
|
}
|
|
119
125
|
|
|
120
126
|
/**
|
|
@@ -149,7 +155,8 @@ export function resolveFfprobe({ env = process.env } = {}) {
|
|
|
149
155
|
|
|
150
156
|
/**
|
|
151
157
|
* whisper-cli バイナリの絶対パス(または PATH 解決に委ねるコマンド名)を返す。
|
|
152
|
-
* 探索順は env →
|
|
158
|
+
* 探索順は env → vendor 同梱 → PATH → パッケージ版同梱
|
|
159
|
+
* (ffmpeg とは順序が異なる — ファイル冒頭コメント参照)。
|
|
153
160
|
* @param {{ env?: NodeJS.ProcessEnv }} [opts]
|
|
154
161
|
*/
|
|
155
162
|
export function resolveWhisperCli({ env = process.env } = {}) {
|
|
@@ -1,11 +1,15 @@
|
|
|
1
1
|
import assert from "node:assert/strict";
|
|
2
2
|
import { spawnSync } from "node:child_process";
|
|
3
|
+
import fs from "node:fs";
|
|
3
4
|
import { mkdtemp, rm, writeFile, chmod } from "node:fs/promises";
|
|
5
|
+
import { syncBuiltinESMExports } from "node:module";
|
|
4
6
|
import { tmpdir } from "node:os";
|
|
5
7
|
import path from "node:path";
|
|
6
8
|
import test from "node:test";
|
|
9
|
+
import { fileURLToPath } from "node:url";
|
|
7
10
|
|
|
8
11
|
import { resolveFfmpeg, resolveFfprobe } from "../src/index.mjs";
|
|
12
|
+
import { packagedBinaryPath, vendorBinaryPath } from "../src/binary-manifest.mjs";
|
|
9
13
|
|
|
10
14
|
// システムに ffmpeg/ffprobe が入っていても影響を受けないよう、実行の度に
|
|
11
15
|
// AKARI_*_BIN / FFMPEG_PATH を明示的に undefined へ倒したベース env を組み立てる。
|
|
@@ -23,6 +27,39 @@ function baseEnv(overrides = {}) {
|
|
|
23
27
|
// フォールバックだけが効く状態を作る(task.md 記載の `env PATH=/usr/bin:/bin` と同じ狙い)。
|
|
24
28
|
const STRIPPED_PATH_ENV = baseEnv({ PATH: "/usr/bin:/bin" });
|
|
25
29
|
|
|
30
|
+
test("packagedBinaryPath: packageRoot の ../../media-bin を候補にし、win32 は .exe を付ける", () => {
|
|
31
|
+
const packageRoot = fileURLToPath(new URL("../", import.meta.url));
|
|
32
|
+
for (const name of ["ffmpeg", "ffprobe", "whisper-cli"]) {
|
|
33
|
+
for (const target of ["darwin-arm64", "linux-x64", "win32-x64"]) {
|
|
34
|
+
const exe = target.startsWith("win32-") ? `${name}.exe` : name;
|
|
35
|
+
assert.equal(packagedBinaryPath(name, target), path.resolve(packageRoot, "../../media-bin", exe));
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
});
|
|
39
|
+
|
|
40
|
+
test("resolveFfmpeg: vendor / packaged 不在時のエラーに packaged 候補パスを含める", t => {
|
|
41
|
+
const vendorPath = vendorBinaryPath("ffmpeg");
|
|
42
|
+
const packagedPath = packagedBinaryPath("ffmpeg");
|
|
43
|
+
// バイナリを移動せず、候補 2 つの存在確認だけを不在にする。
|
|
44
|
+
const existsSync = fs.existsSync;
|
|
45
|
+
const mockedExists = t.mock.method(fs, "existsSync", candidate =>
|
|
46
|
+
candidate === vendorPath || candidate === packagedPath ? false : existsSync(candidate)
|
|
47
|
+
);
|
|
48
|
+
syncBuiltinESMExports();
|
|
49
|
+
t.after(() => {
|
|
50
|
+
mockedExists.mock.restore();
|
|
51
|
+
syncBuiltinESMExports();
|
|
52
|
+
});
|
|
53
|
+
|
|
54
|
+
assert.throws(() => resolveFfmpeg({ env: STRIPPED_PATH_ENV }), error => {
|
|
55
|
+
assert.match(error.message, /ffmpeg が見つかりませんでした/);
|
|
56
|
+
assert.match(error.message, /探索順:/);
|
|
57
|
+
assert.ok(error.message.includes(vendorPath));
|
|
58
|
+
assert.ok(error.message.includes(`パッケージ版同梱バイナリ(${packagedPath})`));
|
|
59
|
+
return true;
|
|
60
|
+
});
|
|
61
|
+
});
|
|
62
|
+
|
|
26
63
|
async function withFixtureFile(run) {
|
|
27
64
|
const dir = await mkdtemp(path.join(tmpdir(), "akari-media-bin-"));
|
|
28
65
|
const filePath = path.join(dir, "fake-ffmpeg");
|