1
0
Fork 0
mirror of https://github.com/codedread/bitjs synced 2025-10-03 09:39:16 +02:00
No description
Find a file
2023-11-20 22:44:41 -08:00
.github/workflows Check in some starter thinking around a media API in bitjs. 2023-05-27 12:07:49 -07:00
archive Add TODO to eventually un-Worker-ify the untar, unzip, unrar scripts. 2023-11-20 21:39:02 -08:00
build Issue #28: Removed build step for bitjs.io now that all browsers (Firefox 114+) support ES Module Workers. 2023-05-28 10:39:35 -07:00
codecs Update to 1.1.6 for mp3 streams and ffprobe reporting mp4 files with unknown levels 2023-10-25 20:40:26 -07:00
docs Minor grammar tweak to unrar docs 2023-03-10 18:41:25 -08:00
file Tighten up the file sniffer findMimeType() implementation and improve test coverage 2023-03-10 17:37:09 -08:00
image/webp-shim Correct some typos, expose codecs in the main module (woops), and provide Typescript types (d.ts files) 2022-10-30 16:54:53 -07:00
io Beef up unit test coverage in io package. 2023-11-20 22:44:41 -08:00
media Check in some starter thinking around a media API in bitjs. 2023-05-27 12:07:49 -07:00
tests Beef up unit test coverage in io package. 2023-11-20 22:44:41 -08:00
types Update Typescript types for 1.1.0 2023-05-28 10:50:31 -07:00
.c8rc Add unit test coverage 2023-02-15 23:22:35 -08:00
.gitignore Add unit test coverage 2023-02-15 23:22:35 -08:00
CHANGELOG.md Update to 1.1.6 for mp3 streams and ffprobe reporting mp4 files with unknown levels 2023-10-25 20:40:26 -07:00
index.js Issue #28: Removed build step for bitjs.io now that all browsers (Firefox 114+) support ES Module Workers. 2023-05-28 10:39:35 -07:00
LICENSE Accidentally didn't add the updated files. 2016-04-19 18:00:27 -07:00
package-lock.json Beef up unit test coverage in io package. 2023-11-20 22:44:41 -08:00
package.json Beef up unit test coverage in io package. 2023-11-20 22:44:41 -08:00
README.md Remove typo in README 2023-03-11 07:32:53 -08:00
tsconfig.json Correct some typos, expose codecs in the main module (woops), and provide Typescript types (d.ts files) 2022-10-30 16:54:53 -07:00

Node.js CI

bitjs: Binary Tools for JavaScript

Introduction

A set of dependency-free JavaScript modules to handle binary data in JS (using Typed Arrays). Includes:

  • bitjs/archive: Unarchiving files (unzip, unrar, untar) in the browser, implemented as Web Workers and allowing progressively unarchiving while streaming.
  • bitjs/codecs: Get the codec info of media containers in a ISO RFC6381 MIME type string
  • bitjs/file: Detect the type of file from its binary signature.
  • bitjs/image: Conversion of WebP images to PNG or JPEG.
  • bitjs/io: Low-level classes for interpreting binary data (BitStream, ByteStream). For example, reading or peeking at N bits at a time.

Installation

Install it using your favourite package manager, the package is registered under @codedread/bitjs.

$ npm install @codedread/bitjs

or

$ yarn add @codedread/bitjs

Using in Node

This module is an ES Module, which should work as expected in other projects using ES Modules. However, if you are using a project that uses CommonJs modules, it's a little tricker to use. One valid example of this is if a TypeScript project compiles to CommonJS, it will try to turn imports into require() statements, which will break. The fix for this (unfortunately) is to update your tsconfig.json:

 "moduleResolution": "Node16",

and use a Dynamic Import:

const { getFullMIMEString } = await import('@codedread/bitjs');

Packages

bitjs.archive

This package includes objects for unarchiving binary data in popular archive formats (zip, rar, tar) providing unzip, unrar and untar capabilities via JavaScript in the browser. A prototype version of a compressor that creates Zip files is also present. The decompression/compression actually happens inside a Web Worker.

Decompressing

import { Unzipper } from './bitjs/archive/decompress.js';
const unzipper = new Unzipper(zipFileArrayBuffer);
unzipper.addEventListener('progress', updateProgress);
unzipper.addEventListener('extract', receiveOneFile);
unzipper.addEventListener('finish', displayZipContents);
unzipper.start();

function updateProgress(e) {
  // e.currentFilename is the file currently being unarchived/scanned.
  // e.totalCompressedBytesRead has how many bytes have been unzipped so far
}

function receiveOneFile(e) {
  // e.unarchivedFile.filename: string
  // e.unarchivedFile.fileData: Uint8Array
}

function displayZipContents() {
  // Now sort your received files and show them or whatever...
}

The unarchivers also support progressively decoding while streaming the file, if you are receiving the zipped file from a slow place (a Cloud API, for instance). For example:

import { Unzipper } from './bitjs/archive/decompress.js';
const unzipper = new Unzipper(anArrayBufferWithStartingBytes);
unzipper.addEventListener('progress', updateProgress);
unzipper.addEventListener('extract', receiveOneFile);
unzipper.addEventListener('finish', displayZipContents);
unzipper.start();
...
// after some time
unzipper.update(anArrayBufferWithMoreBytes);
...
// after some more time
unzipper.update(anArrayBufferWithYetMoreBytes);

Compressing

The Zipper only supports creating zip files without compression (story only) for now. The interface is pretty straightforward and there is no event-based / streaming API.

import { Zipper } from './bitjs/archive/compress.js';
const zipper = new Zipper();
const now = Date.now();
// Zip files foo.jpg and bar.txt.
const zippedArrayBuffer = await zipper.start(
  [
    {
      fileName: 'foo.jpg',
      lastModTime: now,
      fileData: fooArrayBuffer,
    },
    {
      fileName: 'bar.txt',
      lastModTime: now,
      fileData: barArrayBuffer,
    }
  ],
  true /* isLastFile */);

bitjs.codecs

This package includes code for dealing with media files (audio/video). It is useful for deriving ISO RFC6381 MIME type strings, including the codec information. Currently supports a limited subset of MP4 and WEBM.

How to use:

  • First, install ffprobe (ffmpeg) on your system.
  • Then:

import { getFullMIMEString } from 'bitjs/codecs/codecs.js';
/**
 * @typedef {import('bitjs/codecs/codecs.js').ProbeInfo} ProbeInfo
 */

const cmd = 'ffprobe -show_format -show_streams -print_format json -v quiet foo.mp4';
exec(cmd, (error, stdout) => {
  /** @type {ProbeInfo} */
  const info = JSON.parse(stdout);
  // 'video/mp4; codecs="avc1.4D4028, mp4a.40.2"'
  const contentType = getFullMIMEString(info);
  ...
});

bitjs.file

This package includes code for dealing with files. It includes a sniffer which detects the type of file, given an ArrayBuffer.

import { findMimeType } from './bitjs/file/sniffer.js';
const mimeType = findMimeType(someArrayBuffer);

bitjs.image

This package includes code for dealing with binary images. It includes a module for converting WebP images into alternative raster graphics formats (PNG/JPG).

import { convertWebPtoPNG, convertWebPtoJPG } from './bitjs/image/webp-shim/webp-shim.js';
// convertWebPtoPNG() takes in an ArrayBuffer containing the bytes of a WebP
// image and returns a Promise that resolves with an ArrayBuffer containing the
// bytes of an equivalent PNG image.
convertWebPtoPNG(webpBuffer).then(pngBuf => {
  const pngUrl = URL.createObjectURL(new Blob([pngBuf], {type: 'image/png'}));
  someImgElement.setAttribute(src, pngUrl);
});

bitjs.io

This package includes stream objects for reading and writing binary data at the bit and byte level: BitStream, ByteStream.

import { BitStream } from './bitjs/io/bitstream.js';
const bstream = new BitStream(someArrayBuffer, true, offset, length);
const crc = bstream.readBits(12); // read in 12 bits as CRC, advancing the pointer
const flagbits = bstream.peekBits(6); // look ahead at next 6 bits, but do not advance the pointer

Reference

  • UnRar: A work-in-progress description of the RAR file format.

History

This project grew out of another project of mine, kthoom (a comic book reader implemented in the browser). This repository was automatically exported from my original repository on GoogleCode and has undergone considerable changes and improvements since then, including adding streaming support, starter RarVM support, tests, many bug fixes, and updating the code to ES6.