mediasoup-client handler for aiortc Python library. Suitable for building Node.js applications that connect to a mediasoup server using WebRTC and exchange real audio, video and DataChannel messages with it in both directions.
Install mediasoup-client-aiortc within your Node.js application:
npm install mediasoup-client-aiortc
The "postinstall" script in package.json
will install the Python libraries (including aiortc). You can override the path to python
executable by setting the PYTHON
environment variable:
PYTHON=/home/me/bin/python3.13 npm install mediasoup-client-aiortc
Same once you run your Node.js application. mediasoup-client-aiortc will spawn Python processes and communicate with them via UnixSocket
. You can override the python
executable path by setting the PYTHON
environment variable:
PYTHON=/home/me/bin/python3.13 node my_app.js
// ES6 style.
import {
createWorker,
Worker,
WorkerSettings,
WorkerLogLevel,
AiortcMediaStream,
AiortcMediaStreamConstraints,
AiortcMediaTrackConstraints,
} from 'mediasoup-client-aiortc';
// CommonJS style.
const {
createWorker,
Worker,
WorkerSettings,
WorkerLogLevel,
AiortcMediaStream,
AiortcMediaStreamConstraints,
AiortcMediaTrackConstraints,
} = require('mediasoup-client-aiortc');
async createWorker(settings: WorkerSettings)
functionCreates a mediasoup-client-aiortc Worker
instance. Each Worker
spawns and manages a Python subprocess.
@async
@returns
Worker
const worker = await createWorker({
logLevel: 'warn',
});
Worker
classThe Worker
class. It represents a separate Python subprocess that can provide the Node.js application with audio/video tracks and mediasoup-client handlers
.
worker.pid
getterThe Python subprocess PID.
@type
String, read only
worker.closed
getterWhether the subprocess is closed.
worker.died
getterWhether the subprocess died unexpectedly (probably a bug somewhere).
worker.subprocessClosed
getterWhether the subprocessed is closed. It becomes true
once the worker subprocess is completely closed and 'subprocessclose' event fires.
@type
Boolean, read only
worker.close()
methodCloses the subprocess and all its open resources (such as audio/video tracks and mediasoup-client handlers).
async worker.getUserMedia(constraints: AiortcMediaStreamConstraints)
methodMimics the navigator.getUserMedia()
API. It creates an AiortcMediaStream
instance containing audio and/or video tracks. Those tracks can point to different sources such as device microphone, webcam, multimedia files or HTTP streams.
@async
@returns
AiortcMediaStream
const stream = await getUserMedia({
audio: true,
video: {
source: 'file',
file: 'file:///home/foo/media/foo.mp4',
},
});
const audioTrack = stream.getAudioTracks()[0];
const videoTrack = stream.getVideoTracks()[0];
async worker.createHandlerFactory()
methodCreates a mediasoup-client handler factory, suitable for the handlerFactory argument when instantiating a mediasoup-client Device.
@async
@returns
HandlerFactory
const device = new mediasoupClient.Device({
handlerFactory: worker.createHandlerFactory(),
});
Note that all Python resources (such as audio/video) used within the Device
must be obtained from the same mediasoup-client-aiortc Worker
instance.
worker.on("died", fn(error: Error)
eventEmitted if the subprocess abruptly dies. This should not happen. If it happens there is a bug in the Python component.
worker.on("subprocessclose", fn())
eventEmitted when the subprocess has closed completely. This event is emitted asynchronously once worker.close()
has been called (or after 'died' event in case the worker subprocess abnormally died).
WorkerSettings
typetype WorkerSettings = {
/**
* Logging level for logs generated by the Python subprocess.
*/
logLevel?: WorkerLogLevel; // If unset it defaults to "error".
};
WorkerLogLevel
typetype WorkerLogLevel = 'debug' | 'warn' | 'error' | 'none';
Logs generated by both, Node.js and Python components of this module, are printed using the mediasoup-client debugging system with "mediasoup-client-aiortc" prefix/namespace.
AiortcMediaStream
classA custom implementation of the W3C MediaStream class. An instance of AiortcMediaStream
is generated by calling worker.getUserMedia()
.
Audio and video tracks within an AiortcMediaStream
are instances of FakeMediaStreamTrack and reference "native" MediaStreamTracks
in the Python subprocess (handled by aiortc
library).
AiortcMediaStreamConstraints
typeThe argument given to worker.getUserMedia()
.
type AiortcMediaStreamConstraints = {
audio?: AiortcMediaTrackConstraints | boolean;
video?: AiortcMediaTrackConstraints | boolean;
};
Setting audio
or video
to true
equals to {source: "device"}
(so default microphone or webcam will be used to obtain the track or tracks).
AiortcMediaTrackConstraints
typetype AiortcMediaTrackConstraints = {
source: 'device' | 'file' | 'url';
device?: string;
file?: string;
url?: string;
format?: string;
options?: object;
timeout?: number;
loop?: boolean;
decode?: boolean;
};
source
Determines which source aiortc will use to generate the audio or video track. These are the possible values:
device
If source
is "device" and this field is given, it specifies the device ID of the microphone or webcam to use. If unset, the default one in the system will be used.
Darwin
platform:
Linux
platform:
file
Mandatory if source
is "file". Must be the absolute path to a multimedia file.
url
Mandatory if source
is "url". Must be the URL of an HTTP stream.
format
Specifies the device format used by ffmpeg
.
Default values for Darwin
platform:
Default values for Linux
platform:
options
Specifies the device options used by ffmpeg
.
Default values for Darwin
platform:
{}
for audio.{ framerate: "30", video_size: "640x480" }
for video.Default values for Linux
platform:
{}
for audio.{ framerate: "30", video_size: "640x480" }
for video.timeout
, loop
and decode
See documentation in aiortc site (decode
option is not documented but you can figure it out by reading usage examples).
mediasoup-client-aiortc supports sending/receiving string and binary DataChannel messages. However, due to the lack of Blob
support in Node.js, dataChannel.binaryType
is always "arraybuffer" so received binary messages are always ArrayBuffer
instances.
When sending, dataChannel.send()
(and hence dataProducer.send()
) allows passing a string, a Buffer
instance or an ArrayBuffer
instance.
npm run lint
npm run test
npm run release:check
PYTHON_LOG_TO_STDOUT=true npm run test
See the list of open issues.