{"id":19197339,"url":"https://github.com/versatica/mediasoup-client-aiortc","last_synced_at":"2025-04-04T20:08:13.485Z","repository":{"id":44092053,"uuid":"240497700","full_name":"versatica/mediasoup-client-aiortc","owner":"versatica","description":"mediasoup-client handler for aiortc Python library","archived":false,"fork":false,"pushed_at":"2025-03-24T19:23:44.000Z","size":1697,"stargazers_count":63,"open_issues_count":4,"forks_count":32,"subscribers_count":7,"default_branch":"v3","last_synced_at":"2025-03-28T19:08:09.774Z","etag":null,"topics":["client-library","nodejs","webrtc"],"latest_commit_sha":null,"homepage":"https://mediasoup.org","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"isc","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/versatica.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":".github/FUNDING.yml","license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null},"funding":{"github":null,"patreon":null,"open_collective":"mediasoup","ko_fi":null,"tidelift":null,"community_bridge":null,"liberapay":null,"issuehunt":null,"otechie":null,"lfx_crowdfunding":null,"custom":null}},"created_at":"2020-02-14T11:55:04.000Z","updated_at":"2025-03-24T19:23:47.000Z","dependencies_parsed_at":"2022-07-28T23:09:38.095Z","dependency_job_id":"635901f8-2968-409f-b45c-e309a75bad05","html_url":"https://github.com/versatica/mediasoup-client-aiortc","commit_stats":{"total_commits":304,"total_committers":5,"mean_commits":60.8,"dds":"0.24342105263157898","last_synced_commit":"bbc01874d928d41ee8c0d50519a80185e4d16f40"},"previous_names":[],"tags_count":43,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/versatica%2Fmediasoup-client-aiortc","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/versatica%2Fmediasoup-client-aiortc/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/versatica%2Fmediasoup-client-aiortc/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/versatica%2Fmediasoup-client-aiortc/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/versatica","download_url":"https://codeload.github.com/versatica/mediasoup-client-aiortc/tar.gz/refs/heads/v3","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247242678,"owners_count":20907134,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["client-library","nodejs","webrtc"],"created_at":"2024-11-09T12:16:24.916Z","updated_at":"2025-04-04T20:08:13.461Z","avatar_url":"https://github.com/versatica.png","language":"TypeScript","funding_links":["https://opencollective.com/mediasoup","https://opencollective.com/mediasoup/"],"categories":[],"sub_categories":[],"readme":"# mediasoup-client-aiortc\n\n[![][npm-shield-mediasoup-client-aiortc]][npm-mediasoup-client-aiortc]\n[![][github-actions-shield-mediasoup-client-aiortc]][github-actions-mediasoup-client-aiortc]\n[![][opencollective-shield-mediasoup]][opencollective-mediasoup]\n\n[mediasoup-client](https://github.com/versatica/mediasoup-client/) handler for [aiortc](https://github.com/aiortc/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.\n\n## Requirements\n\n- Python 3.\n- Windows not supported.\n\n## Installation\n\nInstall **mediasoup-client-aiortc** within your Node.js application:\n\n```bash\nnpm install mediasoup-client-aiortc\n```\n\nThe \"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:\n\n```bash\nPYTHON=/home/me/bin/python3.13 npm install mediasoup-client-aiortc\n```\n\nSame 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:\n\n```bash\nPYTHON=/home/me/bin/python3.13 node my_app.js\n```\n\n## API\n\n```javascript\n// ES6 style.\nimport {\n\tcreateWorker,\n\tWorker,\n\tWorkerSettings,\n\tWorkerLogLevel,\n\tAiortcMediaStream,\n\tAiortcMediaStreamConstraints,\n\tAiortcMediaTrackConstraints,\n} from 'mediasoup-client-aiortc';\n\n// CommonJS style.\nconst {\n\tcreateWorker,\n\tWorker,\n\tWorkerSettings,\n\tWorkerLogLevel,\n\tAiortcMediaStream,\n\tAiortcMediaStreamConstraints,\n\tAiortcMediaTrackConstraints,\n} = require('mediasoup-client-aiortc');\n```\n\n### `async createWorker(settings: WorkerSettings)` function\n\nCreates a **mediasoup-client-aiortc** `Worker` instance. Each `Worker` spawns and manages a Python subprocess.\n\n\u003e `@async`\n\u003e\n\u003e `@returns` Worker\n\n```typescript\nconst worker = await createWorker({\n\tlogLevel: 'warn',\n});\n```\n\n### `Worker` class\n\nThe `Worker` class. It represents a separate Python subprocess that can provide the Node.js application with audio/video tracks and **mediasoup-client** `handlers`.\n\n#### `worker.pid` getter\n\nThe Python subprocess PID.\n\n\u003e `@type` String, read only\n\n#### `worker.closed` getter\n\nWhether the subprocess is closed.\n\n#### `worker.died` getter\n\nWhether the subprocess died unexpectedly (probably a bug somewhere).\n\n#### `worker.subprocessClosed` getter\n\nWhether the subprocessed is closed. It becomes `true` once the worker subprocess is completely closed and 'subprocessclose' event fires.\n\n\u003e `@type` Boolean, read only\n\n#### `worker.close()` method\n\nCloses the subprocess and all its open resources (such as audio/video tracks and **mediasoup-client** handlers).\n\n#### `async worker.getUserMedia(constraints: AiortcMediaStreamConstraints)` method\n\nMimics 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.\n\n\u003e `@async`\n\u003e\n\u003e `@returns` AiortcMediaStream\n\n```typescript\nconst stream = await getUserMedia({\n\taudio: true,\n\tvideo: {\n\t\tsource: 'file',\n\t\tfile: 'file:///home/foo/media/foo.mp4',\n\t},\n});\n\nconst audioTrack = stream.getAudioTracks()[0];\nconst videoTrack = stream.getVideoTracks()[0];\n```\n\n#### `async worker.createHandlerFactory()` method\n\nCreates a **mediasoup-client** handler factory, suitable for the [handlerFactory](https://mediasoup.org/documentation/v3/mediasoup-client/api/#Device-dictionaries) argument when instantiating a mediasoup-client [Device](https://mediasoup.org/documentation/v3/mediasoup-client/api/#mediasoupClient-Device).\n\n\u003e `@async`\n\u003e\n\u003e `@returns` HandlerFactory\n\n```typescript\nconst device = new mediasoupClient.Device({\n\thandlerFactory: worker.createHandlerFactory(),\n});\n```\n\nNote that all Python resources (such as audio/video) used within the `Device` must be obtained from the same **mediasoup-client-aiortc** `Worker` instance.\n\n#### `worker.on(\"died\", fn(error: Error)` event\n\nEmitted if the subprocess abruptly dies. This should not happen. If it happens there is a bug in the Python component.\n\n#### `worker.on(\"subprocessclose\", fn())` event\n\nEmitted 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).\n\n\u003cdiv markdown=\"1\" class=\"note\"\u003e\nAwait for this event if you can to be sure that no Node handler is still open/running after you close a worker.\n\u003c/div\u003e\n\n### `WorkerSettings` type\n\n```typescript\ntype WorkerSettings = {\n\t/**\n\t * Logging level for logs generated by the Python subprocess.\n\t */\n\tlogLevel?: WorkerLogLevel; // If unset it defaults to \"error\".\n};\n```\n\n### `WorkerLogLevel` type\n\n```typescript\ntype WorkerLogLevel = 'debug' | 'warn' | 'error' | 'none';\n```\n\nLogs generated by both, Node.js and Python components of this module, are printed using the mediasoup-client [debugging](https://mediasoup.org/documentation/v3/mediasoup-client/debugging/) system with \"mediasoup-client-aiortc\" prefix/namespace.\n\n### `AiortcMediaStream` class\n\nA custom implementation of the [W3C MediaStream](https://www.w3.org/TR/mediacapture-streams/#mediastream) class. An instance of `AiortcMediaStream` is generated by calling `worker.getUserMedia()`.\n\nAudio and video tracks within an `AiortcMediaStream` are instances of [FakeMediaStreamTrack](https://github.com/ibc/fake-mediastreamtrack) and reference \"native\" `MediaStreamTracks` in the Python subprocess (handled by `aiortc` library).\n\n### `AiortcMediaStreamConstraints` type\n\nThe argument given to `worker.getUserMedia()`.\n\n```typescript\ntype AiortcMediaStreamConstraints = {\n\taudio?: AiortcMediaTrackConstraints | boolean;\n\tvideo?: AiortcMediaTrackConstraints | boolean;\n};\n```\n\nSetting `audio` or `video` to `true` equals to `{source: \"device\"}` (so default microphone or webcam will be used to obtain the track or tracks).\n\n### `AiortcMediaTrackConstraints` type\n\n```typescript\ntype AiortcMediaTrackConstraints = {\n\tsource: 'device' | 'file' | 'url';\n\tdevice?: string;\n\tfile?: string;\n\turl?: string;\n\tformat?: string;\n\toptions?: object;\n\ttimeout?: number;\n\tloop?: boolean;\n\tdecode?: boolean;\n};\n```\n\n#### `source`\n\nDetermines which source **aiortc** will use to generate the audio or video track. These are the possible values:\n\n- \"device\": System microphone or webcam.\n- \"file\": Path to a multimedia file in the system.\n- \"url\": URL of an HTTP stream.\n\n#### `device`\n\nIf `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.\n\n- Default values for `Darwin` platform:\n  - \"none:0\" for audio.\n  - \"default:none\" for video.\n- Default values for `Linux` platform:\n  - \"hw:0\" for audio.\n  - \"/dev/video0\" for video.\n\n#### `file`\n\nMandatory if `source` is \"file\". Must be the absolute path to a multimedia file.\n\n#### `url`\n\nMandatory if `source` is \"url\". Must be the URL of an HTTP stream.\n\n#### `format`\n\nSpecifies the device format used by `ffmpeg`.\n\n- Default values for `Darwin` platform:\n\n  - \"avfoundation\" for audio.\n  - \"avfoundation\" for video.\n\n- Default values for `Linux` platform:\n  - \"alsa\" for audio.\n  - \"v4f2\" for video.\n\n#### `options`\n\nSpecifies the device options used by `ffmpeg`.\n\n- Default values for `Darwin` platform:\n\n  - `{}` for audio.\n  - `{ framerate: \"30\", video_size: \"640x480\" }` for video.\n\n- Default values for `Linux` platform:\n  - `{}` for audio.\n  - `{ framerate: \"30\", video_size: \"640x480\" }` for video.\n\n#### `timeout`, `loop` and `decode`\n\nSee [documentation](https://aiortc.readthedocs.io/en/latest/helpers.html#media-sources) in **aiortc** site (`decode` option is not documented but you can figure it out by reading usage [examples](https://github.com/aiortc/aiortc/blob/main/examples/webcam/README.rst)).\n\n## Other considerations\n\n### DataChannel\n\n**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.\n\nWhen sending, `dataChannel.send()` (and hence `dataProducer.send()`) allows passing a string, a `Buffer` instance or an `ArrayBuffer` instance.\n\n## Development\n\n### Lint\n\n```bash\nnpm run lint\n```\n\n### Test\n\n```bash\nnpm run test\n```\n\n### Check release\n\n```bash\nnpm run release:check\n```\n\n### Make Python log to stdout/stderr while running tests\n\n```bash\nPYTHON_LOG_TO_STDOUT=true npm run test\n```\n\n## Caveats\n\nSee the list of [open issues](https://github.com/versatica/mediasoup-client-aiortc/issues).\n\n## Authors\n\n- José Luis Millán [[github](https://github.com/jmillan/)]\n- Iñaki Baz Castillo [[website](https://inakibaz.me)|[github](https://github.com/ibc/)]\n\n## License\n\n[ISC](./LICENSE)\n\n[npm-shield-mediasoup-client-aiortc]: https://img.shields.io/npm/v/mediasoup-client-aiortc.svg\n[npm-mediasoup-client-aiortc]: https://npmjs.org/package/mediasoup-client-aiortc\n[github-actions-shield-mediasoup-client-aiortc]: https://github.com/versatica/mediasoup-client-aiortc/actions/workflows/mediasoup-client-aiortc.yaml/badge.svg\n[github-actions-mediasoup-client-aiortc]: https://github.com/versatica/mediasoup-client-aiortc/actions/workflows/mediasoup-client.yaml\n[opencollective-shield-mediasoup]: https://img.shields.io/opencollective/all/mediasoup.svg\n[opencollective-mediasoup]: https://opencollective.com/mediasoup/\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fversatica%2Fmediasoup-client-aiortc","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fversatica%2Fmediasoup-client-aiortc","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fversatica%2Fmediasoup-client-aiortc/lists"}