rfcvoip is a maintained, protocol-focused VoIP/SIP/RTP library.
Project description
rfcvoip
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
VoIPPhoneandVoIPCallAPI 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
dnspythonis 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)orVoIPPhone(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_depthis 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=tcpsips:registrar.example.comregistrar.example.comwithtransport="tcp"sip:pbx.example.net:5060as 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.
- Opus, default dynamic payload 111, requiring loadable
- Compiler-dependent group, installable with
rfcvoip[compiler]:- G.722, static payload 9, requiring the
G722PyPI package.
- G.722, static payload 9, requiring the
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.
- TJ Porter, original PyVoIP implementation.
- synodriver, pysilk and SILK bindings work.
- Nabu Casa.
- Home Assistant.
Additional thanks to the open-source development and research communities whose tools and specifications make this project possible.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file rfcvoip-2.9.8.tar.gz.
File metadata
- Download URL: rfcvoip-2.9.8.tar.gz
- Upload date:
- Size: 173.3 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.11.4
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
ff57726ac754375ef5b48f0bafeebf0cb24f6d6bc3381fd6812788ed7347dbaf
|
|
| MD5 |
d888770c0640cff568695ded8170945a
|
|
| BLAKE2b-256 |
a16363252463a6c36528d173e1fc498caa63f81233029a585b474f10c0f40b5b
|
File details
Details for the file rfcvoip-2.9.8-py3-none-any.whl.
File metadata
- Download URL: rfcvoip-2.9.8-py3-none-any.whl
- Upload date:
- Size: 127.0 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.11.4
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
a55e3e8a71b14b28fa7482dfddffecda8fad06f676130e02db060f2911f2e569
|
|
| MD5 |
e9a2e45f29fb63649bff280b2fb995b3
|
|
| BLAKE2b-256 |
f442b2659f081111a780e9fb18d508a5899a696df741147b805e6ba9cec3a6fc
|