Research
Security News
Quasar RAT Disguised as an npm Package for Detecting Vulnerabilities in Ethereum Smart Contracts
Socket researchers uncover a malicious npm package posing as a tool for detecting vulnerabilities in Etherium smart contracts.
@emliri/mmjs
Advanced tools
@emliri/mmjs
: https://www.npmjs.com/package/@emliri/mmjsoffice@emliri.com
mmjs
mmjs
is a framework library to enable implementing complex multimedia workflows on JS platforms.
The core design allows to build data-flow pipelines for processing time-ordered packet streams in a graph-based manner. Usually audio, video and subtitles data. But anything else is possible that you want to attach a timestamp to :)
Our framework allows to decouple processing steps being performed in workers via media-aware data-structures. The details of transferring data across worker instances and synchronizing it is however dealt-with by the core framework itself. Implementors of processors
don't need to know about the execution context and application details. The concept we use is called Worker-proxy and with our core API we are basically allowing RPC back and forth across JS scopes to make this possible.
Thus, each Processor
can take care of a specific task where it processes input packets and transfers output packets via its respective InputSocket
s and OuputSocket
s, fully independently of concurrently running tasks.
Moreoever, Processor
s can access generic metadata to handle various input streams and generate output data streams (packets), independent of the sources and destinations or the actual application. Every processor serves a specific processing purpose with maximum reusability in mind.
Processors
are things we run via our ProcessorWorkerProxy
. They have Sockets
, these allow them to transfer Packets
to each other. Every packet contains BufferSlices
(they are like DataView
but fancier), each of those has BufferProperties
i.e PayloadDescription
. Every Socket
has a SocketDescriptor
(which is a payload description too).
There are ways for processors to send each others Signals
"up" and "down" the packet streaming graph. That is very useful for real-time processing application cases, but not only.
Moreover, data processing can be queued, retained/halted/flushed/drained and filtered in between processors (but also inside) at the socket level, using something we call a FifoValve
. Consider it like the traffic lights in this, which can be controlled by the application or workflow internal timing/controllers.
Finally, some components emit events, which eventually get processed by the main thread. For example, socket or valve events can be used to drive/feedback the flow-controlling layer. Processors events are usually there to inform about internal exceptions.
Error-data semantics are built with hierarchy and propagation in mind.
As a top-level component in our core architecture, we provide the Flow
which is supposed to embed processors, and obviously embed its own type of component as a container.
A Flow
is called like this because it represents a "workflow" from an application point-of-view - it should allow to fulfill a tangible use-case. But also because it can embed a graph of processors, and manages the state of data flowing through these processors, as well as allowing to connect externally to its inputs/outputs and/or access the result upon "completion".
As opposed to other frameworks, we do not provide a container which at the same time inherits from the "elementary" atomic graph-element. The container element has the necessary properties (external sockets) to inter-connect the graphs that it contains at any embedded depth with other graphs. However it mostly is concerned with state-keeping of the higher-level task itself and propagating low-level events from individual processors.
The source-tree and bundled library contains different parts. First of all the core library with the generic components for all the abstract concepts explained above. Then built-in implementations of Processors
, IOSockets
, Flows
, .... You can use these, or build your own on top!
Finally, we like to ship tangible test-cases for whatever we build. Concerning plugins, rather than building a unit-test we almost prefer that it is used in a real-world example with a useful result in order to test it. That said, for generic core components, we like to have solid unit testing.
We are using TypeScript to design a solid but flexible framework, while being able to wrap any libraries that implement formats or codecs like H264, MP3, MP4 or Webm. We preferrably wrap libraries that are already written in TS or with detailed type-declarations.
Multimedia-js is thought to run on Nodejs and Web based runtimes (browsers etc). Processors are thought to be platform independent. The only requirement is an ES5 compatible runtime, and having workers enabled.
For maximum enjoyability, be sure to have the Worker
API enabled. In fact, the purpose of task-specific concurrent pipeline processing can not be taken advantage of without our Worker-proxy concept, and thus most use-cases will not run then.
From an architectural point of view, we envision to build use-case implementations (processors, flows) such that they will be used on either platform.
The core by its design obviously does not use any Web/Nodejs specific APIs either.
Furthermore the core design allows to abstract any Web/Nodejs specifics into io-sockets
which are supposed to allow the data-processing pipeline to acces environment I/O in whichever form (e.g local file-system, HTTP via XHR/Fetch or Nodejs APIs, WebAudio, LocalStorage, etc...). IO-sockets implementations may generalize across platform details, or be platform specific and thus lead to API-support errors in turn (for example WebAudio just doesn't exist by default on Nodejs).
There exists a v0.x
with various releases. Please see comment at bottom if you are looking for this.
To get started with Multimedia-js (mmjs), simply clone & build the project, and check our test-cases
in the project root.
git@github.com:emliri/multimedia-js.git
make # only needed once because we want to install some third-party binaries in publishable `vendor` directory
npm start # if you only modify TS codebase, you can only run this next time
In your browser, navigate to http://localhost:8080/test-cases/web/?case=0
Replace 0
by any index (see initial console output).
In a hurry or too lazy to build it yourself? ;P
We always make the latest build of master available through the Netlify network here:
https://multimedia-js-nightly.netlify.com/
You can even directly check out web test-cases here:
https://multimedia-js-nightly.netlify.com/test-cases/web
Multimedia-js is published on NPM (and dependent JS-CDNs) as package named multimedia
:
https://www.npmjs.com/package/multimedia
Use npm install --save multimedia
to add it to your existing JS application project for example.
Also when compiling yourself, find the relevant UMD bundles in the dist
folder.
Example of ES6 import when installed via NPM:
import * as mmjs from 'multimedia/dist/MM.umd'
Check out more use-cases in the test-cases
dir, or browse directly to the online demo deploy.
Here we are demonstrating a straight forward usage of the Flow
API for a specific use-case where a flow-implementation is used to "remix" i.e recombine an existing video track and an audio track (which may be MP3 and would then get transcoded to AAC) into a new single MOV/MP4 file. These tracks are initially assumed to come in any ISO-BMFF/MP4 format as well (except when MP3 for the audio obviously). In a simpler way, we are muxing a new file from two initial files, but only preserving the first audio/video track respectively from each file.
// pre: imported Multimedia package as `mmjs` in this scope
const flow = new mmjs.Flows.CombineMp4sToMovFlow(
videoUrl,
audioUrl,
false, // useFileDonwloadSocket
null, // downloadLinkContainer
true // isMp3Audio
)
flow.state = mmjs.Core.FlowState.WAITING
flow.state = mmjs.Core.FlowState.FLOWING
// returns Promise<Blob>
flow.whenCompleted((result) => {
const exportedMov = result.data
// do something with the result (Blob type)
})
Please note: The v1 branch is in fast-pace development and as we increase minor versions, some public APIs might change in non-backward-compatible way.
API compatibility across versions is not any of our priorities at the moment. We are focused on delivering a lean and stable library packed with features and fulfilling for use-cases.
However the most high-level and use-case oriented interfaces usually do not change, and we are integrating against the "test-cases" which we make available as part of the library, so stick to that if you need something to trust in at the moment.
As a roadmap, we see a potential v2 release as the first "API stable", and therefore a major milestone to achieve. A stable API will be the product of the current phase where we can explore various use-cases and their needs.
We are running automated unit & integration tests in our CI using the JEST test runner. This means the runtime environment is enforced to be bare Node.js (as opposed to browser or other Web based engine).
This approach allows us to constrain the testing scope on non-DOM dependent modules, non browser-API dependent modules (and/or forcing us to mock these where really needed, as they "should" interact with our code). We want to test our code, not some browser implementation or platform-specific part of the runtime.
Ideally, we write a "spec" in BDD style for each module (that's the goal). This is to be considered a "unit test" for the module, and should contain sub-specifications (tests) for all various cases the UuT should comply to.
We can also write integration tests that will depend on several modules (in terms of source files or object families). There is no formal technical limitation at the moment between writing a spec that is to be considered a unit test or an integration test in the strict definition at the moment in our setup, from the point of view of one "module".
For every module, we test everything that is a meaningful use-case, and there with the maximum range of data. We don't test everything (we can't), and most importantly we don't test things that aren't supposed to be done with our stuff.
Please consider the terms unit vs integration test is sometimes a matter of point of view (and more specifically in the case of mmjs). If we write a unit test for a Flow
type component, then that is an integration test for all the processors it uses. To be meaningful, we think that unit tests are useful for all the "core" API abstract functionalities and components as well as specific "processors" and "io-sockets". When it comes to more high-level functionality like "flows", it would be regarded an integration test by the nature of the UuT.
TODO: Next, we will set up functional testing in an automated browser environment to deliver on acceptance criterias for high-level use-cases, especially where Web-API specific integration may play a role.
So far, we don't see the need to extend this approach on different Node API and runtime versions or platform integrations as stronger integrity is given there naturally. Our CI uses a specific Node version (which we officially support in that sense), and developers are allowed to use any recent version on their side. We don't constrain the development environment to a specific one.
Also see information on the Supported Node.js version.
We use make
to bring together all the things, since we don't consider npm a task-runner worthy of this term (but a great package-system however). Nor do we want to misue Webpack as such a one. We appreciate the ability of Make to guard us from having the computer do the same thing twice unnecessarily.
We rely on Webpack for JS compilation and bundling. We use the official Typescript toolchain with it (not Babel).
Our build is a bit more complex than just installing a few packages and hitting Webpack however. We are making use of prebuilt WASM binaries for example, and rely on them being copied to a specific place outside of node_modules
, or allow them to come from other sources than npm
in the first place.
We happily take advantage of using GIT "submodules" where it is meaningful.
Note that, thanks to make, neither node_modules nor submodules will be installed i.e initialized/updated otherwise then when necessary (e.g only when package.json
is newer than the node_modules
i.e package-lock.json
file).
npm
)Development on MS Windows is not supported at the moment, but you may try by installing CygWin tools or similar (maybe?).
First build? You don't need to care about installing dependencies! Our build system does it for you.
Then, just run:
make
That's it.
Don't be afraid to call make
again! It is going to check thoroughly before acting and never going to do anything useless that wastes time.
You need to run make
at least once before to make sure 3rd-party binaries have been vendorized.
npm start
Go to http://localhost:8080/test-cases/web/
We support down to Node.js v8.10.0 and higher and are running our CI on v11.
We use ESlint and some plugins and parsers specificly for TS to get the job done really well. Some plain ES rules are disabled since they clash with some TS idioms.
npm run lint
// or
npm run lint-fix // auto-fixes lint errors
Pro tip: To omit warnings, run npm run lint -- --quiet
Runs all unit/integration tests under JEST:
npm test
See JEST documentation (or ./node_modules/.bin/jest --help
) to check how to constrain testing on spec file-paths or names.
multimedia
v0.x ?As of v0.8 of multimedia.js, the v0.x branch is not being maintained anymore (at least here). IT still works anyway fwiw :) Feel free to use it for the use-cases implemented. The last v0 release is here: https://github.com/tchakabam/multimedia.js/tree/b433e471c52cafb18308e859cf740acf3222521c or on NPM: (https://www.npmjs.com/package/multimedia)
FAQs
Multimedia streaming framework for browser and node
We found that @emliri/mmjs demonstrated a not healthy version release cadence and project activity because the last version was released a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Research
Security News
Socket researchers uncover a malicious npm package posing as a tool for detecting vulnerabilities in Etherium smart contracts.
Security News
Research
A supply chain attack on Rspack's npm packages injected cryptomining malware, potentially impacting thousands of developers.
Research
Security News
Socket researchers discovered a malware campaign on npm delivering the Skuld infostealer via typosquatted packages, exposing sensitive data.