{"id":13399729,"url":"https://github.com/mscdex/sipster","last_synced_at":"2025-11-07T18:03:44.374Z","repository":{"id":14813001,"uuid":"17535431","full_name":"mscdex/sipster","owner":"mscdex","description":"A pjsip/pjsua2 binding for node.js","archived":false,"fork":false,"pushed_at":"2016-10-19T02:05:42.000Z","size":96,"stargazers_count":189,"open_issues_count":23,"forks_count":47,"subscribers_count":17,"default_branch":"master","last_synced_at":"2024-04-14T15:18:56.407Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"C++","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/mscdex.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2014-03-08T04:56:10.000Z","updated_at":"2024-03-28T07:32:24.000Z","dependencies_parsed_at":"2022-08-26T07:11:15.257Z","dependency_job_id":null,"html_url":"https://github.com/mscdex/sipster","commit_stats":null,"previous_names":[],"tags_count":6,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mscdex%2Fsipster","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mscdex%2Fsipster/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mscdex%2Fsipster/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mscdex%2Fsipster/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/mscdex","download_url":"https://codeload.github.com/mscdex/sipster/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":233283692,"owners_count":18652865,"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":[],"created_at":"2024-07-30T19:00:42.004Z","updated_at":"2025-11-07T18:03:44.265Z","avatar_url":"https://github.com/mscdex.png","language":"C++","funding_links":[],"categories":["C++"],"sub_categories":[],"readme":"Description\n===========\n\nA [pjsip](http://www.pjsip.org) (or more accurately a [pjsua2](http://www.pjsip.org/docs/book-latest/html/index.html)) binding for node.js.\n\nFamiliarity with pjsip/pjsua2 is a plus when using this binding.\n\n\nRequirements\n============\n\n* Non-Windows OS\n* [pjsip](http://www.pjsip.org/) -- v2.4.5 or newer\n* [node.js](http://nodejs.org/) -- v0.10 or newer\n\n\nInstall\n=======\n\n    npm install sipster\n\n\nExamples\n========\n\n* UAS set up as a SIP trunk (no registration):\n\n```javascript\nvar sipster = require('sipster');\n\n// initialize pjsip\nsipster.init();\n\n// set up a transport to listen for incoming connections, defaults to UDP\nvar transport = new sipster.Transport({ port: 5060 });\n\n// set up a SIP account, we need at least one -- as required by pjsip.\n// this sets up an account for calls coming from 192.168.100.10\nvar acct = new sipster.Account({\n  idUri: 'sip:192.168.100.10'\n});\n\n// watch for incoming calls\nacct.on('call', function(info, call) {\n  console.log('=== Incoming call from ' + info.remoteContact);\n\n  // watch for call state changes\n  call.on('state', function(state) {\n    console.log('=== Call state is now: ' + state.toUpperCase());\n  });\n\n  // listen for DTMF digits\n  call.on('dtmf', function(digit) {\n    console.log('=== DTMF digit received: ' + digit);\n  });\n\n  // audio stream(s) available\n  call.on('media', function(medias) {\n    // play looping .wav file to the first audio stream\n    var player = sipster.createPlayer('sound.wav');\n    player.startTransmitTo(medias[0]);\n\n    // record the audio of the other side, this will not include the audio from\n    // the player above.\n    var recorder = sipster.createRecorder('call.wav');\n    medias[0].startTransmitTo(recorder);\n    // to include the player audio, you can mix the sources together simply\n    // by transmitting to the same recorder:\n    //   player.startTransmitTo(recorder);\n  });\n\n  // answer the call (with default 200 OK)\n  call.answer();\n});\n\n// finalize the pjsip initialization phase ...\nsipster.start();\n```\n\n\nAPI\n===\n\nExported static methods\n-----------------------\n\n* **init**([\u003c _object_ \u003eendpointCfg]) - _(void)_ - Starts the initializion of the pjsip library (`libInit()`). This is to be done only once. `endpointCfg` is an [EpConfig](http://www.pjsip.org/pjsip/docs/html/structpj_1_1EpConfig.htm)-like object for if you need to change any global options from the library defaults.\n\n* **start**() - _(void)_ - Finalizes the initialization of the pjsip library (`libStart()`). This is generally called once you've got everything configured and set up.\n\n* **hangupAllCalls**() - _(void)_ - Hangs up all existing calls.\n\n* **createRecorder**(\u003c _string_ \u003efilename[, \u003c _string_ \u003eformat[, \u003c _integer_ \u003emaxSize]]) - _Media_ - Creates an audio recorder that writes to the given `filename`. `format` can be one of 'ulaw', 'alaw', or 'pcm' (default is 'ulaw'). `maxSize` is the maximum file size (default is no limit).\n\n* **createPlayer**(\u003c _string_ \u003efilename[, \u003c _boolean_ \u003enoLoop]) - _Media_ - Creates an audio player that reads from `filename`. Set `noLoop` to true to disable looping of the audio. When `noLoop` is true, an 'eof' event will be emitted on the Media object when it reaches the end of playback.\n\n* **createPlaylist**(\u003c _array_ \u003efilenames[, \u003c _boolean_ \u003enoLoop]) - _Media_ - Creates an audio player that sequentially reads from the list of `filenames`. Set `noLoop` to true to disable looping of the playlist. When `noLoop` is true, an 'eof' event will be emitted on the Media object when it reaches the end of the playlist.\n\n\nExported properties\n-------------------\n\n* **version** - _object_ - (Read-only) Contains information about the pjsip library version (`libVersion()`):\n    * **major** - _integer_ - The major number.\n    * **minor** - _integer_ - The minor number.\n    * **rev** - _integer_ - The additional revision number.\n    * **suffix** - _string_ - The version suffix (e.g. '-svn').\n    * **full** - _string_ - The concatenation of `major`, `minor`, `rev`, and `suffix` (e.g. '2.2.1-svn').\n    * **numeric** - _integer_ - The `major`, `minor`, and `rev` as a single integer in the form 0xMMIIRR00 where MM is `major`, II is `minor`, and RR is `rev`.\n\n* **config** - _object_ - (Read-only) Returns the **entire** current (EpConfig) config for pjsip.\n\n* **state** - _string_ - (Read-only) Returns the state of the library/endpoint (`libGetState()`). For example: 'created', 'init', 'starting', 'running', or 'closing'.\n\n* **mediaActivePorts** - _integer_ - (Read-only) Returns the total number of active Media ports.\n\n* **mediaMaxPorts** - _integer_ - (Read-only) Returns the maximum number of Media ports permitted.\n\nAdditionally any needed pjsip library constants (may be needed when creating and passing in config objects) are exported as well.\n\n\nExported types\n--------------\n\n* **Transport** - Represents an underlying (network) interface that Calls and Accounts use.\n\n* **Account** - An entity used for identification purposes for incoming or outgoing requests.\n\n\nTransport methods\n-----------------\n\n* **(constructor)**([\u003c _object_ \u003etransportConfig]) - Creates and returns a new, enabled Transport instance. `transportConfig` is a [TransportConfig](http://www.pjsip.org/pjsip/docs/html/structpj_1_1TransportConfig.htm)-like object for if you need to change any transport options from the library defaults.\n\n* **unref**() - _(void)_ - Detaches the Transport from the event loop.\n\n* **ref**() - _(void)_ - Attaches the Transport to the event loop (default upon instantiation).\n\n* **getInfo**() - _object_ - Returns information (`TransportInfo`) about the transport:\n    * **type** - _string_ - Transport type name.\n    * **info** - _string_ - Transport string info/description.\n    * **flags** - _integer_ - Transport flags (e.g. PJSIP_TRANSPORT_RELIABLE, PJSIP_TRANSPORT_SECURE, PJSIP_TRANSPORT_DATAGRAM).\n    * **localAddress** - _string_ - Local/bound address.\n    * **localName** - _string_ - Published address.\n    * **usageCount** - _integer_ - Current number of objects currently referencing this transport.\n\n* **disable**() - _(void)_ - Disables the transport. Disabling a transport does not necessarily close the socket, it will only discard incoming messages and prevent the transport from being used to send outgoing messages.\n\n* **enable**() - _(void)_ - Enables the transport. Transports are automatically enabled upon creation, so you don't need to call this method unless you explicitly disable the transport first.\n\n\nTransport properties\n--------------------\n\n* **enabled** - _boolean_ - (Read-only) Indicates if the transport is currently enabled or not.\n\n\nAccount methods\n---------------\n\n* **(constructor)**(\u003c _object_ \u003eaccountConfig) - Creates and returns a new Account instance. `accountConfig` is an [AccountConfig](http://www.pjsip.org/pjsip/docs/html/structpj_1_1AccountConfig.htm)-like object.\n\n* **unref**() - _(void)_ - Detaches the Account from the event loop.\n\n* **ref**() - _(void)_ - Attaches the Account to the event loop (default upon instantiation).\n\n* **modify**(\u003c _object_ \u003eaccountConfig) - _(void)_ - Reconfigure the Account with the given `accountConfig`.\n\n* **getInfo**() - _object_ - Returns information (`AccountInfo`) about the account:\n    * **uri** - _string_ - The account's URI.\n    * **regIsConfigured** - _boolean_ - Flag to tell whether this account has registration setting (reg_uri is not empty).\n    * **regIsActive** - _boolean_ - Flag to tell whether this account is currently registered (has active registration session).\n    * **regExpiresSec** - _integer_ - An up to date expiration interval for account registration session.\n\n* **setRegistration**(\u003c _boolean_ \u003erenew) - _(void)_ - Update registration or perform unregistration. You only need to call this method if you want to manually update the registration or want to unregister from the server. If `renew` is false, this will begin the unregistration process.\n\n* **setTransport**(\u003c _Transport_ \u003etrans) - _(void)_ - Lock/bind the given transport to this account. Normally you shouldn't need to do this, as transports will be selected automatically by the library according to the destination. When an account is locked/bound to a specific transport, all outgoing requests from this account will use the specified transport (this includes SIP registration, dialog (call and event subscription), and out-of-dialog requests such as MESSAGE).\n\n* **makeCall**(\u003c _string_ \u003edestination) - _Call_ - Start a new SIP call to `destination`.\n\n\nAccount properties\n------------------\n\n* **valid** - _boolean_ - (Read-only) Is the Account still valid?\n\n* **default** - _boolean_ - (Read/Write) Is this the default Account for when no other Account matches a request?\n\n\nAccount events\n--------------\n\n* **registering**() - The registration process has started.\n\n* **unregistering**() - The unregistration process has started.\n\n* **registered**() - The registration process has completed.\n\n* **unregistered**() - The unregistration process has completed.\n\n* **state**(\u003c _boolean_ \u003eactive, \u003c _integer_ \u003estatusCode) - The account state has changed. `active` indicates if registration is active. `statusCode` refers to the relevant SIP status code.\n\n* **call**(\u003c _object_ \u003einfo, \u003c _Call_ \u003ecall) - An incoming call request. `info` contains:\n    * **srcAddress** - _string_ - The ip (and port) of the request.\n    * **localUri** - _string_ - Local SIP URI.\n    * **localContact** - _string_ - Local Contact field.\n    * **remoteUri** - _string_ - Remote SIP URI.\n    * **remoteContact** - _string_ - Remote Contact field.\n    * **callId** - _string_ - The Call-ID field.\n\n\nCall methods\n------------\n\n* **answer**([\u003c _integer_ \u003estatusCode[, \u003c _string_ \u003ereason]]) - _(void)_ - For incoming calls, this responds to the INVITE with an optional `statusCode` (defaults to 200) and optional `reason` phrase.\n\n* **hangup**([\u003c _integer_ \u003estatusCode[, \u003c _string_ \u003ereason]]) - _(void)_ - Hangs up the call with an optional `statusCode` (defaults to 603) and optional `reason` phrase. This function is different than answering the call with 3xx-6xx response (with answer()), in that this function will hangup the call regardless of the state and role of the call, while answer() only works with incoming calls on EARLY state.\n\n* **hold**() - _(void)_ - Puts the call on hold.\n\n* **reinvite**() - _(void)_ - Releases a hold.\n\n* **update**() - _(void)_ - Sends an UPDATE request.\n\n* **transfer**(\u003c _string_ \u003edestination) - _(void)_ - Transfers the call to `destination`.\n\n* **dtmf**(\u003c _string_ \u003edigits) - _(void)_ - Sends DTMF digits to the remote end using the RFC 2833 payload format.\n\n* **unref**() - _(void)_ - Detaches the Call from the event loop (default).\n\n* **ref**() - _(void)_ - Attaches the Call to the event loop.\n\n* **getStatsDump**([\u003c _boolean_ \u003einclMediaStats[, \u003c _string_ \u003eindent]]) - _string_ - Returns formatted statistics about the call. If `inclMediaStats` is true, then statistics about the Call's media is included (default is true). `indent` is the string to use for indenting (default is two spaces).\n\n\nCall properties\n---------------\n\n* **connDuration** - _double_ - (Read-only) Call connected duration in seconds (zero when call is not established).\n\n* **totalDuration** - _double_ - (Read-only) Total call duration in seconds, including set-up time.\n\n* **hasMedia** - _boolean_ - (Read-only) True if the Call has active media.\n\n* **isActive** - _boolean_ - (Read-only) True if the call has an active INVITE session and the INVITE session has not been disconnected.\n\n\nCall events\n-----------\n\n* **state**(\u003c _string_ \u003estate) - The call state has changed. `state` is one of: 'calling', 'incoming', 'early', 'connecting', 'confirmed', or 'disconnected'.\n\n* **dtmf**(\u003c _string_ \u003edigit) - A DTMF digit has been received from the remote end.\n\n* **media**(\u003c _array_ \u003emedias) - The list of Medias associated with this call have changed and the current list is available in `medias`.\n\n\nMedia methods\n-------------\n\n* **startTransmitTo**(\u003c _Media_ \u003esink) - _(void)_ - Starts transmitting to `sink`.\n\n* **stopTransmitTo**(\u003c _Media_ \u003esink) - _(void)_ - Stops transmitting to `sink`.\n\n* **adjustTxLevel**(\u003c _float_ \u003eval) - _(void)_ - Adjust the signal level of the audio sent from this Media by making it louder or quieter: a `val` of 1.0 means no level adjustment and a `val` of 0 means to mute.\n\n* **adjustRxLevel**(\u003c _float_ \u003eval) - _(void)_ - Adjust the signal level of the audio sent to this Media by making it louder or quieter: a `val` of 1.0 means no level adjustment and a `val` of 0 means to mute.\n\n* **close**() - _(void)_ - Immediately closes the Media. This can be useful to do explicitly since v8's garbage collector is quite lazy. After calling this, using this particular Media instance (and its methods) is useless.\n\n\nMedia properties\n----------------\n\n* **dir** - _string_ - Returns the direction of the media from our perspective. The value is one of: 'none', 'inbound', 'outbound', 'bidirectional', or 'unknown'.\n\n* **rtpAddr** - _string_ - Returns the remote address (and port) of where the RTP originates.\n\n* **rtcpAddr** - _string_ - Returns the remote address (and port) of where the RTCP originates.\n\n* **rxLevel** - _integer_ - Returns the last received signal level.\n\n* **txLevel** - _integer_ - Returns the last transmitted signal level.\n\n\nMedia events\n------------\n\n* **eof**() - This is only applicable to player or playlist Media objects and indicates that the end of the file or end of playlist has been reached.\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmscdex%2Fsipster","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmscdex%2Fsipster","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmscdex%2Fsipster/lists"}