@effing/ffmpeg 0.4.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.
package/README.md ADDED
@@ -0,0 +1,36 @@
1
+ # @effing/ffmpeg
2
+
3
+ FFmpeg binary downloader for the Effing monorepo. Downloads a platform-specific FFmpeg binary at install time from the [ffmpeg-static](https://github.com/eugeneware/ffmpeg-static) GitHub releases (currently tag **b6.0**, FFmpeg 6.0).
4
+
5
+ ## Usage
6
+
7
+ ```ts
8
+ import { pathToFFmpeg } from "@effing/ffmpeg";
9
+
10
+ // pathToFFmpeg is the absolute path to the binary, or null on unsupported platforms
11
+ ```
12
+
13
+ ## How it works
14
+
15
+ The `install` lifecycle script (`node install.mjs`) runs during `pnpm install` and:
16
+
17
+ 1. Detects the current platform and architecture
18
+ 2. Skips the download if the binary already exists
19
+ 3. Downloads the gzipped binary from GitHub releases
20
+ 4. Decompresses it and sets executable permissions
21
+
22
+ The binary is placed in the package root (`packages/ffmpeg/ffmpeg`). In the monorepo, pnpm symlinks mean all workspace consumers share the same binary.
23
+
24
+ ## Supported platforms
25
+
26
+ | Platform | Architectures |
27
+ | -------- | --------------------- |
28
+ | darwin | x64, arm64 |
29
+ | linux | x64, ia32, arm64, arm |
30
+ | win32 | x64, ia32 |
31
+
32
+ ## Environment variables
33
+
34
+ | Variable | Description |
35
+ | --------------------- | ----------------------------------------------------------------------------------------- |
36
+ | `FFMPEG_BINARIES_URL` | Override the base URL for binary downloads (defaults to the ffmpeg-static GitHub release) |
@@ -0,0 +1,3 @@
1
+ declare const pathToFFmpeg: string | null;
2
+
3
+ export { pathToFFmpeg };
package/dist/index.js ADDED
@@ -0,0 +1,25 @@
1
+ // src/index.ts
2
+ import os from "os";
3
+ import path from "path";
4
+ import { fileURLToPath } from "url";
5
+ var __dirname = path.dirname(fileURLToPath(import.meta.url));
6
+ var SUPPORTED = /* @__PURE__ */ new Set([
7
+ "darwin-x64",
8
+ "darwin-arm64",
9
+ "linux-x64",
10
+ "linux-ia32",
11
+ "linux-arm64",
12
+ "linux-arm",
13
+ "win32-x64",
14
+ "win32-ia32"
15
+ ]);
16
+ var platform = os.platform();
17
+ var arch = os.arch();
18
+ var key = `${platform}-${arch}`;
19
+ var binaryName = platform === "win32" ? "ffmpeg.exe" : "ffmpeg";
20
+ var ffmpegPath = SUPPORTED.has(key) ? path.join(__dirname, "..", binaryName) : null;
21
+ var pathToFFmpeg = ffmpegPath;
22
+ export {
23
+ pathToFFmpeg
24
+ };
25
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/index.ts"],"sourcesContent":["import os from \"node:os\";\nimport path from \"node:path\";\nimport { fileURLToPath } from \"node:url\";\n\nconst __dirname = path.dirname(fileURLToPath(import.meta.url));\n\nconst SUPPORTED = new Set([\n \"darwin-x64\",\n \"darwin-arm64\",\n \"linux-x64\",\n \"linux-ia32\",\n \"linux-arm64\",\n \"linux-arm\",\n \"win32-x64\",\n \"win32-ia32\",\n]);\n\nconst platform = os.platform();\nconst arch = os.arch();\nconst key = `${platform}-${arch}`;\n\nconst binaryName = platform === \"win32\" ? \"ffmpeg.exe\" : \"ffmpeg\";\n\nconst ffmpegPath: string | null = SUPPORTED.has(key)\n ? path.join(__dirname, \"..\", binaryName)\n : null;\n\nexport const pathToFFmpeg = ffmpegPath;\n"],"mappings":";AAAA,OAAO,QAAQ;AACf,OAAO,UAAU;AACjB,SAAS,qBAAqB;AAE9B,IAAM,YAAY,KAAK,QAAQ,cAAc,YAAY,GAAG,CAAC;AAE7D,IAAM,YAAY,oBAAI,IAAI;AAAA,EACxB;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,CAAC;AAED,IAAM,WAAW,GAAG,SAAS;AAC7B,IAAM,OAAO,GAAG,KAAK;AACrB,IAAM,MAAM,GAAG,QAAQ,IAAI,IAAI;AAE/B,IAAM,aAAa,aAAa,UAAU,eAAe;AAEzD,IAAM,aAA4B,UAAU,IAAI,GAAG,IAC/C,KAAK,KAAK,WAAW,MAAM,UAAU,IACrC;AAEG,IAAM,eAAe;","names":[]}
package/install.mjs ADDED
@@ -0,0 +1,103 @@
1
+ import { createWriteStream } from "node:fs";
2
+ import { access, chmod } from "node:fs/promises";
3
+ import https from "node:https";
4
+ import os from "node:os";
5
+ import path from "node:path";
6
+ import { pipeline } from "node:stream/promises";
7
+ import { fileURLToPath } from "node:url";
8
+ import zlib from "node:zlib";
9
+
10
+ const __dirname = path.dirname(fileURLToPath(import.meta.url));
11
+
12
+ const PLATFORM_MAP = {
13
+ darwin: "darwin",
14
+ linux: "linux",
15
+ win32: "win32",
16
+ };
17
+
18
+ const ARCH_MAP = {
19
+ x64: "x64",
20
+ ia32: "ia32",
21
+ arm64: "arm64",
22
+ arm: "arm",
23
+ };
24
+
25
+ const SUPPORTED = new Set([
26
+ "darwin-x64",
27
+ "darwin-arm64",
28
+ "linux-x64",
29
+ "linux-ia32",
30
+ "linux-arm64",
31
+ "linux-arm",
32
+ "win32-x64",
33
+ "win32-ia32",
34
+ ]);
35
+
36
+ const platform = PLATFORM_MAP[os.platform()];
37
+ const arch = ARCH_MAP[os.arch()];
38
+
39
+ if (!platform || !arch || !SUPPORTED.has(`${platform}-${arch}`)) {
40
+ console.warn(
41
+ `@effing/ffmpeg: unsupported platform ${os.platform()}-${os.arch()}, skipping binary download`,
42
+ );
43
+ process.exit(0);
44
+ }
45
+
46
+ const binaryName = platform === "win32" ? "ffmpeg.exe" : "ffmpeg";
47
+ const binaryPath = path.join(__dirname, binaryName);
48
+
49
+ // Skip if binary already exists
50
+ try {
51
+ await access(binaryPath);
52
+ console.log(`@effing/ffmpeg: binary already exists at ${binaryPath}`);
53
+ process.exit(0);
54
+ } catch {
55
+ // Binary doesn't exist, proceed with download
56
+ }
57
+
58
+ const baseUrl =
59
+ process.env.FFMPEG_BINARIES_URL ||
60
+ "https://github.com/eugeneware/ffmpeg-static/releases/download/b6.0";
61
+
62
+ const url = `${baseUrl}/ffmpeg-${platform}-${arch}.gz`;
63
+
64
+ console.log(`@effing/ffmpeg: downloading ffmpeg from ${url}`);
65
+
66
+ /**
67
+ * Follow redirects (GitHub releases redirect to S3/CDN).
68
+ * Returns a readable response stream.
69
+ */
70
+ function get(url, redirects = 0) {
71
+ if (redirects > 5) {
72
+ throw new Error("Too many redirects");
73
+ }
74
+ return new Promise((resolve, reject) => {
75
+ https
76
+ .get(url, (res) => {
77
+ if (res.statusCode >= 300 && res.statusCode < 400 && res.headers.location) {
78
+ res.resume(); // discard body
79
+ resolve(get(res.headers.location, redirects + 1));
80
+ } else if (res.statusCode !== 200) {
81
+ res.resume();
82
+ reject(new Error(`Download failed: HTTP ${res.statusCode} for ${url}`));
83
+ } else {
84
+ resolve(res);
85
+ }
86
+ })
87
+ .on("error", reject);
88
+ });
89
+ }
90
+
91
+ try {
92
+ const response = await get(url);
93
+ const gunzip = zlib.createGunzip();
94
+ const file = createWriteStream(binaryPath);
95
+
96
+ await pipeline(response, gunzip, file);
97
+ await chmod(binaryPath, 0o755);
98
+
99
+ console.log(`@effing/ffmpeg: binary installed to ${binaryPath}`);
100
+ } catch (err) {
101
+ console.error(`@effing/ffmpeg: failed to download binary: ${err.message}`);
102
+ process.exit(1);
103
+ }
package/package.json ADDED
@@ -0,0 +1,33 @@
1
+ {
2
+ "name": "@effing/ffmpeg",
3
+ "version": "0.4.0",
4
+ "description": "FFmpeg binary downloader for Effing",
5
+ "type": "module",
6
+ "exports": {
7
+ ".": {
8
+ "types": "./dist/index.d.ts",
9
+ "import": "./dist/index.js"
10
+ }
11
+ },
12
+ "files": [
13
+ "dist",
14
+ "install.mjs"
15
+ ],
16
+ "scripts": {
17
+ "build": "tsup",
18
+ "typecheck": "tsc --noEmit",
19
+ "install": "node install.mjs"
20
+ },
21
+ "devDependencies": {
22
+ "tsup": "catalog:",
23
+ "typescript": "catalog:"
24
+ },
25
+ "keywords": [
26
+ "ffmpeg",
27
+ "binary"
28
+ ],
29
+ "license": "O'Saasy",
30
+ "publishConfig": {
31
+ "access": "public"
32
+ }
33
+ }