Compare commits

19 Commits

Author SHA1 Message Date
70177202bf fix?: possible fix to #1
Signed-off-by: Alix von Schirp <github@avonschirp.bootmedia.de>
2026-02-27 02:02:56 +01:00
bcd311352c chore: move to pnpm
Signed-off-by: Alix von Schirp <github@avonschirp.bootmedia.de>
2026-02-27 01:44:30 +01:00
3144e09bc6 chore: rename submodule
Signed-off-by: Alix von Schirp <github@avonschirp.bootmedia.de>
2026-02-27 01:42:39 +01:00
4bc9acdada fix: added missing ffprobe-wasm.mjs & renamed to match repo 2026-02-26 23:57:03 +01:00
f97fb957dc fix?: undefined tags
Signed-off-by: Alix von Schirp <github@avonschirp.bootmedia.de>
2026-02-22 18:23:29 +01:00
d9013772ef chore: bump pre-release-minor, update submod ref
Signed-off-by: Alix von Schirp <github@avonschirp.bootmedia.de>
2026-02-22 01:58:57 +01:00
fad46dbae1 chore: update package.json
Signed-off-by: Alix von Schirp <github@avonschirp.bootmedia.de>
2026-02-21 01:28:05 +01:00
98151ecaef chore: update submodule ref
Signed-off-by: Alix von Schirp <github@avonschirp.bootmedia.de>
2026-02-19 21:51:48 +01:00
efa4e6f0a2 chore: update submodule ref
Signed-off-by: Alix von Schirp <github@avonschirp.bootmedia.de>
2026-02-19 21:42:09 +01:00
24a55c018f fix: make vite 7 compliant
Signed-off-by: Alix von Schirp <github@avonschirp.bootmedia.de>
2026-02-19 20:38:55 +01:00
bc9e1670b2 fix: add vite plugins for wasm
Signed-off-by: Alix von Schirp <github@avonschirp.bootmedia.de>
2026-02-19 13:44:55 +01:00
c0e13cdaa1 chore: update submodule ref
Signed-off-by: Alix von Schirp <github@avonschirp.bootmedia.de>
2026-02-19 13:44:39 +01:00
3d1951c50a chore: update submodule ref
Signed-off-by: Alix von Schirp <github@avonschirp.bootmedia.de>
2026-02-19 12:43:27 +01:00
90864d1b05 fix: rename ffprobe-wasm.js to .mjs on build
Signed-off-by: Alix von Schirp <github@avonschirp.bootmedia.de>
2026-02-19 12:36:22 +01:00
e7dbb8c0c9 chore: update submodule ref
Signed-off-by: Alix von Schirp <github@avonschirp.bootmedia.de>
2026-02-19 10:05:02 +01:00
cece48aaeb chore: change submodule ref
Signed-off-by: Alix von Schirp <github@avonschirp.bootmedia.de>
2026-02-18 22:50:08 +01:00
5214d5c530 chore: updates to submodule
Signed-off-by: Alix von Schirp <github@avonschirp.bootmedia.de>
2026-02-18 21:30:44 +01:00
ff2bef3e9c deps: update devDependencies
Signed-off-by: Alix von Schirp <github@avonschirp.bootmedia.de>
2026-02-18 20:40:23 +01:00
Tomás Fox
193d2e7b9e Make file info output more similar to ffprobe 2022-03-17 17:49:20 -03:00
21 changed files with 1159 additions and 1058 deletions

4
.gitmodules vendored
View File

@@ -1,3 +1,3 @@
[submodule "ffprobe-wasm-app"] [submodule "ffprobe-wasm-app"]
path = ffprobe-wasm-app path = libav-wasm
url = https://github.com/alfg/ffprobe-wasm url = https://git.cislabs.de/cis-oss/libav-wasm.git

1
.prettierrc.yml Normal file
View File

@@ -0,0 +1 @@
trailingComma: all

View File

@@ -4,7 +4,7 @@ Gather information from multimedia streams. Works on the browser and Node.js.
Uses the code at [alfg/ffprobe-wasm](https://github.com/alfg/ffprobe-wasm), but in a packaged format, so it can be reused in other projects. Uses the code at [alfg/ffprobe-wasm](https://github.com/alfg/ffprobe-wasm), but in a packaged format, so it can be reused in other projects.
_Note_: This project doesn't build or use FFProbe. Instead it uses FFmpeg's libavformat and libavcodec to output similar results. _For limitations and recommendations, see [Notes section](#notes)._
## Installation ## Installation
@@ -42,5 +42,7 @@ input.addEventListener("change", (event) => {
## Notes ## Notes
- This project doesn't build or use FFprobe. Instead it uses FFmpeg's libavformat and libavcodec to output similar results. This means that not everything that FFprobe supports is bundled, so there are some containers and codecs that are not supported.
- In Node.js, it works on version >= 16.
- In browser, `SharedArrayBuffer` is being used. To enable this in your server, read [Security requirements](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/SharedArrayBuffer#security_requirements). - In browser, `SharedArrayBuffer` is being used. To enable this in your server, read [Security requirements](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/SharedArrayBuffer#security_requirements).
- In browser, everything is bundled in the `browser.mjs` script. When gzipped, this file is bigger than 1 MiB, so it's recommended to use `import()` to lazy load the asset. The good side of this is that you don't have to configure your bundler to include the worker or wasm files and you won't face [same-origin](https://developer.mozilla.org/en-US/docs/Web/API/Worker/Worker) issues with the worker. - In browser, everything is bundled in the `browser.mjs` script. When gzipped, this file is bigger than 1 MiB, so it's recommended to use `import()` to lazy load the asset. The good side of this is that you don't have to configure your bundler to include the worker or wasm files and you won't face [same-origin](https://developer.mozilla.org/en-US/docs/Web/API/Worker/Worker) issues with the worker.

View File

@@ -12,14 +12,10 @@ cd ffprobe-wasm-app
docker-compose run ffprobe-wasm make docker-compose run ffprobe-wasm make
cd .. cd ..
cp -R ffprobe-wasm-app/dist dist cp -R ffprobe-wasm-app/dist dist
node scripts/replace.js
cp src/*.d.* dist cp src/*.d.* dist
# Build browser/node workers # Build browser/node workers
npm run build npm run build
# Remove unnecessary files
rm dist/browser-vite.* dist/ffprobe-wasm.d.mts dist/ffprobe-wasm.mjs dist/worker-browser.*
# Copy files for npm publish # Copy files for npm publish
cp package.json LICENSE README.md dist cp package.json LICENSE README.md dist

Submodule ffprobe-wasm-app deleted from c0f96a1755

1
libav-wasm Submodule

Submodule libav-wasm added at 62ae9d08f0

855
package-lock.json generated
View File

@@ -1,855 +0,0 @@
{
"name": "ffprobe-wasm",
"version": "0.2.0",
"lockfileVersion": 2,
"requires": true,
"packages": {
"": {
"name": "ffprobe-wasm",
"version": "0.2.0",
"license": "MIT",
"devDependencies": {
"@types/node": "^17.0.21",
"typescript": "^4.5.5",
"vite": "^2.8.6"
}
},
"node_modules/@types/node": {
"version": "17.0.21",
"resolved": "https://registry.npmjs.org/@types/node/-/node-17.0.21.tgz",
"integrity": "sha512-DBZCJbhII3r90XbQxI8Y9IjjiiOGlZ0Hr32omXIZvwwZ7p4DMMXGrKXVyPfuoBOri9XNtL0UK69jYIBIsRX3QQ==",
"dev": true
},
"node_modules/esbuild": {
"version": "0.14.25",
"resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.14.25.tgz",
"integrity": "sha512-4JHEIOMNFvK09ziiL+iVmldIhLbn49V4NAVo888tcGFKedEZY/Y8YapfStJ6zSE23tzYPKxqKwQBnQoIO0BI/Q==",
"dev": true,
"hasInstallScript": true,
"bin": {
"esbuild": "bin/esbuild"
},
"engines": {
"node": ">=12"
},
"optionalDependencies": {
"esbuild-android-64": "0.14.25",
"esbuild-android-arm64": "0.14.25",
"esbuild-darwin-64": "0.14.25",
"esbuild-darwin-arm64": "0.14.25",
"esbuild-freebsd-64": "0.14.25",
"esbuild-freebsd-arm64": "0.14.25",
"esbuild-linux-32": "0.14.25",
"esbuild-linux-64": "0.14.25",
"esbuild-linux-arm": "0.14.25",
"esbuild-linux-arm64": "0.14.25",
"esbuild-linux-mips64le": "0.14.25",
"esbuild-linux-ppc64le": "0.14.25",
"esbuild-linux-riscv64": "0.14.25",
"esbuild-linux-s390x": "0.14.25",
"esbuild-netbsd-64": "0.14.25",
"esbuild-openbsd-64": "0.14.25",
"esbuild-sunos-64": "0.14.25",
"esbuild-windows-32": "0.14.25",
"esbuild-windows-64": "0.14.25",
"esbuild-windows-arm64": "0.14.25"
}
},
"node_modules/esbuild-android-64": {
"version": "0.14.25",
"resolved": "https://registry.npmjs.org/esbuild-android-64/-/esbuild-android-64-0.14.25.tgz",
"integrity": "sha512-L5vCUk7TzFbBnoESNoXjU3x9+/+7TDIE/1mTfy/erAfvZAqC+S3sp/Qa9wkypFMcFvN9FzvESkTlpeQDolREtQ==",
"cpu": [
"x64"
],
"dev": true,
"optional": true,
"os": [
"android"
],
"engines": {
"node": ">=12"
}
},
"node_modules/esbuild-android-arm64": {
"version": "0.14.25",
"resolved": "https://registry.npmjs.org/esbuild-android-arm64/-/esbuild-android-arm64-0.14.25.tgz",
"integrity": "sha512-4jv5xPjM/qNm27T5j3ZEck0PvjgQtoMHnz4FzwF5zNP56PvY2CT0WStcAIl6jNlsuDdN63rk2HRBIsO6xFbcFw==",
"cpu": [
"arm64"
],
"dev": true,
"optional": true,
"os": [
"android"
],
"engines": {
"node": ">=12"
}
},
"node_modules/esbuild-darwin-64": {
"version": "0.14.25",
"resolved": "https://registry.npmjs.org/esbuild-darwin-64/-/esbuild-darwin-64-0.14.25.tgz",
"integrity": "sha512-TGp8tuudIxOyWd1+8aYPxQmC1ZQyvij/AfNBa35RubixD0zJ1vkKHVAzo0Zao1zcG6pNqiSyzfPto8vmg0s7oA==",
"cpu": [
"x64"
],
"dev": true,
"optional": true,
"os": [
"darwin"
],
"engines": {
"node": ">=12"
}
},
"node_modules/esbuild-darwin-arm64": {
"version": "0.14.25",
"resolved": "https://registry.npmjs.org/esbuild-darwin-arm64/-/esbuild-darwin-arm64-0.14.25.tgz",
"integrity": "sha512-oTcDgdm0MDVEmw2DWu8BV68pYuImpFgvWREPErBZmNA4MYKGuBRaCiJqq6jZmBR1x+3y1DWCjez+5uLtuAm6mw==",
"cpu": [
"arm64"
],
"dev": true,
"optional": true,
"os": [
"darwin"
],
"engines": {
"node": ">=12"
}
},
"node_modules/esbuild-freebsd-64": {
"version": "0.14.25",
"resolved": "https://registry.npmjs.org/esbuild-freebsd-64/-/esbuild-freebsd-64-0.14.25.tgz",
"integrity": "sha512-ueAqbnMZ8arnuLH8tHwTCQYeptnHOUV7vA6px6j4zjjQwDx7TdP7kACPf3TLZLdJQ3CAD1XCvQ2sPhX+8tacvQ==",
"cpu": [
"x64"
],
"dev": true,
"optional": true,
"os": [
"freebsd"
],
"engines": {
"node": ">=12"
}
},
"node_modules/esbuild-freebsd-arm64": {
"version": "0.14.25",
"resolved": "https://registry.npmjs.org/esbuild-freebsd-arm64/-/esbuild-freebsd-arm64-0.14.25.tgz",
"integrity": "sha512-+ZVWud2HKh+Ob6k/qiJWjBtUg4KmJGGmbvEXXW1SNKS7hW7HU+Zq2ZCcE1akFxOPkVB+EhOty/sSek30tkCYug==",
"cpu": [
"arm64"
],
"dev": true,
"optional": true,
"os": [
"freebsd"
],
"engines": {
"node": ">=12"
}
},
"node_modules/esbuild-linux-32": {
"version": "0.14.25",
"resolved": "https://registry.npmjs.org/esbuild-linux-32/-/esbuild-linux-32-0.14.25.tgz",
"integrity": "sha512-3OP/lwV3kCzEz45tobH9nj+uE4ubhGsfx+tn0L26WAGtUbmmcRpqy7XRG/qK7h1mClZ+eguIANcQntYMdYklfw==",
"cpu": [
"ia32"
],
"dev": true,
"optional": true,
"os": [
"linux"
],
"engines": {
"node": ">=12"
}
},
"node_modules/esbuild-linux-64": {
"version": "0.14.25",
"resolved": "https://registry.npmjs.org/esbuild-linux-64/-/esbuild-linux-64-0.14.25.tgz",
"integrity": "sha512-+aKHdHZmX9qwVlQmu5xYXh7GsBFf4TWrePgeJTalhXHOG7NNuUwoHmketGiZEoNsWyyqwH9rE5BC+iwcLY30Ug==",
"cpu": [
"x64"
],
"dev": true,
"optional": true,
"os": [
"linux"
],
"engines": {
"node": ">=12"
}
},
"node_modules/esbuild-linux-arm": {
"version": "0.14.25",
"resolved": "https://registry.npmjs.org/esbuild-linux-arm/-/esbuild-linux-arm-0.14.25.tgz",
"integrity": "sha512-aTLcE2VBoLydL943REcAcgnDi3bHtmULSXWLbjtBdtykRatJVSxKMjK9YlBXUZC4/YcNQfH7AxwVeQr9fNxPhw==",
"cpu": [
"arm"
],
"dev": true,
"optional": true,
"os": [
"linux"
],
"engines": {
"node": ">=12"
}
},
"node_modules/esbuild-linux-arm64": {
"version": "0.14.25",
"resolved": "https://registry.npmjs.org/esbuild-linux-arm64/-/esbuild-linux-arm64-0.14.25.tgz",
"integrity": "sha512-UxfenPx/wSZx55gScCImPtXekvZQLI2GW3qe5dtlmU7luiqhp5GWPzGeQEbD3yN3xg/pHc671m5bma5Ns7lBHw==",
"cpu": [
"arm64"
],
"dev": true,
"optional": true,
"os": [
"linux"
],
"engines": {
"node": ">=12"
}
},
"node_modules/esbuild-linux-mips64le": {
"version": "0.14.25",
"resolved": "https://registry.npmjs.org/esbuild-linux-mips64le/-/esbuild-linux-mips64le-0.14.25.tgz",
"integrity": "sha512-wLWYyqVfYx9Ur6eU5RT92yJVsaBGi5RdkoWqRHOqcJ38Kn60QMlcghsKeWfe9jcYut8LangYZ98xO1LxIoSXrQ==",
"cpu": [
"mips64el"
],
"dev": true,
"optional": true,
"os": [
"linux"
],
"engines": {
"node": ">=12"
}
},
"node_modules/esbuild-linux-ppc64le": {
"version": "0.14.25",
"resolved": "https://registry.npmjs.org/esbuild-linux-ppc64le/-/esbuild-linux-ppc64le-0.14.25.tgz",
"integrity": "sha512-0dR6Csl6Zas3g4p9ULckEl8Mo8IInJh33VCJ3eaV1hj9+MHGdmDOakYMN8MZP9/5nl+NU/0ygpd14cWgy8uqRw==",
"cpu": [
"ppc64"
],
"dev": true,
"optional": true,
"os": [
"linux"
],
"engines": {
"node": ">=12"
}
},
"node_modules/esbuild-linux-riscv64": {
"version": "0.14.25",
"resolved": "https://registry.npmjs.org/esbuild-linux-riscv64/-/esbuild-linux-riscv64-0.14.25.tgz",
"integrity": "sha512-J4d20HDmTrgvhR0bdkDhvvJGaikH3LzXQnNaseo8rcw9Yqby9A90gKUmWpfwqLVNRILvNnAmKLfBjCKU9ajg8w==",
"cpu": [
"riscv64"
],
"dev": true,
"optional": true,
"os": [
"linux"
],
"engines": {
"node": ">=12"
}
},
"node_modules/esbuild-linux-s390x": {
"version": "0.14.25",
"resolved": "https://registry.npmjs.org/esbuild-linux-s390x/-/esbuild-linux-s390x-0.14.25.tgz",
"integrity": "sha512-YI2d5V6nTE73ZnhEKQD7MtsPs1EtUZJ3obS21oxQxGbbRw1G+PtJKjNyur+3t6nzHP9oTg6GHQ3S3hOLLmbDIQ==",
"cpu": [
"s390x"
],
"dev": true,
"optional": true,
"os": [
"linux"
],
"engines": {
"node": ">=12"
}
},
"node_modules/esbuild-netbsd-64": {
"version": "0.14.25",
"resolved": "https://registry.npmjs.org/esbuild-netbsd-64/-/esbuild-netbsd-64-0.14.25.tgz",
"integrity": "sha512-TKIVgNWLUOkr+Exrye70XTEE1lJjdQXdM4tAXRzfHE9iBA7LXWcNtVIuSnphTqpanPzTDFarF0yqq4kpbC6miA==",
"cpu": [
"x64"
],
"dev": true,
"optional": true,
"os": [
"netbsd"
],
"engines": {
"node": ">=12"
}
},
"node_modules/esbuild-openbsd-64": {
"version": "0.14.25",
"resolved": "https://registry.npmjs.org/esbuild-openbsd-64/-/esbuild-openbsd-64-0.14.25.tgz",
"integrity": "sha512-QgFJ37A15D7NIXBTYEqz29+uw3nNBOIyog+3kFidANn6kjw0GHZ0lEYQn+cwjyzu94WobR+fes7cTl/ZYlHb1A==",
"cpu": [
"x64"
],
"dev": true,
"optional": true,
"os": [
"openbsd"
],
"engines": {
"node": ">=12"
}
},
"node_modules/esbuild-sunos-64": {
"version": "0.14.25",
"resolved": "https://registry.npmjs.org/esbuild-sunos-64/-/esbuild-sunos-64-0.14.25.tgz",
"integrity": "sha512-rmWfjUItYIVlqr5EnTH1+GCxXiBOC42WBZ3w++qh7n2cS9Xo0lO5pGSG2N+huOU2fX5L+6YUuJ78/vOYvefeFw==",
"cpu": [
"x64"
],
"dev": true,
"optional": true,
"os": [
"sunos"
],
"engines": {
"node": ">=12"
}
},
"node_modules/esbuild-windows-32": {
"version": "0.14.25",
"resolved": "https://registry.npmjs.org/esbuild-windows-32/-/esbuild-windows-32-0.14.25.tgz",
"integrity": "sha512-HGAxVUofl3iUIz9W10Y9XKtD0bNsK9fBXv1D55N/ljNvkrAYcGB8YCm0v7DjlwtyS6ws3dkdQyXadbxkbzaKOA==",
"cpu": [
"ia32"
],
"dev": true,
"optional": true,
"os": [
"win32"
],
"engines": {
"node": ">=12"
}
},
"node_modules/esbuild-windows-64": {
"version": "0.14.25",
"resolved": "https://registry.npmjs.org/esbuild-windows-64/-/esbuild-windows-64-0.14.25.tgz",
"integrity": "sha512-TirEohRkfWU9hXLgoDxzhMQD1g8I2mOqvdQF2RS9E/wbkORTAqJHyh7wqGRCQAwNzdNXdg3JAyhQ9/177AadWA==",
"cpu": [
"x64"
],
"dev": true,
"optional": true,
"os": [
"win32"
],
"engines": {
"node": ">=12"
}
},
"node_modules/esbuild-windows-arm64": {
"version": "0.14.25",
"resolved": "https://registry.npmjs.org/esbuild-windows-arm64/-/esbuild-windows-arm64-0.14.25.tgz",
"integrity": "sha512-4ype9ERiI45rSh+R8qUoBtaj6kJvUOI7oVLhKqPEpcF4Pa5PpT3hm/mXAyotJHREkHpM87PAJcA442mLnbtlNA==",
"cpu": [
"arm64"
],
"dev": true,
"optional": true,
"os": [
"win32"
],
"engines": {
"node": ">=12"
}
},
"node_modules/fsevents": {
"version": "2.3.2",
"resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz",
"integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==",
"dev": true,
"hasInstallScript": true,
"optional": true,
"os": [
"darwin"
],
"engines": {
"node": "^8.16.0 || ^10.6.0 || >=11.0.0"
}
},
"node_modules/function-bind": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz",
"integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==",
"dev": true
},
"node_modules/has": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz",
"integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==",
"dev": true,
"dependencies": {
"function-bind": "^1.1.1"
},
"engines": {
"node": ">= 0.4.0"
}
},
"node_modules/is-core-module": {
"version": "2.8.1",
"resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.8.1.tgz",
"integrity": "sha512-SdNCUs284hr40hFTFP6l0IfZ/RSrMXF3qgoRHd3/79unUTvrFO/JoXwkGm+5J/Oe3E/b5GsnG330uUNgRpu1PA==",
"dev": true,
"dependencies": {
"has": "^1.0.3"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/nanoid": {
"version": "3.3.1",
"resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.1.tgz",
"integrity": "sha512-n6Vs/3KGyxPQd6uO0eH4Bv0ojGSUvuLlIHtC3Y0kEO23YRge8H9x1GCzLn28YX0H66pMkxuaeESFq4tKISKwdw==",
"dev": true,
"bin": {
"nanoid": "bin/nanoid.cjs"
},
"engines": {
"node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1"
}
},
"node_modules/path-parse": {
"version": "1.0.7",
"resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz",
"integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==",
"dev": true
},
"node_modules/picocolors": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz",
"integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==",
"dev": true
},
"node_modules/postcss": {
"version": "8.4.8",
"resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.8.tgz",
"integrity": "sha512-2tXEqGxrjvAO6U+CJzDL2Fk2kPHTv1jQsYkSoMeOis2SsYaXRO2COxTdQp99cYvif9JTXaAk9lYGc3VhJt7JPQ==",
"dev": true,
"dependencies": {
"nanoid": "^3.3.1",
"picocolors": "^1.0.0",
"source-map-js": "^1.0.2"
},
"engines": {
"node": "^10 || ^12 || >=14"
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/postcss/"
}
},
"node_modules/resolve": {
"version": "1.22.0",
"resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.0.tgz",
"integrity": "sha512-Hhtrw0nLeSrFQ7phPp4OOcVjLPIeMnRlr5mcnVuMe7M/7eBn98A3hmFRLoFo3DLZkivSYwhRUJTyPyWAk56WLw==",
"dev": true,
"dependencies": {
"is-core-module": "^2.8.1",
"path-parse": "^1.0.7",
"supports-preserve-symlinks-flag": "^1.0.0"
},
"bin": {
"resolve": "bin/resolve"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/rollup": {
"version": "2.70.0",
"resolved": "https://registry.npmjs.org/rollup/-/rollup-2.70.0.tgz",
"integrity": "sha512-iEzYw+syFxQ0X9RefVwhr8BA2TNJsTaX8L8dhyeyMECDbmiba+8UQzcu+xZdji0+JQ+s7kouQnw+9Oz5M19XKA==",
"dev": true,
"bin": {
"rollup": "dist/bin/rollup"
},
"engines": {
"node": ">=10.0.0"
},
"optionalDependencies": {
"fsevents": "~2.3.2"
}
},
"node_modules/source-map-js": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.0.2.tgz",
"integrity": "sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==",
"dev": true,
"engines": {
"node": ">=0.10.0"
}
},
"node_modules/supports-preserve-symlinks-flag": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz",
"integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==",
"dev": true,
"engines": {
"node": ">= 0.4"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/typescript": {
"version": "4.5.5",
"resolved": "https://registry.npmjs.org/typescript/-/typescript-4.5.5.tgz",
"integrity": "sha512-TCTIul70LyWe6IJWT8QSYeA54WQe8EjQFU4wY52Fasj5UKx88LNYKCgBEHcOMOrFF1rKGbD8v/xcNWVUq9SymA==",
"dev": true,
"bin": {
"tsc": "bin/tsc",
"tsserver": "bin/tsserver"
},
"engines": {
"node": ">=4.2.0"
}
},
"node_modules/vite": {
"version": "2.8.6",
"resolved": "https://registry.npmjs.org/vite/-/vite-2.8.6.tgz",
"integrity": "sha512-e4H0QpludOVKkmOsRyqQ7LTcMUDF3mcgyNU4lmi0B5JUbe0ZxeBBl8VoZ8Y6Rfn9eFKYtdXNPcYK97ZwH+K2ug==",
"dev": true,
"dependencies": {
"esbuild": "^0.14.14",
"postcss": "^8.4.6",
"resolve": "^1.22.0",
"rollup": "^2.59.0"
},
"bin": {
"vite": "bin/vite.js"
},
"engines": {
"node": ">=12.2.0"
},
"optionalDependencies": {
"fsevents": "~2.3.2"
},
"peerDependencies": {
"less": "*",
"sass": "*",
"stylus": "*"
},
"peerDependenciesMeta": {
"less": {
"optional": true
},
"sass": {
"optional": true
},
"stylus": {
"optional": true
}
}
}
},
"dependencies": {
"@types/node": {
"version": "17.0.21",
"resolved": "https://registry.npmjs.org/@types/node/-/node-17.0.21.tgz",
"integrity": "sha512-DBZCJbhII3r90XbQxI8Y9IjjiiOGlZ0Hr32omXIZvwwZ7p4DMMXGrKXVyPfuoBOri9XNtL0UK69jYIBIsRX3QQ==",
"dev": true
},
"esbuild": {
"version": "0.14.25",
"resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.14.25.tgz",
"integrity": "sha512-4JHEIOMNFvK09ziiL+iVmldIhLbn49V4NAVo888tcGFKedEZY/Y8YapfStJ6zSE23tzYPKxqKwQBnQoIO0BI/Q==",
"dev": true,
"requires": {
"esbuild-android-64": "0.14.25",
"esbuild-android-arm64": "0.14.25",
"esbuild-darwin-64": "0.14.25",
"esbuild-darwin-arm64": "0.14.25",
"esbuild-freebsd-64": "0.14.25",
"esbuild-freebsd-arm64": "0.14.25",
"esbuild-linux-32": "0.14.25",
"esbuild-linux-64": "0.14.25",
"esbuild-linux-arm": "0.14.25",
"esbuild-linux-arm64": "0.14.25",
"esbuild-linux-mips64le": "0.14.25",
"esbuild-linux-ppc64le": "0.14.25",
"esbuild-linux-riscv64": "0.14.25",
"esbuild-linux-s390x": "0.14.25",
"esbuild-netbsd-64": "0.14.25",
"esbuild-openbsd-64": "0.14.25",
"esbuild-sunos-64": "0.14.25",
"esbuild-windows-32": "0.14.25",
"esbuild-windows-64": "0.14.25",
"esbuild-windows-arm64": "0.14.25"
}
},
"esbuild-android-64": {
"version": "0.14.25",
"resolved": "https://registry.npmjs.org/esbuild-android-64/-/esbuild-android-64-0.14.25.tgz",
"integrity": "sha512-L5vCUk7TzFbBnoESNoXjU3x9+/+7TDIE/1mTfy/erAfvZAqC+S3sp/Qa9wkypFMcFvN9FzvESkTlpeQDolREtQ==",
"dev": true,
"optional": true
},
"esbuild-android-arm64": {
"version": "0.14.25",
"resolved": "https://registry.npmjs.org/esbuild-android-arm64/-/esbuild-android-arm64-0.14.25.tgz",
"integrity": "sha512-4jv5xPjM/qNm27T5j3ZEck0PvjgQtoMHnz4FzwF5zNP56PvY2CT0WStcAIl6jNlsuDdN63rk2HRBIsO6xFbcFw==",
"dev": true,
"optional": true
},
"esbuild-darwin-64": {
"version": "0.14.25",
"resolved": "https://registry.npmjs.org/esbuild-darwin-64/-/esbuild-darwin-64-0.14.25.tgz",
"integrity": "sha512-TGp8tuudIxOyWd1+8aYPxQmC1ZQyvij/AfNBa35RubixD0zJ1vkKHVAzo0Zao1zcG6pNqiSyzfPto8vmg0s7oA==",
"dev": true,
"optional": true
},
"esbuild-darwin-arm64": {
"version": "0.14.25",
"resolved": "https://registry.npmjs.org/esbuild-darwin-arm64/-/esbuild-darwin-arm64-0.14.25.tgz",
"integrity": "sha512-oTcDgdm0MDVEmw2DWu8BV68pYuImpFgvWREPErBZmNA4MYKGuBRaCiJqq6jZmBR1x+3y1DWCjez+5uLtuAm6mw==",
"dev": true,
"optional": true
},
"esbuild-freebsd-64": {
"version": "0.14.25",
"resolved": "https://registry.npmjs.org/esbuild-freebsd-64/-/esbuild-freebsd-64-0.14.25.tgz",
"integrity": "sha512-ueAqbnMZ8arnuLH8tHwTCQYeptnHOUV7vA6px6j4zjjQwDx7TdP7kACPf3TLZLdJQ3CAD1XCvQ2sPhX+8tacvQ==",
"dev": true,
"optional": true
},
"esbuild-freebsd-arm64": {
"version": "0.14.25",
"resolved": "https://registry.npmjs.org/esbuild-freebsd-arm64/-/esbuild-freebsd-arm64-0.14.25.tgz",
"integrity": "sha512-+ZVWud2HKh+Ob6k/qiJWjBtUg4KmJGGmbvEXXW1SNKS7hW7HU+Zq2ZCcE1akFxOPkVB+EhOty/sSek30tkCYug==",
"dev": true,
"optional": true
},
"esbuild-linux-32": {
"version": "0.14.25",
"resolved": "https://registry.npmjs.org/esbuild-linux-32/-/esbuild-linux-32-0.14.25.tgz",
"integrity": "sha512-3OP/lwV3kCzEz45tobH9nj+uE4ubhGsfx+tn0L26WAGtUbmmcRpqy7XRG/qK7h1mClZ+eguIANcQntYMdYklfw==",
"dev": true,
"optional": true
},
"esbuild-linux-64": {
"version": "0.14.25",
"resolved": "https://registry.npmjs.org/esbuild-linux-64/-/esbuild-linux-64-0.14.25.tgz",
"integrity": "sha512-+aKHdHZmX9qwVlQmu5xYXh7GsBFf4TWrePgeJTalhXHOG7NNuUwoHmketGiZEoNsWyyqwH9rE5BC+iwcLY30Ug==",
"dev": true,
"optional": true
},
"esbuild-linux-arm": {
"version": "0.14.25",
"resolved": "https://registry.npmjs.org/esbuild-linux-arm/-/esbuild-linux-arm-0.14.25.tgz",
"integrity": "sha512-aTLcE2VBoLydL943REcAcgnDi3bHtmULSXWLbjtBdtykRatJVSxKMjK9YlBXUZC4/YcNQfH7AxwVeQr9fNxPhw==",
"dev": true,
"optional": true
},
"esbuild-linux-arm64": {
"version": "0.14.25",
"resolved": "https://registry.npmjs.org/esbuild-linux-arm64/-/esbuild-linux-arm64-0.14.25.tgz",
"integrity": "sha512-UxfenPx/wSZx55gScCImPtXekvZQLI2GW3qe5dtlmU7luiqhp5GWPzGeQEbD3yN3xg/pHc671m5bma5Ns7lBHw==",
"dev": true,
"optional": true
},
"esbuild-linux-mips64le": {
"version": "0.14.25",
"resolved": "https://registry.npmjs.org/esbuild-linux-mips64le/-/esbuild-linux-mips64le-0.14.25.tgz",
"integrity": "sha512-wLWYyqVfYx9Ur6eU5RT92yJVsaBGi5RdkoWqRHOqcJ38Kn60QMlcghsKeWfe9jcYut8LangYZ98xO1LxIoSXrQ==",
"dev": true,
"optional": true
},
"esbuild-linux-ppc64le": {
"version": "0.14.25",
"resolved": "https://registry.npmjs.org/esbuild-linux-ppc64le/-/esbuild-linux-ppc64le-0.14.25.tgz",
"integrity": "sha512-0dR6Csl6Zas3g4p9ULckEl8Mo8IInJh33VCJ3eaV1hj9+MHGdmDOakYMN8MZP9/5nl+NU/0ygpd14cWgy8uqRw==",
"dev": true,
"optional": true
},
"esbuild-linux-riscv64": {
"version": "0.14.25",
"resolved": "https://registry.npmjs.org/esbuild-linux-riscv64/-/esbuild-linux-riscv64-0.14.25.tgz",
"integrity": "sha512-J4d20HDmTrgvhR0bdkDhvvJGaikH3LzXQnNaseo8rcw9Yqby9A90gKUmWpfwqLVNRILvNnAmKLfBjCKU9ajg8w==",
"dev": true,
"optional": true
},
"esbuild-linux-s390x": {
"version": "0.14.25",
"resolved": "https://registry.npmjs.org/esbuild-linux-s390x/-/esbuild-linux-s390x-0.14.25.tgz",
"integrity": "sha512-YI2d5V6nTE73ZnhEKQD7MtsPs1EtUZJ3obS21oxQxGbbRw1G+PtJKjNyur+3t6nzHP9oTg6GHQ3S3hOLLmbDIQ==",
"dev": true,
"optional": true
},
"esbuild-netbsd-64": {
"version": "0.14.25",
"resolved": "https://registry.npmjs.org/esbuild-netbsd-64/-/esbuild-netbsd-64-0.14.25.tgz",
"integrity": "sha512-TKIVgNWLUOkr+Exrye70XTEE1lJjdQXdM4tAXRzfHE9iBA7LXWcNtVIuSnphTqpanPzTDFarF0yqq4kpbC6miA==",
"dev": true,
"optional": true
},
"esbuild-openbsd-64": {
"version": "0.14.25",
"resolved": "https://registry.npmjs.org/esbuild-openbsd-64/-/esbuild-openbsd-64-0.14.25.tgz",
"integrity": "sha512-QgFJ37A15D7NIXBTYEqz29+uw3nNBOIyog+3kFidANn6kjw0GHZ0lEYQn+cwjyzu94WobR+fes7cTl/ZYlHb1A==",
"dev": true,
"optional": true
},
"esbuild-sunos-64": {
"version": "0.14.25",
"resolved": "https://registry.npmjs.org/esbuild-sunos-64/-/esbuild-sunos-64-0.14.25.tgz",
"integrity": "sha512-rmWfjUItYIVlqr5EnTH1+GCxXiBOC42WBZ3w++qh7n2cS9Xo0lO5pGSG2N+huOU2fX5L+6YUuJ78/vOYvefeFw==",
"dev": true,
"optional": true
},
"esbuild-windows-32": {
"version": "0.14.25",
"resolved": "https://registry.npmjs.org/esbuild-windows-32/-/esbuild-windows-32-0.14.25.tgz",
"integrity": "sha512-HGAxVUofl3iUIz9W10Y9XKtD0bNsK9fBXv1D55N/ljNvkrAYcGB8YCm0v7DjlwtyS6ws3dkdQyXadbxkbzaKOA==",
"dev": true,
"optional": true
},
"esbuild-windows-64": {
"version": "0.14.25",
"resolved": "https://registry.npmjs.org/esbuild-windows-64/-/esbuild-windows-64-0.14.25.tgz",
"integrity": "sha512-TirEohRkfWU9hXLgoDxzhMQD1g8I2mOqvdQF2RS9E/wbkORTAqJHyh7wqGRCQAwNzdNXdg3JAyhQ9/177AadWA==",
"dev": true,
"optional": true
},
"esbuild-windows-arm64": {
"version": "0.14.25",
"resolved": "https://registry.npmjs.org/esbuild-windows-arm64/-/esbuild-windows-arm64-0.14.25.tgz",
"integrity": "sha512-4ype9ERiI45rSh+R8qUoBtaj6kJvUOI7oVLhKqPEpcF4Pa5PpT3hm/mXAyotJHREkHpM87PAJcA442mLnbtlNA==",
"dev": true,
"optional": true
},
"fsevents": {
"version": "2.3.2",
"resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz",
"integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==",
"dev": true,
"optional": true
},
"function-bind": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz",
"integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==",
"dev": true
},
"has": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz",
"integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==",
"dev": true,
"requires": {
"function-bind": "^1.1.1"
}
},
"is-core-module": {
"version": "2.8.1",
"resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.8.1.tgz",
"integrity": "sha512-SdNCUs284hr40hFTFP6l0IfZ/RSrMXF3qgoRHd3/79unUTvrFO/JoXwkGm+5J/Oe3E/b5GsnG330uUNgRpu1PA==",
"dev": true,
"requires": {
"has": "^1.0.3"
}
},
"nanoid": {
"version": "3.3.1",
"resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.1.tgz",
"integrity": "sha512-n6Vs/3KGyxPQd6uO0eH4Bv0ojGSUvuLlIHtC3Y0kEO23YRge8H9x1GCzLn28YX0H66pMkxuaeESFq4tKISKwdw==",
"dev": true
},
"path-parse": {
"version": "1.0.7",
"resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz",
"integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==",
"dev": true
},
"picocolors": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz",
"integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==",
"dev": true
},
"postcss": {
"version": "8.4.8",
"resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.8.tgz",
"integrity": "sha512-2tXEqGxrjvAO6U+CJzDL2Fk2kPHTv1jQsYkSoMeOis2SsYaXRO2COxTdQp99cYvif9JTXaAk9lYGc3VhJt7JPQ==",
"dev": true,
"requires": {
"nanoid": "^3.3.1",
"picocolors": "^1.0.0",
"source-map-js": "^1.0.2"
}
},
"resolve": {
"version": "1.22.0",
"resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.0.tgz",
"integrity": "sha512-Hhtrw0nLeSrFQ7phPp4OOcVjLPIeMnRlr5mcnVuMe7M/7eBn98A3hmFRLoFo3DLZkivSYwhRUJTyPyWAk56WLw==",
"dev": true,
"requires": {
"is-core-module": "^2.8.1",
"path-parse": "^1.0.7",
"supports-preserve-symlinks-flag": "^1.0.0"
}
},
"rollup": {
"version": "2.70.0",
"resolved": "https://registry.npmjs.org/rollup/-/rollup-2.70.0.tgz",
"integrity": "sha512-iEzYw+syFxQ0X9RefVwhr8BA2TNJsTaX8L8dhyeyMECDbmiba+8UQzcu+xZdji0+JQ+s7kouQnw+9Oz5M19XKA==",
"dev": true,
"requires": {
"fsevents": "~2.3.2"
}
},
"source-map-js": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.0.2.tgz",
"integrity": "sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==",
"dev": true
},
"supports-preserve-symlinks-flag": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz",
"integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==",
"dev": true
},
"typescript": {
"version": "4.5.5",
"resolved": "https://registry.npmjs.org/typescript/-/typescript-4.5.5.tgz",
"integrity": "sha512-TCTIul70LyWe6IJWT8QSYeA54WQe8EjQFU4wY52Fasj5UKx88LNYKCgBEHcOMOrFF1rKGbD8v/xcNWVUq9SymA==",
"dev": true
},
"vite": {
"version": "2.8.6",
"resolved": "https://registry.npmjs.org/vite/-/vite-2.8.6.tgz",
"integrity": "sha512-e4H0QpludOVKkmOsRyqQ7LTcMUDF3mcgyNU4lmi0B5JUbe0ZxeBBl8VoZ8Y6Rfn9eFKYtdXNPcYK97ZwH+K2ug==",
"dev": true,
"requires": {
"esbuild": "^0.14.14",
"fsevents": "~2.3.2",
"postcss": "^8.4.6",
"resolve": "^1.22.0",
"rollup": "^2.59.0"
}
}
}
}

View File

@@ -1,13 +1,10 @@
{ {
"name": "ffprobe-wasm", "name": "@cis-oss/avprobe-wasm",
"version": "0.2.0", "version": "0.3.3-rc1",
"description": "ffprobe-like for browser and node, powered by WebAssembly", "description": "ffprobe-like for browser and node, powered by WebAssembly",
"repository": { "repository": {
"type": "git", "type": "git",
"url": "https://github.com/tfoxy/ffprobe-wasm" "url": "https://git.cislabs.de/cis-oss/avprobe-wasm"
},
"bugs": {
"url": "https://github.com/tfoxy/ffprobe-wasm/issues"
}, },
"keywords": [ "keywords": [
"ffprobe", "ffprobe",
@@ -15,15 +12,20 @@
"ffmpeg", "ffmpeg",
"video" "video"
], ],
"author": "Tomás Fox <tomas.c.fox@gmail.com>", "author": {
"name": "Alix von Schirp",
"url": "https://b00tload.space",
"email": "hi@b00tload.space"
},
"type": "module",
"license": "MIT", "license": "MIT",
"exports": { "exports": {
"node": "./node.mjs", "node": "./node.mjs",
"types": "./ffprobe-worker.d.ts", "types": "./ffprobe-worker.d.mts",
"default": "./browser.mjs" "default": "./browser.mjs"
}, },
"main": "./node.mjs", "main": "./node.mjs",
"types": "./ffprobe-worker.d.ts", "types": "./ffprobe-worker.d.mts",
"browser": "./browser.mjs", "browser": "./browser.mjs",
"scripts": { "scripts": {
"build": "npm run tsc && npm run vite", "build": "npm run tsc && npm run vite",
@@ -31,8 +33,10 @@
"vite": "vite build" "vite": "vite build"
}, },
"devDependencies": { "devDependencies": {
"@types/node": "^17.0.21", "@types/node": "^25.2.3",
"typescript": "^4.5.5", "typescript": "^5.9.3",
"vite": "^2.8.6" "vite": "^7.3.1",
"vite-plugin-top-level-await": "^1.6.0",
"vite-plugin-wasm": "^3.5.0"
} }
} }

849
pnpm-lock.yaml generated Normal file
View File

@@ -0,0 +1,849 @@
lockfileVersion: '9.0'
settings:
autoInstallPeers: true
excludeLinksFromLockfile: false
importers:
.:
devDependencies:
'@types/node':
specifier: ^25.2.3
version: 25.3.0
typescript:
specifier: ^5.9.3
version: 5.9.3
vite:
specifier: ^7.3.1
version: 7.3.1(@types/node@25.3.0)
vite-plugin-top-level-await:
specifier: ^1.6.0
version: 1.6.0(rollup@4.59.0)(vite@7.3.1(@types/node@25.3.0))
vite-plugin-wasm:
specifier: ^3.5.0
version: 3.5.0(vite@7.3.1(@types/node@25.3.0))
packages:
'@esbuild/aix-ppc64@0.27.3':
resolution: {integrity: sha512-9fJMTNFTWZMh5qwrBItuziu834eOCUcEqymSH7pY+zoMVEZg3gcPuBNxH1EvfVYe9h0x/Ptw8KBzv7qxb7l8dg==}
engines: {node: '>=18'}
cpu: [ppc64]
os: [aix]
'@esbuild/android-arm64@0.27.3':
resolution: {integrity: sha512-YdghPYUmj/FX2SYKJ0OZxf+iaKgMsKHVPF1MAq/P8WirnSpCStzKJFjOjzsW0QQ7oIAiccHdcqjbHmJxRb/dmg==}
engines: {node: '>=18'}
cpu: [arm64]
os: [android]
'@esbuild/android-arm@0.27.3':
resolution: {integrity: sha512-i5D1hPY7GIQmXlXhs2w8AWHhenb00+GxjxRncS2ZM7YNVGNfaMxgzSGuO8o8SJzRc/oZwU2bcScvVERk03QhzA==}
engines: {node: '>=18'}
cpu: [arm]
os: [android]
'@esbuild/android-x64@0.27.3':
resolution: {integrity: sha512-IN/0BNTkHtk8lkOM8JWAYFg4ORxBkZQf9zXiEOfERX/CzxW3Vg1ewAhU7QSWQpVIzTW+b8Xy+lGzdYXV6UZObQ==}
engines: {node: '>=18'}
cpu: [x64]
os: [android]
'@esbuild/darwin-arm64@0.27.3':
resolution: {integrity: sha512-Re491k7ByTVRy0t3EKWajdLIr0gz2kKKfzafkth4Q8A5n1xTHrkqZgLLjFEHVD+AXdUGgQMq+Godfq45mGpCKg==}
engines: {node: '>=18'}
cpu: [arm64]
os: [darwin]
'@esbuild/darwin-x64@0.27.3':
resolution: {integrity: sha512-vHk/hA7/1AckjGzRqi6wbo+jaShzRowYip6rt6q7VYEDX4LEy1pZfDpdxCBnGtl+A5zq8iXDcyuxwtv3hNtHFg==}
engines: {node: '>=18'}
cpu: [x64]
os: [darwin]
'@esbuild/freebsd-arm64@0.27.3':
resolution: {integrity: sha512-ipTYM2fjt3kQAYOvo6vcxJx3nBYAzPjgTCk7QEgZG8AUO3ydUhvelmhrbOheMnGOlaSFUoHXB6un+A7q4ygY9w==}
engines: {node: '>=18'}
cpu: [arm64]
os: [freebsd]
'@esbuild/freebsd-x64@0.27.3':
resolution: {integrity: sha512-dDk0X87T7mI6U3K9VjWtHOXqwAMJBNN2r7bejDsc+j03SEjtD9HrOl8gVFByeM0aJksoUuUVU9TBaZa2rgj0oA==}
engines: {node: '>=18'}
cpu: [x64]
os: [freebsd]
'@esbuild/linux-arm64@0.27.3':
resolution: {integrity: sha512-sZOuFz/xWnZ4KH3YfFrKCf1WyPZHakVzTiqji3WDc0BCl2kBwiJLCXpzLzUBLgmp4veFZdvN5ChW4Eq/8Fc2Fg==}
engines: {node: '>=18'}
cpu: [arm64]
os: [linux]
'@esbuild/linux-arm@0.27.3':
resolution: {integrity: sha512-s6nPv2QkSupJwLYyfS+gwdirm0ukyTFNl3KTgZEAiJDd+iHZcbTPPcWCcRYH+WlNbwChgH2QkE9NSlNrMT8Gfw==}
engines: {node: '>=18'}
cpu: [arm]
os: [linux]
'@esbuild/linux-ia32@0.27.3':
resolution: {integrity: sha512-yGlQYjdxtLdh0a3jHjuwOrxQjOZYD/C9PfdbgJJF3TIZWnm/tMd/RcNiLngiu4iwcBAOezdnSLAwQDPqTmtTYg==}
engines: {node: '>=18'}
cpu: [ia32]
os: [linux]
'@esbuild/linux-loong64@0.27.3':
resolution: {integrity: sha512-WO60Sn8ly3gtzhyjATDgieJNet/KqsDlX5nRC5Y3oTFcS1l0KWba+SEa9Ja1GfDqSF1z6hif/SkpQJbL63cgOA==}
engines: {node: '>=18'}
cpu: [loong64]
os: [linux]
'@esbuild/linux-mips64el@0.27.3':
resolution: {integrity: sha512-APsymYA6sGcZ4pD6k+UxbDjOFSvPWyZhjaiPyl/f79xKxwTnrn5QUnXR5prvetuaSMsb4jgeHewIDCIWljrSxw==}
engines: {node: '>=18'}
cpu: [mips64el]
os: [linux]
'@esbuild/linux-ppc64@0.27.3':
resolution: {integrity: sha512-eizBnTeBefojtDb9nSh4vvVQ3V9Qf9Df01PfawPcRzJH4gFSgrObw+LveUyDoKU3kxi5+9RJTCWlj4FjYXVPEA==}
engines: {node: '>=18'}
cpu: [ppc64]
os: [linux]
'@esbuild/linux-riscv64@0.27.3':
resolution: {integrity: sha512-3Emwh0r5wmfm3ssTWRQSyVhbOHvqegUDRd0WhmXKX2mkHJe1SFCMJhagUleMq+Uci34wLSipf8Lagt4LlpRFWQ==}
engines: {node: '>=18'}
cpu: [riscv64]
os: [linux]
'@esbuild/linux-s390x@0.27.3':
resolution: {integrity: sha512-pBHUx9LzXWBc7MFIEEL0yD/ZVtNgLytvx60gES28GcWMqil8ElCYR4kvbV2BDqsHOvVDRrOxGySBM9Fcv744hw==}
engines: {node: '>=18'}
cpu: [s390x]
os: [linux]
'@esbuild/linux-x64@0.27.3':
resolution: {integrity: sha512-Czi8yzXUWIQYAtL/2y6vogER8pvcsOsk5cpwL4Gk5nJqH5UZiVByIY8Eorm5R13gq+DQKYg0+JyQoytLQas4dA==}
engines: {node: '>=18'}
cpu: [x64]
os: [linux]
'@esbuild/netbsd-arm64@0.27.3':
resolution: {integrity: sha512-sDpk0RgmTCR/5HguIZa9n9u+HVKf40fbEUt+iTzSnCaGvY9kFP0YKBWZtJaraonFnqef5SlJ8/TiPAxzyS+UoA==}
engines: {node: '>=18'}
cpu: [arm64]
os: [netbsd]
'@esbuild/netbsd-x64@0.27.3':
resolution: {integrity: sha512-P14lFKJl/DdaE00LItAukUdZO5iqNH7+PjoBm+fLQjtxfcfFE20Xf5CrLsmZdq5LFFZzb5JMZ9grUwvtVYzjiA==}
engines: {node: '>=18'}
cpu: [x64]
os: [netbsd]
'@esbuild/openbsd-arm64@0.27.3':
resolution: {integrity: sha512-AIcMP77AvirGbRl/UZFTq5hjXK+2wC7qFRGoHSDrZ5v5b8DK/GYpXW3CPRL53NkvDqb9D+alBiC/dV0Fb7eJcw==}
engines: {node: '>=18'}
cpu: [arm64]
os: [openbsd]
'@esbuild/openbsd-x64@0.27.3':
resolution: {integrity: sha512-DnW2sRrBzA+YnE70LKqnM3P+z8vehfJWHXECbwBmH/CU51z6FiqTQTHFenPlHmo3a8UgpLyH3PT+87OViOh1AQ==}
engines: {node: '>=18'}
cpu: [x64]
os: [openbsd]
'@esbuild/openharmony-arm64@0.27.3':
resolution: {integrity: sha512-NinAEgr/etERPTsZJ7aEZQvvg/A6IsZG/LgZy+81wON2huV7SrK3e63dU0XhyZP4RKGyTm7aOgmQk0bGp0fy2g==}
engines: {node: '>=18'}
cpu: [arm64]
os: [openharmony]
'@esbuild/sunos-x64@0.27.3':
resolution: {integrity: sha512-PanZ+nEz+eWoBJ8/f8HKxTTD172SKwdXebZ0ndd953gt1HRBbhMsaNqjTyYLGLPdoWHy4zLU7bDVJztF5f3BHA==}
engines: {node: '>=18'}
cpu: [x64]
os: [sunos]
'@esbuild/win32-arm64@0.27.3':
resolution: {integrity: sha512-B2t59lWWYrbRDw/tjiWOuzSsFh1Y/E95ofKz7rIVYSQkUYBjfSgf6oeYPNWHToFRr2zx52JKApIcAS/D5TUBnA==}
engines: {node: '>=18'}
cpu: [arm64]
os: [win32]
'@esbuild/win32-ia32@0.27.3':
resolution: {integrity: sha512-QLKSFeXNS8+tHW7tZpMtjlNb7HKau0QDpwm49u0vUp9y1WOF+PEzkU84y9GqYaAVW8aH8f3GcBck26jh54cX4Q==}
engines: {node: '>=18'}
cpu: [ia32]
os: [win32]
'@esbuild/win32-x64@0.27.3':
resolution: {integrity: sha512-4uJGhsxuptu3OcpVAzli+/gWusVGwZZHTlS63hh++ehExkVT8SgiEf7/uC/PclrPPkLhZqGgCTjd0VWLo6xMqA==}
engines: {node: '>=18'}
cpu: [x64]
os: [win32]
'@rollup/plugin-virtual@3.0.2':
resolution: {integrity: sha512-10monEYsBp3scM4/ND4LNH5Rxvh3e/cVeL3jWTgZ2SrQ+BmUoQcopVQvnaMcOnykb1VkxUFuDAN+0FnpTFRy2A==}
engines: {node: '>=14.0.0'}
peerDependencies:
rollup: ^1.20.0||^2.0.0||^3.0.0||^4.0.0
peerDependenciesMeta:
rollup:
optional: true
'@rollup/rollup-android-arm-eabi@4.59.0':
resolution: {integrity: sha512-upnNBkA6ZH2VKGcBj9Fyl9IGNPULcjXRlg0LLeaioQWueH30p6IXtJEbKAgvyv+mJaMxSm1l6xwDXYjpEMiLMg==}
cpu: [arm]
os: [android]
'@rollup/rollup-android-arm64@4.59.0':
resolution: {integrity: sha512-hZ+Zxj3SySm4A/DylsDKZAeVg0mvi++0PYVceVyX7hemkw7OreKdCvW2oQ3T1FMZvCaQXqOTHb8qmBShoqk69Q==}
cpu: [arm64]
os: [android]
'@rollup/rollup-darwin-arm64@4.59.0':
resolution: {integrity: sha512-W2Psnbh1J8ZJw0xKAd8zdNgF9HRLkdWwwdWqubSVk0pUuQkoHnv7rx4GiF9rT4t5DIZGAsConRE3AxCdJ4m8rg==}
cpu: [arm64]
os: [darwin]
'@rollup/rollup-darwin-x64@4.59.0':
resolution: {integrity: sha512-ZW2KkwlS4lwTv7ZVsYDiARfFCnSGhzYPdiOU4IM2fDbL+QGlyAbjgSFuqNRbSthybLbIJ915UtZBtmuLrQAT/w==}
cpu: [x64]
os: [darwin]
'@rollup/rollup-freebsd-arm64@4.59.0':
resolution: {integrity: sha512-EsKaJ5ytAu9jI3lonzn3BgG8iRBjV4LxZexygcQbpiU0wU0ATxhNVEpXKfUa0pS05gTcSDMKpn3Sx+QB9RlTTA==}
cpu: [arm64]
os: [freebsd]
'@rollup/rollup-freebsd-x64@4.59.0':
resolution: {integrity: sha512-d3DuZi2KzTMjImrxoHIAODUZYoUUMsuUiY4SRRcJy6NJoZ6iIqWnJu9IScV9jXysyGMVuW+KNzZvBLOcpdl3Vg==}
cpu: [x64]
os: [freebsd]
'@rollup/rollup-linux-arm-gnueabihf@4.59.0':
resolution: {integrity: sha512-t4ONHboXi/3E0rT6OZl1pKbl2Vgxf9vJfWgmUoCEVQVxhW6Cw/c8I6hbbu7DAvgp82RKiH7TpLwxnJeKv2pbsw==}
cpu: [arm]
os: [linux]
'@rollup/rollup-linux-arm-musleabihf@4.59.0':
resolution: {integrity: sha512-CikFT7aYPA2ufMD086cVORBYGHffBo4K8MQ4uPS/ZnY54GKj36i196u8U+aDVT2LX4eSMbyHtyOh7D7Zvk2VvA==}
cpu: [arm]
os: [linux]
'@rollup/rollup-linux-arm64-gnu@4.59.0':
resolution: {integrity: sha512-jYgUGk5aLd1nUb1CtQ8E+t5JhLc9x5WdBKew9ZgAXg7DBk0ZHErLHdXM24rfX+bKrFe+Xp5YuJo54I5HFjGDAA==}
cpu: [arm64]
os: [linux]
'@rollup/rollup-linux-arm64-musl@4.59.0':
resolution: {integrity: sha512-peZRVEdnFWZ5Bh2KeumKG9ty7aCXzzEsHShOZEFiCQlDEepP1dpUl/SrUNXNg13UmZl+gzVDPsiCwnV1uI0RUA==}
cpu: [arm64]
os: [linux]
'@rollup/rollup-linux-loong64-gnu@4.59.0':
resolution: {integrity: sha512-gbUSW/97f7+r4gHy3Jlup8zDG190AuodsWnNiXErp9mT90iCy9NKKU0Xwx5k8VlRAIV2uU9CsMnEFg/xXaOfXg==}
cpu: [loong64]
os: [linux]
'@rollup/rollup-linux-loong64-musl@4.59.0':
resolution: {integrity: sha512-yTRONe79E+o0FWFijasoTjtzG9EBedFXJMl888NBEDCDV9I2wGbFFfJQQe63OijbFCUZqxpHz1GzpbtSFikJ4Q==}
cpu: [loong64]
os: [linux]
'@rollup/rollup-linux-ppc64-gnu@4.59.0':
resolution: {integrity: sha512-sw1o3tfyk12k3OEpRddF68a1unZ5VCN7zoTNtSn2KndUE+ea3m3ROOKRCZxEpmT9nsGnogpFP9x6mnLTCaoLkA==}
cpu: [ppc64]
os: [linux]
'@rollup/rollup-linux-ppc64-musl@4.59.0':
resolution: {integrity: sha512-+2kLtQ4xT3AiIxkzFVFXfsmlZiG5FXYW7ZyIIvGA7Bdeuh9Z0aN4hVyXS/G1E9bTP/vqszNIN/pUKCk/BTHsKA==}
cpu: [ppc64]
os: [linux]
'@rollup/rollup-linux-riscv64-gnu@4.59.0':
resolution: {integrity: sha512-NDYMpsXYJJaj+I7UdwIuHHNxXZ/b/N2hR15NyH3m2qAtb/hHPA4g4SuuvrdxetTdndfj9b1WOmy73kcPRoERUg==}
cpu: [riscv64]
os: [linux]
'@rollup/rollup-linux-riscv64-musl@4.59.0':
resolution: {integrity: sha512-nLckB8WOqHIf1bhymk+oHxvM9D3tyPndZH8i8+35p/1YiVoVswPid2yLzgX7ZJP0KQvnkhM4H6QZ5m0LzbyIAg==}
cpu: [riscv64]
os: [linux]
'@rollup/rollup-linux-s390x-gnu@4.59.0':
resolution: {integrity: sha512-oF87Ie3uAIvORFBpwnCvUzdeYUqi2wY6jRFWJAy1qus/udHFYIkplYRW+wo+GRUP4sKzYdmE1Y3+rY5Gc4ZO+w==}
cpu: [s390x]
os: [linux]
'@rollup/rollup-linux-x64-gnu@4.59.0':
resolution: {integrity: sha512-3AHmtQq/ppNuUspKAlvA8HtLybkDflkMuLK4DPo77DfthRb71V84/c4MlWJXixZz4uruIH4uaa07IqoAkG64fg==}
cpu: [x64]
os: [linux]
'@rollup/rollup-linux-x64-musl@4.59.0':
resolution: {integrity: sha512-2UdiwS/9cTAx7qIUZB/fWtToJwvt0Vbo0zmnYt7ED35KPg13Q0ym1g442THLC7VyI6JfYTP4PiSOWyoMdV2/xg==}
cpu: [x64]
os: [linux]
'@rollup/rollup-openbsd-x64@4.59.0':
resolution: {integrity: sha512-M3bLRAVk6GOwFlPTIxVBSYKUaqfLrn8l0psKinkCFxl4lQvOSz8ZrKDz2gxcBwHFpci0B6rttydI4IpS4IS/jQ==}
cpu: [x64]
os: [openbsd]
'@rollup/rollup-openharmony-arm64@4.59.0':
resolution: {integrity: sha512-tt9KBJqaqp5i5HUZzoafHZX8b5Q2Fe7UjYERADll83O4fGqJ49O1FsL6LpdzVFQcpwvnyd0i+K/VSwu/o/nWlA==}
cpu: [arm64]
os: [openharmony]
'@rollup/rollup-win32-arm64-msvc@4.59.0':
resolution: {integrity: sha512-V5B6mG7OrGTwnxaNUzZTDTjDS7F75PO1ae6MJYdiMu60sq0CqN5CVeVsbhPxalupvTX8gXVSU9gq+Rx1/hvu6A==}
cpu: [arm64]
os: [win32]
'@rollup/rollup-win32-ia32-msvc@4.59.0':
resolution: {integrity: sha512-UKFMHPuM9R0iBegwzKF4y0C4J9u8C6MEJgFuXTBerMk7EJ92GFVFYBfOZaSGLu6COf7FxpQNqhNS4c4icUPqxA==}
cpu: [ia32]
os: [win32]
'@rollup/rollup-win32-x64-gnu@4.59.0':
resolution: {integrity: sha512-laBkYlSS1n2L8fSo1thDNGrCTQMmxjYY5G0WFWjFFYZkKPjsMBsgJfGf4TLxXrF6RyhI60L8TMOjBMvXiTcxeA==}
cpu: [x64]
os: [win32]
'@rollup/rollup-win32-x64-msvc@4.59.0':
resolution: {integrity: sha512-2HRCml6OztYXyJXAvdDXPKcawukWY2GpR5/nxKp4iBgiO3wcoEGkAaqctIbZcNB6KlUQBIqt8VYkNSj2397EfA==}
cpu: [x64]
os: [win32]
'@swc/core-darwin-arm64@1.15.11':
resolution: {integrity: sha512-QoIupRWVH8AF1TgxYyeA5nS18dtqMuxNwchjBIwJo3RdwLEFiJq6onOx9JAxHtuPwUkIVuU2Xbp+jCJ7Vzmgtg==}
engines: {node: '>=10'}
cpu: [arm64]
os: [darwin]
'@swc/core-darwin-x64@1.15.11':
resolution: {integrity: sha512-S52Gu1QtPSfBYDiejlcfp9GlN+NjTZBRRNsz8PNwBgSE626/FUf2PcllVUix7jqkoMC+t0rS8t+2/aSWlMuQtA==}
engines: {node: '>=10'}
cpu: [x64]
os: [darwin]
'@swc/core-linux-arm-gnueabihf@1.15.11':
resolution: {integrity: sha512-lXJs8oXo6Z4yCpimpQ8vPeCjkgoHu5NoMvmJZ8qxDyU99KVdg6KwU9H79vzrmB+HfH+dCZ7JGMqMF//f8Cfvdg==}
engines: {node: '>=10'}
cpu: [arm]
os: [linux]
'@swc/core-linux-arm64-gnu@1.15.11':
resolution: {integrity: sha512-chRsz1K52/vj8Mfq/QOugVphlKPWlMh10V99qfH41hbGvwAU6xSPd681upO4bKiOr9+mRIZZW+EfJqY42ZzRyA==}
engines: {node: '>=10'}
cpu: [arm64]
os: [linux]
'@swc/core-linux-arm64-musl@1.15.11':
resolution: {integrity: sha512-PYftgsTaGnfDK4m6/dty9ryK1FbLk+LosDJ/RJR2nkXGc8rd+WenXIlvHjWULiBVnS1RsjHHOXmTS4nDhe0v0w==}
engines: {node: '>=10'}
cpu: [arm64]
os: [linux]
'@swc/core-linux-x64-gnu@1.15.11':
resolution: {integrity: sha512-DKtnJKIHiZdARyTKiX7zdRjiDS1KihkQWatQiCHMv+zc2sfwb4Glrodx2VLOX4rsa92NLR0Sw8WLcPEMFY1szQ==}
engines: {node: '>=10'}
cpu: [x64]
os: [linux]
'@swc/core-linux-x64-musl@1.15.11':
resolution: {integrity: sha512-mUjjntHj4+8WBaiDe5UwRNHuEzLjIWBTSGTw0JT9+C9/Yyuh4KQqlcEQ3ro6GkHmBGXBFpGIj/o5VMyRWfVfWw==}
engines: {node: '>=10'}
cpu: [x64]
os: [linux]
'@swc/core-win32-arm64-msvc@1.15.11':
resolution: {integrity: sha512-ZkNNG5zL49YpaFzfl6fskNOSxtcZ5uOYmWBkY4wVAvgbSAQzLRVBp+xArGWh2oXlY/WgL99zQSGTv7RI5E6nzA==}
engines: {node: '>=10'}
cpu: [arm64]
os: [win32]
'@swc/core-win32-ia32-msvc@1.15.11':
resolution: {integrity: sha512-6XnzORkZCQzvTQ6cPrU7iaT9+i145oLwnin8JrfsLG41wl26+5cNQ2XV3zcbrnFEV6esjOceom9YO1w9mGJByw==}
engines: {node: '>=10'}
cpu: [ia32]
os: [win32]
'@swc/core-win32-x64-msvc@1.15.11':
resolution: {integrity: sha512-IQ2n6af7XKLL6P1gIeZACskSxK8jWtoKpJWLZmdXTDj1MGzktUy4i+FvpdtxFmJWNavRWH1VmTr6kAubRDHeKw==}
engines: {node: '>=10'}
cpu: [x64]
os: [win32]
'@swc/core@1.15.11':
resolution: {integrity: sha512-iLmLTodbYxU39HhMPaMUooPwO/zqJWvsqkrXv1ZI38rMb048p6N7qtAtTp37sw9NzSrvH6oli8EdDygo09IZ/w==}
engines: {node: '>=10'}
peerDependencies:
'@swc/helpers': '>=0.5.17'
peerDependenciesMeta:
'@swc/helpers':
optional: true
'@swc/counter@0.1.3':
resolution: {integrity: sha512-e2BR4lsJkkRlKZ/qCHPw9ZaSxc0MVUd7gtbtaB7aMvHeJVYe8sOB8DBZkP2DtISHGSku9sCK6T6cnY0CtXrOCQ==}
'@swc/types@0.1.25':
resolution: {integrity: sha512-iAoY/qRhNH8a/hBvm3zKj9qQ4oc2+3w1unPJa2XvTK3XjeLXtzcCingVPw/9e5mn1+0yPqxcBGp9Jf0pkfMb1g==}
'@swc/wasm@1.15.11':
resolution: {integrity: sha512-230rdYZf8ux3nIwISOQNCFrxzxpL/UFY4Khv/3UsvpEdo709j/+Tg80yXWW3DXETeZNPBV72QpvEBhXsl7Lc9g==}
'@types/estree@1.0.8':
resolution: {integrity: sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==}
'@types/node@25.3.0':
resolution: {integrity: sha512-4K3bqJpXpqfg2XKGK9bpDTc6xO/xoUP/RBWS7AtRMug6zZFaRekiLzjVtAoZMquxoAbzBvy5nxQ7veS5eYzf8A==}
esbuild@0.27.3:
resolution: {integrity: sha512-8VwMnyGCONIs6cWue2IdpHxHnAjzxnw2Zr7MkVxB2vjmQ2ivqGFb4LEG3SMnv0Gb2F/G/2yA8zUaiL1gywDCCg==}
engines: {node: '>=18'}
hasBin: true
fdir@6.5.0:
resolution: {integrity: sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==}
engines: {node: '>=12.0.0'}
peerDependencies:
picomatch: ^3 || ^4
peerDependenciesMeta:
picomatch:
optional: true
fsevents@2.3.3:
resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==}
engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0}
os: [darwin]
nanoid@3.3.11:
resolution: {integrity: sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==}
engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1}
hasBin: true
picocolors@1.1.1:
resolution: {integrity: sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==}
picomatch@4.0.3:
resolution: {integrity: sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==}
engines: {node: '>=12'}
postcss@8.5.6:
resolution: {integrity: sha512-3Ybi1tAuwAP9s0r1UQ2J4n5Y0G05bJkpUIO0/bI9MhwmD70S5aTWbXGBwxHrelT+XM1k6dM0pk+SwNkpTRN7Pg==}
engines: {node: ^10 || ^12 || >=14}
rollup@4.59.0:
resolution: {integrity: sha512-2oMpl67a3zCH9H79LeMcbDhXW/UmWG/y2zuqnF2jQq5uq9TbM9TVyXvA4+t+ne2IIkBdrLpAaRQAvo7YI/Yyeg==}
engines: {node: '>=18.0.0', npm: '>=8.0.0'}
hasBin: true
source-map-js@1.2.1:
resolution: {integrity: sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==}
engines: {node: '>=0.10.0'}
tinyglobby@0.2.15:
resolution: {integrity: sha512-j2Zq4NyQYG5XMST4cbs02Ak8iJUdxRM0XI5QyxXuZOzKOINmWurp3smXu3y5wDcJrptwpSjgXHzIQxR0omXljQ==}
engines: {node: '>=12.0.0'}
typescript@5.9.3:
resolution: {integrity: sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==}
engines: {node: '>=14.17'}
hasBin: true
undici-types@7.18.2:
resolution: {integrity: sha512-AsuCzffGHJybSaRrmr5eHr81mwJU3kjw6M+uprWvCXiNeN9SOGwQ3Jn8jb8m3Z6izVgknn1R0FTCEAP2QrLY/w==}
uuid@10.0.0:
resolution: {integrity: sha512-8XkAphELsDnEGrDxUOHB3RGvXz6TeuYSGEZBOjtTtPm2lwhGBjLgOzLHB63IUWfBpNucQjND6d3AOudO+H3RWQ==}
hasBin: true
vite-plugin-top-level-await@1.6.0:
resolution: {integrity: sha512-bNhUreLamTIkoulCR9aDXbTbhLk6n1YE8NJUTTxl5RYskNRtzOR0ASzSjBVRtNdjIfngDXo11qOsybGLNsrdww==}
peerDependencies:
vite: '>=2.8'
vite-plugin-wasm@3.5.0:
resolution: {integrity: sha512-X5VWgCnqiQEGb+omhlBVsvTfxikKtoOgAzQ95+BZ8gQ+VfMHIjSHr0wyvXFQCa0eKQ0fKyaL0kWcEnYqBac4lQ==}
peerDependencies:
vite: ^2 || ^3 || ^4 || ^5 || ^6 || ^7
vite@7.3.1:
resolution: {integrity: sha512-w+N7Hifpc3gRjZ63vYBXA56dvvRlNWRczTdmCBBa+CotUzAPf5b7YMdMR/8CQoeYE5LX3W4wj6RYTgonm1b9DA==}
engines: {node: ^20.19.0 || >=22.12.0}
hasBin: true
peerDependencies:
'@types/node': ^20.19.0 || >=22.12.0
jiti: '>=1.21.0'
less: ^4.0.0
lightningcss: ^1.21.0
sass: ^1.70.0
sass-embedded: ^1.70.0
stylus: '>=0.54.8'
sugarss: ^5.0.0
terser: ^5.16.0
tsx: ^4.8.1
yaml: ^2.4.2
peerDependenciesMeta:
'@types/node':
optional: true
jiti:
optional: true
less:
optional: true
lightningcss:
optional: true
sass:
optional: true
sass-embedded:
optional: true
stylus:
optional: true
sugarss:
optional: true
terser:
optional: true
tsx:
optional: true
yaml:
optional: true
snapshots:
'@esbuild/aix-ppc64@0.27.3':
optional: true
'@esbuild/android-arm64@0.27.3':
optional: true
'@esbuild/android-arm@0.27.3':
optional: true
'@esbuild/android-x64@0.27.3':
optional: true
'@esbuild/darwin-arm64@0.27.3':
optional: true
'@esbuild/darwin-x64@0.27.3':
optional: true
'@esbuild/freebsd-arm64@0.27.3':
optional: true
'@esbuild/freebsd-x64@0.27.3':
optional: true
'@esbuild/linux-arm64@0.27.3':
optional: true
'@esbuild/linux-arm@0.27.3':
optional: true
'@esbuild/linux-ia32@0.27.3':
optional: true
'@esbuild/linux-loong64@0.27.3':
optional: true
'@esbuild/linux-mips64el@0.27.3':
optional: true
'@esbuild/linux-ppc64@0.27.3':
optional: true
'@esbuild/linux-riscv64@0.27.3':
optional: true
'@esbuild/linux-s390x@0.27.3':
optional: true
'@esbuild/linux-x64@0.27.3':
optional: true
'@esbuild/netbsd-arm64@0.27.3':
optional: true
'@esbuild/netbsd-x64@0.27.3':
optional: true
'@esbuild/openbsd-arm64@0.27.3':
optional: true
'@esbuild/openbsd-x64@0.27.3':
optional: true
'@esbuild/openharmony-arm64@0.27.3':
optional: true
'@esbuild/sunos-x64@0.27.3':
optional: true
'@esbuild/win32-arm64@0.27.3':
optional: true
'@esbuild/win32-ia32@0.27.3':
optional: true
'@esbuild/win32-x64@0.27.3':
optional: true
'@rollup/plugin-virtual@3.0.2(rollup@4.59.0)':
optionalDependencies:
rollup: 4.59.0
'@rollup/rollup-android-arm-eabi@4.59.0':
optional: true
'@rollup/rollup-android-arm64@4.59.0':
optional: true
'@rollup/rollup-darwin-arm64@4.59.0':
optional: true
'@rollup/rollup-darwin-x64@4.59.0':
optional: true
'@rollup/rollup-freebsd-arm64@4.59.0':
optional: true
'@rollup/rollup-freebsd-x64@4.59.0':
optional: true
'@rollup/rollup-linux-arm-gnueabihf@4.59.0':
optional: true
'@rollup/rollup-linux-arm-musleabihf@4.59.0':
optional: true
'@rollup/rollup-linux-arm64-gnu@4.59.0':
optional: true
'@rollup/rollup-linux-arm64-musl@4.59.0':
optional: true
'@rollup/rollup-linux-loong64-gnu@4.59.0':
optional: true
'@rollup/rollup-linux-loong64-musl@4.59.0':
optional: true
'@rollup/rollup-linux-ppc64-gnu@4.59.0':
optional: true
'@rollup/rollup-linux-ppc64-musl@4.59.0':
optional: true
'@rollup/rollup-linux-riscv64-gnu@4.59.0':
optional: true
'@rollup/rollup-linux-riscv64-musl@4.59.0':
optional: true
'@rollup/rollup-linux-s390x-gnu@4.59.0':
optional: true
'@rollup/rollup-linux-x64-gnu@4.59.0':
optional: true
'@rollup/rollup-linux-x64-musl@4.59.0':
optional: true
'@rollup/rollup-openbsd-x64@4.59.0':
optional: true
'@rollup/rollup-openharmony-arm64@4.59.0':
optional: true
'@rollup/rollup-win32-arm64-msvc@4.59.0':
optional: true
'@rollup/rollup-win32-ia32-msvc@4.59.0':
optional: true
'@rollup/rollup-win32-x64-gnu@4.59.0':
optional: true
'@rollup/rollup-win32-x64-msvc@4.59.0':
optional: true
'@swc/core-darwin-arm64@1.15.11':
optional: true
'@swc/core-darwin-x64@1.15.11':
optional: true
'@swc/core-linux-arm-gnueabihf@1.15.11':
optional: true
'@swc/core-linux-arm64-gnu@1.15.11':
optional: true
'@swc/core-linux-arm64-musl@1.15.11':
optional: true
'@swc/core-linux-x64-gnu@1.15.11':
optional: true
'@swc/core-linux-x64-musl@1.15.11':
optional: true
'@swc/core-win32-arm64-msvc@1.15.11':
optional: true
'@swc/core-win32-ia32-msvc@1.15.11':
optional: true
'@swc/core-win32-x64-msvc@1.15.11':
optional: true
'@swc/core@1.15.11':
dependencies:
'@swc/counter': 0.1.3
'@swc/types': 0.1.25
optionalDependencies:
'@swc/core-darwin-arm64': 1.15.11
'@swc/core-darwin-x64': 1.15.11
'@swc/core-linux-arm-gnueabihf': 1.15.11
'@swc/core-linux-arm64-gnu': 1.15.11
'@swc/core-linux-arm64-musl': 1.15.11
'@swc/core-linux-x64-gnu': 1.15.11
'@swc/core-linux-x64-musl': 1.15.11
'@swc/core-win32-arm64-msvc': 1.15.11
'@swc/core-win32-ia32-msvc': 1.15.11
'@swc/core-win32-x64-msvc': 1.15.11
'@swc/counter@0.1.3': {}
'@swc/types@0.1.25':
dependencies:
'@swc/counter': 0.1.3
'@swc/wasm@1.15.11': {}
'@types/estree@1.0.8': {}
'@types/node@25.3.0':
dependencies:
undici-types: 7.18.2
esbuild@0.27.3:
optionalDependencies:
'@esbuild/aix-ppc64': 0.27.3
'@esbuild/android-arm': 0.27.3
'@esbuild/android-arm64': 0.27.3
'@esbuild/android-x64': 0.27.3
'@esbuild/darwin-arm64': 0.27.3
'@esbuild/darwin-x64': 0.27.3
'@esbuild/freebsd-arm64': 0.27.3
'@esbuild/freebsd-x64': 0.27.3
'@esbuild/linux-arm': 0.27.3
'@esbuild/linux-arm64': 0.27.3
'@esbuild/linux-ia32': 0.27.3
'@esbuild/linux-loong64': 0.27.3
'@esbuild/linux-mips64el': 0.27.3
'@esbuild/linux-ppc64': 0.27.3
'@esbuild/linux-riscv64': 0.27.3
'@esbuild/linux-s390x': 0.27.3
'@esbuild/linux-x64': 0.27.3
'@esbuild/netbsd-arm64': 0.27.3
'@esbuild/netbsd-x64': 0.27.3
'@esbuild/openbsd-arm64': 0.27.3
'@esbuild/openbsd-x64': 0.27.3
'@esbuild/openharmony-arm64': 0.27.3
'@esbuild/sunos-x64': 0.27.3
'@esbuild/win32-arm64': 0.27.3
'@esbuild/win32-ia32': 0.27.3
'@esbuild/win32-x64': 0.27.3
fdir@6.5.0(picomatch@4.0.3):
optionalDependencies:
picomatch: 4.0.3
fsevents@2.3.3:
optional: true
nanoid@3.3.11: {}
picocolors@1.1.1: {}
picomatch@4.0.3: {}
postcss@8.5.6:
dependencies:
nanoid: 3.3.11
picocolors: 1.1.1
source-map-js: 1.2.1
rollup@4.59.0:
dependencies:
'@types/estree': 1.0.8
optionalDependencies:
'@rollup/rollup-android-arm-eabi': 4.59.0
'@rollup/rollup-android-arm64': 4.59.0
'@rollup/rollup-darwin-arm64': 4.59.0
'@rollup/rollup-darwin-x64': 4.59.0
'@rollup/rollup-freebsd-arm64': 4.59.0
'@rollup/rollup-freebsd-x64': 4.59.0
'@rollup/rollup-linux-arm-gnueabihf': 4.59.0
'@rollup/rollup-linux-arm-musleabihf': 4.59.0
'@rollup/rollup-linux-arm64-gnu': 4.59.0
'@rollup/rollup-linux-arm64-musl': 4.59.0
'@rollup/rollup-linux-loong64-gnu': 4.59.0
'@rollup/rollup-linux-loong64-musl': 4.59.0
'@rollup/rollup-linux-ppc64-gnu': 4.59.0
'@rollup/rollup-linux-ppc64-musl': 4.59.0
'@rollup/rollup-linux-riscv64-gnu': 4.59.0
'@rollup/rollup-linux-riscv64-musl': 4.59.0
'@rollup/rollup-linux-s390x-gnu': 4.59.0
'@rollup/rollup-linux-x64-gnu': 4.59.0
'@rollup/rollup-linux-x64-musl': 4.59.0
'@rollup/rollup-openbsd-x64': 4.59.0
'@rollup/rollup-openharmony-arm64': 4.59.0
'@rollup/rollup-win32-arm64-msvc': 4.59.0
'@rollup/rollup-win32-ia32-msvc': 4.59.0
'@rollup/rollup-win32-x64-gnu': 4.59.0
'@rollup/rollup-win32-x64-msvc': 4.59.0
fsevents: 2.3.3
source-map-js@1.2.1: {}
tinyglobby@0.2.15:
dependencies:
fdir: 6.5.0(picomatch@4.0.3)
picomatch: 4.0.3
typescript@5.9.3: {}
undici-types@7.18.2: {}
uuid@10.0.0: {}
vite-plugin-top-level-await@1.6.0(rollup@4.59.0)(vite@7.3.1(@types/node@25.3.0)):
dependencies:
'@rollup/plugin-virtual': 3.0.2(rollup@4.59.0)
'@swc/core': 1.15.11
'@swc/wasm': 1.15.11
uuid: 10.0.0
vite: 7.3.1(@types/node@25.3.0)
transitivePeerDependencies:
- '@swc/helpers'
- rollup
vite-plugin-wasm@3.5.0(vite@7.3.1(@types/node@25.3.0)):
dependencies:
vite: 7.3.1(@types/node@25.3.0)
vite@7.3.1(@types/node@25.3.0):
dependencies:
esbuild: 0.27.3
fdir: 6.5.0(picomatch@4.0.3)
picomatch: 4.0.3
postcss: 8.5.6
rollup: 4.59.0
tinyglobby: 0.2.15
optionalDependencies:
'@types/node': 25.3.0
fsevents: 2.3.3

View File

@@ -1,27 +0,0 @@
const { readFile, writeFile } = require("fs/promises");
const { dirname, resolve } = require("path");
main();
async function main() {
const root = dirname(__dirname);
const wasmJsPath = resolve(root, "dist/ffprobe-wasm.mjs");
let content = await readFile(wasmJsPath, { encoding: "utf8" });
content = `\
import initWasmInstance from "./ffprobe-wasm.wasm";
const initWasm = (info) =>
initWasmInstance(info).then((exports) => ({ instance: { exports } }));
${content}`;
content = content.replace(`import.meta.url`, `''`);
content = content.replace(
`instantiateAsync().catch(readyPromiseReject)`,
`initWasm(info).then(receiveInstantiatedSource, readyPromiseReject)`
);
await writeFile(wasmJsPath, content, { encoding: "utf8" });
}

View File

@@ -1,12 +1,14 @@
import type { FFprobeWorker as AbstractFFprobeWorker } from "./ffprobe-worker.mjs";
import type { import type {
Chapter, Chapter,
ChapterTag, Disposition,
FileInfo, FileInfo,
Format,
Frame, Frame,
FramesInfo, FramesInfo,
Rational,
Stream, Stream,
} from "./ffprobe-wasm.mjs"; } from "./types.mjs";
import type { FFprobeWorker as AbstractFFprobeWorker } from "./ffprobe-worker.js";
import BrowserWorker from "./worker-browser.mjs?worker&inline"; import BrowserWorker from "./worker-browser.mjs?worker&inline";
import type { import type {
IncomingMessage, IncomingMessage,
@@ -23,10 +25,13 @@ export class FFprobeWorker implements AbstractFFprobeWorker {
async getFileInfo(file: File): Promise<FileInfo> { async getFileInfo(file: File): Promise<FileInfo> {
this.#validateFile(file); this.#validateFile(file);
return this.#postMessage({ const fileInfo: FileInfo = await this.#postMessage({
type: "getFileInfo", type: "getFileInfo",
payload: [file.name, { files: [file] }], payload: [file.name, { files: [file] }],
}); });
fileInfo.format.filename = file.name;
fileInfo.format.size = file.size.toString();
return fileInfo;
} }
async getFrames(file: File, offset: number): Promise<FramesInfo> { async getFrames(file: File, offset: number): Promise<FramesInfo> {
@@ -44,7 +49,7 @@ export class FFprobeWorker implements AbstractFFprobeWorker {
#validateFile(file: File | string): asserts file is File { #validateFile(file: File | string): asserts file is File {
if (typeof file === "string") { if (typeof file === "string") {
throw new Error( throw new Error(
"String only supported in Node.js, you must provide a File" "String only supported in Node.js, you must provide a File",
); );
} }
} }
@@ -71,4 +76,13 @@ export class FFprobeWorker implements AbstractFFprobeWorker {
} }
} }
export type { Chapter, ChapterTag, FileInfo, Frame, FramesInfo, Stream }; export type {
Chapter,
Disposition,
FileInfo,
Format,
Frame,
FramesInfo,
Rational,
Stream,
};

View File

@@ -1,3 +1,5 @@
import { FileInfo, FramesInfo } from "./types.mjs";
export interface FFprobe { export interface FFprobe {
get_file_info(path: string): Raw<FileInfo>; get_file_info(path: string): Raw<FileInfo>;
get_frames(path: string, offset: number): Raw<FramesInfo>; get_frames(path: string, offset: number): Raw<FramesInfo>;
@@ -69,22 +71,7 @@ export interface AnalyzePathReturn {
parentObject: any | null; parentObject: any | null;
} }
export interface FileInfo { export interface Vector<T> {
bit_rate: number;
chapters: Chapter[];
/**
* Duration in microseconds
*/
duration: number;
flags: number;
name: string;
nb_chapters: number;
nb_streams: number;
streams: Stream[];
url: string;
}
export interface Collection<T> {
count: { value: number }; count: { value: number };
ptr: number; ptr: number;
ptrType: any; ptrType: any;
@@ -92,57 +79,17 @@ export interface Collection<T> {
size(): number; size(): number;
} }
export type Raw<T> = { export interface DictionaryEntry {
[K in keyof T]: T[K] extends Array<infer U> ? Collection<Raw<U>> : T[K];
};
export interface Chapter {
end: number;
id: number;
start: number;
tags: ChapterTag[];
/**
* @example "1/1000"
*/
time_base: string;
}
export interface ChapterTag {
key: string; key: string;
value: string; value: string;
} }
export interface Stream { export type Raw<T> = {
bit_rate: number; [K in keyof T]: T[K] extends Array<infer U>
channels: number; ? Vector<Raw<U>>
codec_name: string; : T[K] extends Record<string, string>
codec_type: number; ? Vector<DictionaryEntry>
duration: number; : T[K] extends string | number | boolean | undefined | null
format: string; ? T[K]
frame_size: number; : Raw<T[K]>;
height: number; };
id: number;
level: number;
profile: string;
sample_rate: number;
start_time: number;
width: number;
}
export interface FramesInfo {
avg_frame_rate: number;
duration: number;
frames: Frame[];
gop_size: number;
nb_frames: number;
time_base: number;
}
export interface Frame {
dts: number;
frame_number: number;
pict_type: number;
pkt_size: number;
pos: number;
pts: number;
}

View File

@@ -1,6 +1,6 @@
import { FFprobe } from "./ffprobe-wasm-shared"; import { FFprobe } from "./ffprobe-wasm-shared.mjs";
export * from "./ffprobe-wasm-shared"; export * from "./ffprobe-wasm-shared.mjs";
export default function loadFFprobe(ffprobe?: FFprobeInit): Promise<FFprobe>; export default function loadFFprobe(ffprobe?: FFprobeInit): Promise<FFprobe>;

View File

@@ -1,6 +1,6 @@
import { FFprobe } from "./ffprobe-wasm-shared"; import { FFprobe } from "./ffprobe-wasm-shared.mjs";
export * from "./ffprobe-wasm-shared"; export * from "./ffprobe-wasm-shared.mjs";
declare const ffprobe: FFprobe; declare const ffprobe: FFprobe;

17
src/ffprobe-worker.d.mts Normal file
View File

@@ -0,0 +1,17 @@
import { FileInfo, FramesInfo } from "./types.mjs";
export * from "./types.mjs";
export declare class FFprobeWorker {
/**
* This function tries to be equivalent to
* ```
* ffprobe -hide_banner -loglevel fatal -show_format -show_streams -show_chapters -show_private_data -print_format json
* ```
*/
getFileInfo(file: File | string): Promise<FileInfo>;
getFrames(file: File | string, offset: number): Promise<FramesInfo>;
terminate(): void;
}

View File

@@ -1,18 +0,0 @@
import type {
Chapter,
ChapterTag,
FileInfo,
Frame,
FramesInfo,
Stream,
} from "./ffprobe-wasm-shared";
export declare class FFprobeWorker {
getFileInfo(file: File | string): Promise<FileInfo>;
getFrames(file: File | string, offset: number): Promise<FramesInfo>;
terminate(): void;
}
export { Chapter, ChapterTag, FileInfo, Frame, FramesInfo, Stream };

View File

@@ -1,15 +1,18 @@
import { stat } from "fs/promises";
import { basename, dirname } from "path"; import { basename, dirname } from "path";
import { fileURLToPath } from "url"; import { fileURLToPath } from "url";
import { MessageChannel, Worker } from "worker_threads"; import { MessageChannel, Worker } from "worker_threads";
import type { FFprobeWorker as AbstractFFprobeWorker } from "./ffprobe-worker.mjs";
import type { import type {
Chapter, Chapter,
ChapterTag, Disposition,
FileInfo, FileInfo,
Format,
Frame, Frame,
FramesInfo, FramesInfo,
Rational,
Stream, Stream,
} from "./ffprobe-wasm.js"; } from "./types.mjs";
import type { FFprobeWorker as AbstractFFprobeWorker } from "./ffprobe-worker.js";
import type { import type {
IncomingMessage, IncomingMessage,
IncomingData, IncomingData,
@@ -26,10 +29,13 @@ export class FFprobeWorker implements AbstractFFprobeWorker {
async getFileInfo(filePath: string): Promise<FileInfo> { async getFileInfo(filePath: string): Promise<FileInfo> {
this.#validateFile(filePath); this.#validateFile(filePath);
return this.#postMessage({ const fileInfo: FileInfo = await this.#postMessage({
type: "getFileInfo", type: "getFileInfo",
payload: [basename(filePath), { root: dirname(filePath) }], payload: [basename(filePath), { root: dirname(filePath) }],
}); });
fileInfo.format.filename = filePath;
fileInfo.format.size = (await stat(filePath)).size.toString();
return fileInfo;
} }
async getFrames(filePath: string, offset: number): Promise<FramesInfo> { async getFrames(filePath: string, offset: number): Promise<FramesInfo> {
@@ -47,7 +53,7 @@ export class FFprobeWorker implements AbstractFFprobeWorker {
#validateFile(filePath: string | File): asserts filePath is string { #validateFile(filePath: string | File): asserts filePath is string {
if (typeof filePath === "object") { if (typeof filePath === "object") {
throw new Error( throw new Error(
"File object only supported in Browser, you must provide a string (path)" "File object only supported in Browser, you must provide a string (path)",
); );
} }
} }
@@ -73,4 +79,13 @@ export class FFprobeWorker implements AbstractFFprobeWorker {
} }
} }
export type { Chapter, ChapterTag, FileInfo, Frame, FramesInfo, Stream }; export type {
Chapter,
Disposition,
FileInfo,
Format,
Frame,
FramesInfo,
Rational,
Stream,
};

131
src/types.d.mts Normal file
View File

@@ -0,0 +1,131 @@
export type Rational = `${number}/${number}`;
export interface FileInfo {
streams: Stream[];
chapters: Chapter[];
format: Format;
}
export interface Format {
filename: string;
nb_streams: number;
nb_programs: number;
format_name: string;
format_long_name: string;
start_time: string;
duration: string;
size: string;
bit_rate: string;
probe_score: number;
tags: Record<string, string>;
}
export interface Chapter {
/**
* Chapter end time in time_base units
*/
end: number;
/**
* unique ID to identify the chapter
*/
id: number;
tags: Record<string, string>;
/**
* Chapter start time in time_base units
*/
start: number;
/**
* Time base in which the start/end timestamps are specified
* @example "1/1000"
*/
time_base: Rational;
}
export interface Stream {
index: number;
codec_name: string;
codec_long_name: string;
profile: string;
codec_type: string;
codec_tag_string: string;
codec_tag: string;
width: number;
height: number;
codec_width: number;
codec_height: number;
closed_captions: number;
has_b_frames: number;
pix_fmt: string;
level: number;
color_range: string;
color_primaries: string;
chroma_location: string;
refs: number;
is_avc: string;
nal_length_size: string;
sample_fmt: string;
sample_rate: string;
channels: number;
channel_layout: string;
bits_per_sample: number;
r_frame_rate: string;
avg_frame_rate: string;
/**
* This is the fundamental unit of time (in seconds) in terms
* of which frame timestamps are represented.
*/
time_base: Rational;
start_pts: number;
start_time: string;
duration_ts: number;
/**
* Duration of the stream, in stream time base.
* If a source file does not specify a duration, but does specify
* a bitrate, this value will be estimated from bitrate and file size.
*/
duration: string;
/**
* Total stream bitrate in bit/s, 0 if not available.
*/
bit_rate: string;
bits_per_raw_sample: string;
nb_frames: string;
disposition: Disposition;
tags: Record<string, string>;
}
export interface Disposition {
default: 0 | 1;
dub: 0 | 1;
original: 0 | 1;
comment: 0 | 1;
lyrics: 0 | 1;
karaoke: 0 | 1;
forced: 0 | 1;
hearing_impaired: 0 | 1;
visual_impaired: 0 | 1;
clean_effects: 0 | 1;
attached_pic: 0 | 1;
timed_thumbnails: 0 | 1;
}
export interface FramesInfo {
avg_frame_rate: number;
duration: number;
frames: Frame[];
gop_size: number;
nb_frames: number;
time_base: number;
}
export interface Frame {
dts: number;
frame_number: number;
pict_type: number;
pkt_size: number;
pos: number;
pts: number;
}

View File

@@ -1,19 +1,22 @@
import { createRequire } from "module";
import { parentPort } from "worker_threads"; import { parentPort } from "worker_threads";
import type { FFprobe } from "./ffprobe-wasm.js";
import { createListener } from "./worker.mjs"; import { createListener } from "./worker.mjs";
if (!parentPort) { if (!parentPort) {
throw new Error("parentPort must be defined. Are you sure you are in a worker context?"); throw new Error("parentPort must be defined.");
} }
const require = createRequire(import.meta.url); const listenerPromise = (async () => {
const { default: initFFprobe } = await import("./ffprobe-wasm.mjs");
const listener = createListener(new Promise((resolve) => { return createListener(new Promise(async (resolve) => {
const ffprobe: FFprobe = require('./ffprobe-wasm.js') const ffprobe = await initFFprobe();
ffprobe.onRuntimeInitialized = () => { ffprobe.onRuntimeInitialized = () => {
resolve(ffprobe); resolve(ffprobe);
} };
}), "NODEFS"); }), "NODEFS");
})();
parentPort.on("message", listener); parentPort.on("message", async (data) => {
const listener = await listenerPromise;
await listener(data);
});

View File

@@ -1,7 +1,17 @@
import type { MessagePort as NodeMessagePort } from "worker_threads"; import type { MessagePort as NodeMessagePort } from "worker_threads";
import type { Chapter, ChapterTag, FFprobe, FileInfo, FramesInfo, FSFilesystems, FSMountOptions, Stream } from "./ffprobe-wasm-shared"; import type {
DictionaryEntry,
FFprobe,
FSFilesystems,
FSMountOptions,
Raw,
Vector,
} from "./ffprobe-wasm-shared.mjs";
import { FileInfo, FramesInfo, Stream } from "./types.mjs";
export type IncomingMessage = { port: MessagePort | NodeMessagePort } & IncomingData; export type IncomingMessage = {
port: MessagePort | NodeMessagePort;
} & IncomingData;
export type IncomingData = export type IncomingData =
| { | {
@@ -63,7 +73,33 @@ export function createListener(
} }
} }
async function getFileInfo(fileName: string, mountOptions: FSMountOptions): Promise<FileInfo> { function vectorToArray<T>(vector: Vector<T>): T[] {
const array: T[] = [];
for (let i = 0; i < vector.size(); i++) {
array.push(vector.get(i));
}
return array;
}
function dictionaryVectorToRecord(
vector: Vector<DictionaryEntry>,
): Record<string, string> {
return Object.fromEntries(
vectorToArray(vector).map(({ key, value }) => [key, value]),
);
}
function serializeStreams(streams: Vector<Raw<Stream>>) {
return vectorToArray(streams).map((stream) => ({
...stream,
tags: (stream && stream.tags) ? dictionaryVectorToRecord(stream.tags) : {},
}));
}
async function getFileInfo(
fileName: string,
mountOptions: FSMountOptions,
): Promise<FileInfo> {
const { FS, get_file_info } = await ffprobePromise; const { FS, get_file_info } = await ffprobePromise;
try { try {
if (!FS.analyzePath("/work").exists) { if (!FS.analyzePath("/work").exists) {
@@ -71,32 +107,21 @@ export function createListener(
} }
FS.mount(FS.filesystems[fsType], mountOptions, "/work"); FS.mount(FS.filesystems[fsType], mountOptions, "/work");
// Call the wasm module.
const rawInfo = get_file_info(`/work/${fileName}`); const rawInfo = get_file_info(`/work/${fileName}`);
// Remap streams into collection. // Safety check on rawInfo itself
const streams: Stream[] = []; if (!rawInfo) throw new Error("FFprobe failed to return file info");
for (let i = 0; i < rawInfo.streams.size(); i++) {
streams.push(rawInfo.streams.get(i));
}
// Remap chapters into collection.
const chapters: Chapter[] = [];
for (let i = 0; i < rawInfo.chapters.size(); i++) {
const rawChapter = rawInfo.chapters.get(i);
const tags: ChapterTag[] = [];
for (let j = 0; j < rawChapter.tags.size(); j++) {
tags.push(rawChapter.tags.get(j));
}
chapters.push({ ...rawChapter, tags });
}
return { return {
...rawInfo, streams: serializeStreams(rawInfo.streams),
streams, chapters: rawInfo.chapters ? vectorToArray(rawInfo.chapters).map((chapter) => ({
chapters, ...chapter,
tags: chapter.tags ? dictionaryVectorToRecord(chapter.tags) : {},
})) : [],
format: {
...rawInfo.format,
tags: (rawInfo.format && rawInfo.format.tags) ? dictionaryVectorToRecord(rawInfo.format.tags) : {},
}
}; };
} finally { } finally {
// Cleanup mount. // Cleanup mount.
@@ -104,7 +129,11 @@ export function createListener(
} }
} }
async function getFrames(fileName: string, mountOptions: FSMountOptions, offset: number): Promise<FramesInfo> { async function getFrames(
fileName: string,
mountOptions: FSMountOptions,
offset: number,
): Promise<FramesInfo> {
const { FS, get_frames } = await ffprobePromise; const { FS, get_frames } = await ffprobePromise;
try { try {
if (!FS.analyzePath("/work").exists) { if (!FS.analyzePath("/work").exists) {
@@ -112,18 +141,11 @@ export function createListener(
} }
FS.mount(FS.filesystems.WORKERFS, mountOptions, "/work"); FS.mount(FS.filesystems.WORKERFS, mountOptions, "/work");
// Call the wasm module.
const framesInfo = get_frames(`/work/${fileName}`, offset); const framesInfo = get_frames(`/work/${fileName}`, offset);
// Remap frames into collection.
const frames = [];
for (let i = 0; i < framesInfo.frames.size(); i++) {
frames.push(framesInfo.frames.get(i));
}
return { return {
...framesInfo, ...framesInfo,
frames, frames: vectorToArray(framesInfo.frames),
}; };
} finally { } finally {
// Cleanup mount. // Cleanup mount.

View File

@@ -1,5 +1,7 @@
import { resolve } from "path"; import { resolve } from "path";
import { defineConfig } from "vite"; import { defineConfig } from "vite";
import topLevelAwait from "vite-plugin-top-level-await";
import wasm from "vite-plugin-wasm";
// https://vitejs.dev/config/ // https://vitejs.dev/config/
export default defineConfig({ export default defineConfig({
@@ -14,18 +16,16 @@ export default defineConfig({
minify: false, minify: false,
sourcemap: true, sourcemap: true,
}, },
worker: {
plugins: [ plugins: [
{
name: "append-source-url", wasm(),
generateBundle(options, bundle) { topLevelAwait()
Object.entries(bundle).forEach(([file, output]) => {
if (output.type === "chunk") {
output.code += `\n//# sourceURL=${file}`;
}
});
},
},
], ],
worker: {
plugins: () => [
wasm(),
topLevelAwait(),
],
format: "es"
}, },
}); });