Skip to content

Commit

Permalink
fix: lint warnings
Browse files Browse the repository at this point in the history
  • Loading branch information
steabert committed Apr 4, 2021
1 parent 6422bd6 commit 7f5524a
Show file tree
Hide file tree
Showing 38 changed files with 351 additions and 295 deletions.
40 changes: 21 additions & 19 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -82,42 +82,44 @@ Alternatively, you can import it into your javascript code if you bundle it your
import {components, pipelines} from 'media-stream-library';
```

Note that we expose our own bundle as the default entry point.
This is to avoid issues where you would have to write fallback
imports for browserify packages if using webpack 5.
Note that we expose our own bundle as the default entry point. This is to avoid
issues where you would have to write fallback imports for browserify packages if
using webpack 5.

If you want the smallest possible bundle, you can import directly from
`media-stream-library/dist/esm/index.browser.js` and then make sure
to properly resolve everything in your own webpack config (you can
check our own `webpack.config.js` as en example how to write fallbacks
for the browserify packages).
`media-stream-library/dist/esm/index.browser.js` and then make sure to properly
resolve everything in your own webpack config (you can check our own
`webpack.config.js` as en example how to write fallbacks for the browserify
packages).

### Components and pipelines

The library contains a collection of components that can be connected
together to form media pipelines.
The components are a low-level abstraction on top of Node streams to allow two-way
communication, while media pipelines are sets of connected components with methods
that allow you to control the pipeline, and easily add/remove components.
The library contains a collection of components that can be connected together
to form media pipelines. The components are a low-level abstraction on top of
Node streams to allow two-way communication, while media pipelines are sets of
connected components with methods that allow you to control the pipeline, and
easily add/remove components.

Components can be categorized as:

- sources (socket, file, ...)
- transforms (parsers, depay, muxers, ...)
- sinks (HTML5 element, file, ...)

To build a pipeline, you can connect the required components.
A number common pipelines are exported directly for convenience.
To build a pipeline, you can connect the required components. A number of common
pipelines are exported directly for convenience.

Check the `examples` section to see how these can be used in your own code.
To run the examples yourself, you'll need to clone this repository loccally
and follow the developer instructions.
Check the `examples` section to see how these can be used in your own code. To
run the examples yourself, you'll need to clone this repository loccally and
follow the developer instructions.

## Debugging

In the browser, you can set `localStorage.debug = 'msl:*'` to log everything
related to just this library (make sure to reload the page after setting the value).
related to just this library (make sure to reload the page after setting the
value).

## Contributing

Please read our [contributing guidelines](CONTRIBUTING.md) before making pull requests.
Please read our [contributing guidelines](CONTRIBUTING.md) before making pull
requests.
13 changes: 1 addition & 12 deletions lib/components/canvas/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -70,8 +70,6 @@ const generateUpdateInfo = (clockrate: number) => {
* - onSync: will be called when the presentation time offset is
* known, with the latter as argument (in UNIX milliseconds)
*
* @class CanvasComponent
* @extends {Component}
*/
export class CanvasSink extends Sink {
public onCanplay?: () => void
Expand All @@ -80,9 +78,7 @@ export class CanvasSink extends Sink {
private _scheduler: Scheduler<BlobMessage>
private _info: RateInfo
/**
* Creates an instance of CanvasComponent.
* @param { HTMLCanvasElement } el - An HTML < canvas > element
* @memberof CanvasComponent
* @param el - The <canvas> element to draw incoming JPEG messages on.
*/
constructor(el: HTMLCanvasElement) {
if (el === undefined) {
Expand Down Expand Up @@ -271,18 +267,13 @@ export class CanvasSink extends Sink {

/**
* Retrieve the current presentation time (seconds)
*
* @readonly
* @memberof CanvasComponent
*/
get currentTime() {
return this._clock.currentTime
}

/**
* Pause the presentation.
*
* @memberof CanvasComponent
*/
pause() {
this._scheduler.suspend()
Expand All @@ -291,8 +282,6 @@ export class CanvasSink extends Sink {

/**
* Start the presentation.
*
* @memberof CanvasComponent
*/
play() {
this._clock.play()
Expand Down
111 changes: 82 additions & 29 deletions lib/components/component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,43 +6,76 @@ export type Component = Source | Tube | Sink

type ErrorEventHandler = (err: Error) => void

/**
* Component
*
* A component is a set of bi-directional streams consisting of an 'incoming'
* and 'outgoing' stream.
*
* They contain references to other components so they can form a linked list of
* components, i.e. a pipeline. When linking components, the incoming and
* outgoing streams are piped, so that data flowing through the incoming stream
* is transfered to the next component, and data in the outgoing stream flows
* to the previous component.
*
* Components at the end of such a pipeline typically connect the incoming and
* outgoing streams to a data source or data sink.
*
* Typically, for a component that is connected to two other components, both
* incoming and outgoing will be Transform streams. For a source, 'incoming'
* will be a Readable stream and 'outgoing' a Writable stream, while for a sink
* it is reversed. Both source and sink could also use a single Duplex stream,
* with incoming === outgoing.
*
* server end-point client end-point
* /------------- ----------------- -------------\
* | Writable | <- | Transform | <- | Readable |
* | source | | tube | | sink |
* | Readable | -> | Transform | -> | Writable |
* \------------- ----------------- -------------/
*/
abstract class AbstractComponent {
/**
* The stream going towards the client end-point
*/
public abstract incoming: Stream
/**
* The stream going back to the server end-point
*/
public abstract outgoing: Stream
/**
* The next component (downstream, towards the client)
*/
public abstract next: Tube | Sink | null
/**
* The previous component (upstream, towards the server)
*/
public abstract prev: Tube | Source | null
protected _incomingErrorHandler?: ErrorEventHandler
protected _outgoingErrorHandler?: ErrorEventHandler
/**
* Connect a downstream component (towards the client)
*/
public abstract connect(next: Tube | Sink | null): Component
public abstract disconnect(): Component

/**
* Create a component, i.e. a set of bi-directional streams consisting of
* an 'incoming' and 'outgoing' stream to handle two-way communication with
* other components.
* @param {Stream} incoming - The stream going towards the client end-point.
* @param {Stream} outgoing - The stream going back to the server end-point.
*
* Typically, for a component that is connected to two other components, both
* incoming and outgoing will be Transform streams. For a source, 'incoming'
* will be a Readable stream and 'outgoing' a Writable stream, while for a sink
* it is reversed. Both source and sink could also use a single Duplex stream,
* with incoming === outgoing.
*
* server end-point client end-point
* /------------- ----------------- -------------\
* | Writable | <- | Transform | <- | Readable |
* | source | | tube | | sink |
* | Readable | -> | Transform | -> | Writable |
* \------------- ----------------- -------------/
* Disconnect a downstream component downstream (towards the client)
*/
public abstract disconnect(): Component
}

/**
* Source component
*
* A component that can only have a next component connected (no previous) and
* where the incoming and outgoing streams are connected to an external data
* source.
*/
export class Source extends AbstractComponent {
/**
* Set up a component that emits incoming messages.
* @param {Array} messages List of objects (with data property) to emit.
* @return {Component}
* Set up a source component that has a message list as data source.
*
* @param messages - List of objects (with data property) to emit on the
* incoming stream
*/
public static fromMessages(messages: GenericMessage[]) {
const component = new Source(
Expand Down Expand Up @@ -74,8 +107,8 @@ export class Source extends AbstractComponent {
* next component 'down' stream and the 'up' stream of the other component
* flows into the 'up' stream of this component. This is what establishes the
* meaning of 'up' and 'down'.
* @param {Component} next - The component to connect.
* @return {Component} - A reference to the connected component.
* @param next - The component to connect.
* @return A reference to the connected component.
*
* -------------- pipe --------------
* <- | outgoing | <- | outgoing | <-
Expand Down Expand Up @@ -163,7 +196,20 @@ export class Source extends AbstractComponent {
}
}

/**
* Tube component
*
* A component where both incoming and outgoing streams are Duplex streams, and
* can be connected to a previous and next component, typically in the middle of
* a pipeline.
*/
export class Tube extends Source {
/**
* Create a component that calls a handler function for each message passing
* through, but otherwise just passes data through.
*
* Can be used to log messages passing through a pipeline.
*/
public static fromHandlers(
fnIncoming: MessageHandler | undefined,
fnOutgoing: MessageHandler | undefined,
Expand Down Expand Up @@ -191,12 +237,19 @@ export class Tube extends Source {
}
}

/**
* Sink component
*
* A component that can only have a previous component connected (no next) and
* where the incoming and outgoing streams are connected to an external data
* source.
*/
export class Sink extends AbstractComponent {
/**
* Set up a component that swallows incoming data (calling fn on it).
* To print data, you would use fn = console.log.
* @param {Function} fn The callback to use for the incoming data.
* @return {Component}
* Create a component that swallows incoming data (calling fn on it). To
* print data, you would use fn = console.log.
*
* @param fn - The callback to use for the incoming data.
*/
public static fromHandler(fn: MessageHandler) {
const component = new Sink(
Expand Down
4 changes: 2 additions & 2 deletions lib/components/helpers/sleep.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
/**
* Return a promise that resolves after a specific time.
* @param {Number} ms Waiting time in milliseconds
* @return {Promise} Resolves after waiting time
* @param ms Waiting time in milliseconds
* @return Resolves after waiting time
*/
export const sleep = (ms: number) => {
return new Promise((resolve) => {
Expand Down
8 changes: 4 additions & 4 deletions lib/components/helpers/stream-factory.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ export default class StreamFactory {
/**
* Creates a writable stream that sends all messages written to the stream
* to a callback function and then considers it written.
* @param {Function} fn The callback to be invoked on the message
* @param fn The callback to be invoked on the message
*/
public static consumer(
fn: (msg: any) => void = () => {
Expand All @@ -13,7 +13,7 @@ export default class StreamFactory {
) {
return new Writable({
objectMode: true,
write(msg, encoding, callback) {
write(msg, _encoding, callback) {
fn(msg)
callback()
},
Expand All @@ -26,7 +26,7 @@ export default class StreamFactory {
}
return new Transform({
objectMode: true,
transform(msg, encoding, callback) {
transform(msg, _encoding, callback) {
fn(msg)
callback(undefined, msg)
},
Expand All @@ -35,7 +35,7 @@ export default class StreamFactory {

/**
* Creates a readable stream that sends a message for each element of an array.
* @param {Array} arr The array with elements to be turned into a stream.
* @param arr The array with elements to be turned into a stream.
*/
public static producer(messages?: any[]) {
let counter = 0
Expand Down
4 changes: 2 additions & 2 deletions lib/components/mp4-parser/parser.ts
Original file line number Diff line number Diff line change
Expand Up @@ -121,8 +121,8 @@ export class Parser {
* Add the next chunk of data to the parser and extract messages.
* If no message can be extracted, an empty array is returned, otherwise
* an array of messages is returned.
* @param {Buffer} chunk The next piece of data.
* @return {Array} An array of messages, possibly empty.
* @param chunk - The next piece of data.
* @return An array of messages, possibly empty.
*/
parse(chunk: Buffer): IsomMessage[] {
this._push(chunk)
Expand Down
4 changes: 2 additions & 2 deletions lib/components/mp4capture/index.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,8 +42,8 @@ const copySpies = (type: MessageType, messages: GenericMessage[]) => {

/**
* Set up a pipeline: source - capture - sink.
* @param {Array} fragments Messages to send from source.
* @return {Object} Components and function to start flow.
* @param fragments - Messages to send from source.
* @return Components and function to start flow.
*/
const pipelineFactory = (...fragments: GenericMessage[][]) => {
const sourceMessages = ([] as GenericMessage[]).concat(...fragments)
Expand Down
3 changes: 1 addition & 2 deletions lib/components/mp4capture/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -71,8 +71,7 @@ export class Mp4Capture extends Tube {
* termination, the callback you passed will be called with the captured
* data as argument.
* @public
* @param {Function} callback Will be called when data is captured.
* @return {undefined}
* @param callback Will be called when data is captured.
*/
start(callback: (buffer: Buffer) => void) {
if (!this._active) {
Expand Down
14 changes: 7 additions & 7 deletions lib/components/mp4muxer/helpers/boxbuilder.ts
Original file line number Diff line number Diff line change
Expand Up @@ -129,9 +129,9 @@ export class BoxBuilder {
/**
* Creates a Moov box from the provided options.
* @method moov
* @param {Object} mvhdSettings settings for the movie header box
* @param {Object[]} tracks track specific settings
* @return {Moov} Moov object
* @param sdp - The session description protocol
* @param date - The creation/modification time of the movie
* @return Moov object
*/
moov(sdp: Sdp, date: any) {
const moov = new Container('moov')
Expand Down Expand Up @@ -205,8 +205,8 @@ export class BoxBuilder {
/**
* Creates a moof box from the provided fragment metadata.
* @method moof
* @param {Object} options options containing, sequencenumber, base time, trun settings, samples
* @return {Moof} Moof object
* @param metadata - Track ID, timestamp, bytelength
* @return moof Container
*/
moof(metadata: MoofMetadata) {
const { trackId, timestamp, byteLength } = metadata
Expand Down Expand Up @@ -254,8 +254,8 @@ export class BoxBuilder {

/**
* Creates an mdat box containing the elementary stream data.
* @param {[type]} data [description]
* @return [type] [description]
* @param data - Elementary stream data
* @return mdat Box
*/
mdat(data: Buffer) {
const box = new Box('mdat')
Expand Down
Loading

0 comments on commit 7f5524a

Please sign in to comment.