Skip to main content

rfcvoip is a maintained, protocol-focused VoIP/SIP/RTP library.

Project description

rfcvoip

GitHub PyPI Version License

buymeacoffee

rfcvoip is a maintained, protocol-focused VoIP/SIP/RTP library and a practical drop-in successor to the original PyVoIP API.

The original PyVoIP project has been on a long project freeze. rfcvoip keeps the same spirit and familiar high-level API, while focusing on production reliability, protocol accuracy, safer parsing, better negotiation, and clearer runtime telemetry. Since the original codebase, rfcvoip has fixed more than 200 issues across SIP signaling, RTP media, SDP parsing, digest authentication, codec negotiation, transport handling, cleanup, and thread-safety.

rfcvoip does not require a sound library. You can use any audio backend that can read or write linear byte data, such as wave, PyAudio, sounddevice, a bot framework, or your own media pipeline.

Original PyVoIP contributors are still credited and honored. rfcvoip builds on their work while continuing development under the new project name.

Highlights

  • High-level VoIPPhone and VoIPCall API for inbound and outbound calls.
  • Lower-level SIP and RTP modules for applications that need direct protocol control.
  • SIP registration, deregistration, INVITE, ACK, BYE, CANCEL, OPTIONS, SUBSCRIBE, and NOTIFY handling.
  • UDP signaling, TCP signaling, TLS signaling, SIPS URI handling, outbound SIP proxy support, and RFC 3263-style NAPTR/SRV lookup when dnspython is available.
  • SIP digest authentication with MD5, MD5-sess, SHA-256, SHA-256-sess, SHA-512-256, and SHA-512-256-sess.
  • RTP audio using PCMU, PCMA, PCMU-WB, PCMA-WB, telephone-event DTMF, optional G.722, optional Opus, and optional SILK.
  • Codec priority tuning, FMTP validation, SDP bandwidth checks, dynamic payload mapping, RTP extension and padding parsing, and robust RTP buffering.
  • Built-in telemetry for SIP authentication, local and remote codecs, active calls, RTP selections, and frontend-friendly reports.
  • Safer behavior around malformed SIP/SDP, duplicate headers, Content-Length mismatches, CRLF keepalives, IPv4/IPv6 handling, rport handling, failed call setup, and shutdown cleanup.

Installation

pip install rfcvoip

Optional codec extras:

pip install "rfcvoip[opus]"
pip install "rfcvoip[silk]"
pip install "rfcvoip[g722]"
pip install "rfcvoip[no-compiler]"
pip install "rfcvoip[compiler]"
pip install "rfcvoip[all]"

The opus and silk extras install optional Python packages that do not require a C++ compiler. For convenience, no-compiler installs both of those extras together. Opus support still requires a loadable system libopus library at runtime.

G.722 support requires the optional G722 PyPI package, which may require a C++ compiler when installed from source. It is available through either the g722 or compiler extra. The all extra installs both the no-compiler extras and the compiler-dependent extras. Unavailable optional codecs are reported as unavailable and are not included in SIP offers.

Installing from a source checkout:

python -m pip install .

Importing and migration

New applications should import rfcvoip:

from rfcvoip.VoIP import VoIPPhone
from rfcvoip import RTP, Telemetry

The public API is intentionally familiar to PyVoIP users. In most applications, migration is limited to installing the new package and updating imports from pyVoIP to rfcvoip.

Public audio format

rfcvoip exposes audio to user code as linear PCM bytes. By default this remains unsigned 8-bit linear PCM for compatibility. Applications may select the public bit depth with VoIPPhone(audio_bit_depth=8|16|24|32|64|"best"). Stereo audio is interleaved left/right. The public sample rate, channel count, and bit depth can be selected automatically from the negotiated codec or fixed by the application.

The public audio format is selected as follows:

  • If VoIPPhone(audio_sample_rate=...) is provided, that fixed sample rate is used.
  • If VoIPPhone(audio_channels=1) or VoIPPhone(audio_channels=2) is provided, that fixed channel count is used.
  • If audio_sample_rate=None, rfcvoip uses the selected codec's preferred public sample rate.
  • If audio_channels=None, rfcvoip uses the selected codec's preferred public channel count.
  • If audio_bit_depth is a fixed value, rfcvoip exposes that public bit depth.
  • If audio_bit_depth="best", rfcvoip follows the selected codec's preferred public bit depth after negotiation and falls back to 8-bit before negotiation.
  • Before a codec has been negotiated, the fallback public format is 8000 Hz mono 8-bit unless fixed values were configured.

Public PCM formats are:

  • 8-bit: unsigned linear PCM, midpoint 128.
  • 16-bit: signed little-endian PCM.
  • 24-bit: signed little-endian packed PCM.
  • 32-bit: signed little-endian integer PCM.
  • 64-bit: signed little-endian integer PCM.

For example, 20 ms at 8000 Hz mono is 160 bytes at 8-bit, 320 bytes at 16-bit, 480 bytes at 24-bit, 640 bytes at 32-bit, and 1280 bytes at 64-bit. At 48000 Hz stereo, 20 ms is 1920 bytes at 8-bit, 3840 bytes at 16-bit, 5760 bytes at 24-bit, 7680 bytes at 32-bit, and 15360 bytes at 64-bit. Use call.audio_frame_size() instead of hard-coding 160 when your application may negotiate wideband, stereo-capable codecs, or non-8-bit public PCM.

PCMU and PCMA remain 8000 Hz mono RTP codecs on the wire. Wideband, stereo, and optional codecs convert internally between the public audio format and their native RTP format.

Quick start

A minimal inbound-call application creates a VoIPPhone, starts it, and handles calls in a callback:

from rfcvoip.VoIP import InvalidStateError, VoIPPhone


def answer(call):
    try:
        call.answer()
        call.hangup()
    except InvalidStateError:
        pass


phone = VoIPPhone(
    "sip.example.net",
    5060,
    "1000",
    "password",
    myIP="192.0.2.10",
    callCallback=answer,
)
phone.start()
input("Press enter to disable the phone")
phone.stop()

For full examples covering playback, IVR flows, outbound calls, and codec configuration, see the documentation.

Common features

Inbound and outbound calls

VoIPPhone.call("1001") originates an outbound call and returns a VoIPCall. Calls move through DIALING, RINGING, ANSWERED, and ENDED states.

VoIPCall supports answering, denying, cancelling, hanging up, reading audio, writing audio, DTMF input, and outbound DTMF. Use write_audio, read_audio, get_dtmf, send_dtmf, audio_frame_size, and audio_format.

Outbound SIP proxy

If your provider requires a separate outbound proxy, keep server pointed at the SIP domain or registrar and pass proxy / proxyPort separately. proxy may be a hostname, host:port, or a SIP URI such as sip:pbx.example.net:5060.

phone = VoIPPhone(
    "sip.example.com",
    5060,
    "alice",
    "secret",
    myIP="192.0.2.10",
    proxy="pbx.example.net",
    proxyPort=5060,
    auth_username="alice-auth-id",
)

TCP, TLS, SIPS, and DNS resolution

rfcvoip supports explicit transport selection, URI transport parameters, SIPS, TLS server names, and RFC 3263-style DNS resolution when appropriate.

Examples of supported targets:

  • sip:registrar.example.com;transport=tcp
  • sips:registrar.example.com
  • registrar.example.com with transport="tcp"
  • sip:pbx.example.net:5060 as an outbound proxy

DTMF

rfcvoip supports RTP telephone-event DTMF when the remote endpoint negotiates the telephone-event payload. Received digits are read with call.get_dtmf(). Outbound DTMF is queued with call.send_dtmf("123#") and supports 0-9, *, #, and A-D.

Codecs

Built-in continuous audio codecs:

  • PCMU, G.711 u-law, static payload 0.
  • PCMA, G.711 A-law, static payload 8.
  • PCMU-WB, G.711.1 core-layer wideband adapter, dynamic payload, default 112.
  • PCMA-WB, G.711.1 core-layer wideband adapter, dynamic payload, default 113.

Built-in event payloads:

  • telephone-event DTMF, default dynamic payload 101.

Optional codecs:

  • No-compiler group, installable with rfcvoip[no-compiler]:
    • Opus, default dynamic payload 111, requiring loadable libopus.
    • SILK at 24000, 16000, 12000, and 8000 Hz, requiring pysilk.
  • Compiler-dependent group, installable with rfcvoip[compiler]:
    • G.722, static payload 9, requiring the G722 PyPI package.

Individual codec extras remain available as rfcvoip[opus], rfcvoip[silk], and rfcvoip[g722]. Use rfcvoip[all] to install both optional codec groups.

G.722 uses the RFC 3551 static payload 9 RTP timestamp clock of 8000 Hz for wire compatibility, while encoding 16000 Hz wideband audio internally. In automatic public-audio mode, G.722 uses 16000 Hz mono audio.

PCMA-WB and PCMU-WB are implemented as RFC 5391 / G.711.1 R1 core-layer payloads. rfcvoip advertises mode-set=1, uses a 16000 Hz RTP clock, and converts between the negotiated RTP payload and the configured public unsigned 8-bit audio format. Incoming G.711.1 packets in wider modes are decoded from their G.711-compatible L0 core layer.

Codec priority affects local SDP offer order and the selected RTP codec when a remote endpoint advertises more than one compatible payload. Larger scores are preferred.

import rfcvoip
from rfcvoip import RTP

rfcvoip.set_codec_priority(RTP.PayloadType.PCMU, 1200)
rfcvoip.reset_codec_priorities()

Per-phone priorities can also be supplied with VoIPPhone(codec_priorities=...). If optional codec dependencies are loaded after import, call rfcvoip.refresh_supported_codecs() before creating or placing calls.

Telemetry and codec inspection

The Telemetry module provides serializable reports for local codec support, remote SDP, active calls, SIP authentication, and RTP codec selections.

from rfcvoip import Telemetry

print(Telemetry.report(phone))

Common telemetry helpers include:

  • Telemetry.snapshot(...)
  • Telemetry.report(...)
  • Telemetry.get(...)
  • Telemetry.local_codec_report(phone)
  • Telemetry.phone_codec_report(phone, target="1001")
  • Telemetry.call_active_codecs(call)
  • Telemetry.codec_availability(refresh=True)

Remote codec information can be probed with SIP OPTIONS when the peer or provider includes SDP in the OPTIONS response. If the remote side does not include SDP, the remote codec list is empty and can_start_call is None.

Reliability and protocol behavior

rfcvoip hardens many areas that commonly cause softphone instability:

  • SIP parser validation for malformed headers, duplicate singleton headers, folded headers, compact headers, multipart SDP, and Content-Length handling.
  • SIP TCP/TLS stream framing with keepalive handling and strict body lengths.
  • Correct transaction matching for REGISTER, INVITE, SUBSCRIBE, OPTIONS, ACK, CANCEL, BYE, and digest-auth retries.
  • Digest auth challenge selection, qop handling, auth-int body hashing, stronger algorithms, cnonce generation, and sensitive-header redaction.
  • SDP media scoping for m=, c=, a=rtpmap, a=fmtp, direction attributes, bandwidth lines, disabled streams, unsupported RTP profiles, and incompatible address families.
  • RTP validation for packet length, payload types, extensions, padding, telephone-event payloads, timestamp gaps, jitter buffering, and socket lifecycle.
  • Safer call cleanup for failed outbound calls, late final INVITE responses, unmatched ACKs, remote BYE/CANCEL, shutdown, and RTP port release.

Development checks

python -m pip install -r requirements-dev.txt
python -m pip install .
python -m compileall -q rfcvoip
python -m pytest -q

License

rfcvoip is licensed under the GNU General Public License version 3. See LICENSE for the full license text.

rfcvoip is a modified and renamed continuation of the original PyVoIP project. Original PyVoIP copyright and contributor attribution is preserved in NOTICE.

Contributors and acknowledgements

rfcvoip is built on the original PyVoIP project and continues to honor the people and projects that made it possible.

Additional thanks to the open-source development and research communities whose tools and specifications make this project possible.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

rfcvoip-2.9.5.tar.gz (168.6 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

rfcvoip-2.9.5-py3-none-any.whl (123.9 kB view details)

Uploaded Python 3

File details

Details for the file rfcvoip-2.9.5.tar.gz.

File metadata

  • Download URL: rfcvoip-2.9.5.tar.gz
  • Upload date:
  • Size: 168.6 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.14.3

File hashes

Hashes for rfcvoip-2.9.5.tar.gz
Algorithm Hash digest
SHA256 e70ef20735afff33836d176efe9c1f498fe42b7529936943d4002b90c74e18c7
MD5 3e2bb75bf09eac048619a79a86e1fd71
BLAKE2b-256 30c5b9bf2530518d8a0a34a8eb3a16edce1cc1ad3e2a99c6796014d59e6d1d4a

See more details on using hashes here.

File details

Details for the file rfcvoip-2.9.5-py3-none-any.whl.

File metadata

  • Download URL: rfcvoip-2.9.5-py3-none-any.whl
  • Upload date:
  • Size: 123.9 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.14.3

File hashes

Hashes for rfcvoip-2.9.5-py3-none-any.whl
Algorithm Hash digest
SHA256 9e0c96e54844d5e816c0984f89f783b4756f2b7eaf5100c4043cc64184203d79
MD5 7a278f543d51f42293e50c77ec7852cc
BLAKE2b-256 ecdb88956471c9f49f7fbdf9c43f806ac22dd7aaa56a9f8c182c8dcad4e725fe

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page