Skip to content

@igpapi/media-codec ​

Installed with @igpapi/android; you never import it. One thing to know: if a bundler inlines the packages into one file, copy the package's module/ directory beside what it loads from (details below).

The image and video codec of igpapi, the Instagram private API Simulator for Node.js: what a photo or a video needs before it is uploaded the way the Instagram app uploads it. It holds libjpeg-turbo and LodePNG (decode), libwebp (encode), the PDQ perceptual hash and AOSP's libavc (H.264 decode and encode), compiled to WebAssembly for Node. The platform package installs it.

  • decodeJpeg(bytes) decodes a JPEG to packed RGB.

  • decodePng(bytes) decodes a PNG (any bit depth, palette or grey scale) to packed RGB and says whether any pixel is not fully opaque.

  • encodeWebp({ width, height, rgb, quality }) writes the lossy WebP the app uploads, with its sRGB profile.

  • pdqHashOf(image) answers the PDQ hash and its quality, "<hash>:<quality>" as the app sends them.

  • posterJpegOf({ source, crop, signal }) decodes the first picture of an H.264 stream and writes it as the baseline JPEG the app uploads as a video's poster frame.

  • encodeAvc({ source, target, order, signal }) decodes an H.264 stream and encodes it again with the app's settings (Main profile, level 3.1, constant rate that follows target.bitRateBps).

  • No native code and no install script: each WebAssembly module is inlined (as base64) in one ES module, so it behaves the same on Linux, macOS and Windows with Node 22 or later.

  • A video run happens in its own worker thread, so your event loop keeps running while it encodes. The thread is ended when the run settles or when the run's AbortSignal aborts.

  • Three files must ship next to each other. The package loads module/media-codec-image.mjs, module/media-codec-video.mjs and module/media-codec-video.worker.mjs by file URL (import.meta.url) at run time, so a bundler that inlines the package's dist into one file must still copy the package's module/ directory beside what it loads from.

License ​

(Apache-2.0 AND BSD-3-Clause AND Zlib): libavc is Apache-2.0, libwebp and the PDQ reference are BSD-3-Clause, libjpeg-turbo is IJG, BSD-3-Clause and Zlib, and LodePNG is Zlib. No copyleft component is built in. The licence texts are in licenses/.

  • Source. Every source is the unmodified release or commit named in module/media-codec.manifest.json, with its URL and sha256. The PDQ reference is vendored unmodified in recipe/vendor/pdq with its licence.
  • Build recipe. recipe/build-in-container.sh builds both modules inside the Emscripten SDK image the manifest pins by digest, and recipe/rebuild.mjs runs that build with Docker. The rebuild reproduces both modules byte for byte, and the manifest records their sha256 and the recipe's. The recipe is published and runs from the installed package (recipe/recipe-hash.mjs carries its own copy of the shared hash definition, put there when the package is packed); the rebuild needs Docker and the three source tarballs the manifest names.
  • Replacing a module. Each module is a separate file that the package's own code loads at run time, so you can replace it with your own build.

The pages of this site are the README files of the repository. The API reference is generated from the source.