Because the new version requires the transform to be handled from a worker,
and because of the negative implications of doing so on the window context,
we only provide the option of a Worker here. However, the user can supply
wrap / unwrap functions so that messages generated by this module can be
multiplexed with any other communications to/from that worker. This should
allow arbitrary worker lifecycle patterns (reusing a worker, using it to
handle multiple transforms, sharing it for other tasks, etc.).
The API has two sides; attachRtpScriptTransform is called from the local
(i.e. non worker) side, and gets passed a Worker object. This worker must have
called startRtpScriptTransformService to receive and handle the created
transformer. It is okay to pass a worker that hasn't yet started up, as
long as startRtpScriptTransformService is called in the initialization.
In addition to using these APIs, in case the old Encoded Transform APIs are
used, you need to pass encodedInsertableStreams: true in the configuration
object when creating the RTCPeerConnection.
// in this example we use a single worker for all processing for simplicity constrtcTransformWorker = newWorker(newURL('./worker.js', import.meta.url), { type:'module' })
constpeerConnection = newRTCPeerConnection({ // needed in case the old API is used encodedInsertableStreams:true, }) // TODO: establish connection with other peer and negotiate content
functiononNegotiationDone() { // attach filters to every receiver: for (consttransceiverofpeerConnection.getTransceivers()) { constoptions = { mid:transceiver.mid } // custom data to send with the created transformer attachRtpScriptTransform(transceiver.receiver, rtcTransformWorker, { options })) } }
startRtpScriptTransformService((transformer, options) => { console.log('Received a transformer for MID:', options.mid) // TODO: do something more interesting transformer.readable.pipeTo(transformer.writable) })
You can use isEncodedStreamSupported to test for availability of either
of the API versions supported by this method. If it succeeds, you may call
attachRtpScriptTransform. This is not required for the service side;
there's no problem in starting up a worker and calling
startRtpScriptTransformService even if the API is not available.
Note that attachRtpScriptTransform is synchronous and doesn't wait for
acknowledgment from the worker that the transformer has been received and
set up. This may happen much later, especially if the worker is busy or
still starting up. If you need this, send a message from the worker service
callback.
It is the caller's responsibility to:
adequately create the worker, and handle errors in its execution
make sure the worker service is started when receiving the next
posted message, and that exactly one instance of the service is started
make sure the worker is using the exact same version of
this library (there are no version checks for communications)
if the worker will send or receive other messages, ensure the provided
wrapping works correctly (doesn't conflict with other messages, and
wrapped messages get successfully detected & unwrapped at the other end)
Failure to meet any of these results in undefined behavior.
When compared to the base APIs, attachMetadataExtractor takes an extra
argument: a callback to be invoked for every received metadata frame.
For startMetadataExtractorService, the callback must return an 'extraction
function' to be invoked for each frame. The extraction function must return the
metadata object to send back to the main frame (together with the transfer list,
see MessageData), or undefined to send nothing for that frame.
Unless adequate wrapping is used, this API should never be mixed with the
basic API: a worker must not start both worker services at the same time;
attachMetadataExtractor may only be called on a worker that called
startMetadataExtractorService, and vice versa.
Provides a uniform API for both versions of WebRTC Insertable Streams, now officially called WebRTC Encoded Transform.
https://w3c.github.io/webrtc-encoded-transform
Because the new version requires the transform to be handled from a worker, and because of the negative implications of doing so on the window context, we only provide the option of a Worker here. However, the user can supply wrap / unwrap functions so that messages generated by this module can be multiplexed with any other communications to/from that worker. This should allow arbitrary worker lifecycle patterns (reusing a worker, using it to handle multiple transforms, sharing it for other tasks, etc.).
Basic usage
The API has two sides; attachRtpScriptTransform is called from the local (i.e. non worker) side, and gets passed a Worker object. This worker must have called startRtpScriptTransformService to receive and handle the created transformer. It is okay to pass a worker that hasn't yet started up, as long as startRtpScriptTransformService is called in the initialization.
In addition to using these APIs, in case the old Encoded Transform APIs are used, you need to pass
encodedInsertableStreams: true
in the configuration object when creating theRTCPeerConnection
.Basic example:
API availability
You can use isEncodedStreamSupported to test for availability of either of the API versions supported by this method. If it succeeds, you may call attachRtpScriptTransform. This is not required for the service side; there's no problem in starting up a worker and calling startRtpScriptTransformService even if the API is not available.
Considerations
Note that attachRtpScriptTransform is synchronous and doesn't wait for acknowledgment from the worker that the transformer has been received and set up. This may happen much later, especially if the worker is busy or still starting up. If you need this, send a message from the worker service callback.
It is the caller's responsibility to:
adequately create the worker, and handle errors in its execution
make sure the worker service is started when receiving the next posted message, and that exactly one instance of the service is started
make sure the worker is using the exact same version of this library (there are no version checks for communications)
if the worker will send or receive other messages, ensure the provided wrapping works correctly (doesn't conflict with other messages, and wrapped messages get successfully detected & unwrapped at the other end)
Failure to meet any of these results in undefined behavior.
Metadata extraction
For convenience, an alternative pair of functions is provided that also handle:
These are attachMetadataExtractor and startMetadataExtractorService.
When compared to the base APIs, attachMetadataExtractor takes an extra argument: a callback to be invoked for every received metadata frame. For startMetadataExtractorService, the callback must return an 'extraction function' to be invoked for each frame. The extraction function must return the metadata object to send back to the main frame (together with the transfer list, see MessageData), or
undefined
to send nothing for that frame.Unless adequate wrapping is used, this API should never be mixed with the basic API: a worker must not start both worker services at the same time; attachMetadataExtractor may only be called on a worker that called startMetadataExtractorService, and vice versa.