Skip to main content

Python SIP client library with PJSUA2 and native UDP implementations

Project description

SIP Client Library

Python SIP 客戶端庫,提供兩種不同的實現方式:基於 PJSUA2 的高階實現和基於原生 UDP Socket 的底層實現。

概述

這個庫包含兩個獨立的 SIP 客戶端實現:

🚀 PJSUA2 版本 (sip_client.pj)

  • 適用場景: 生產環境、快速開發、穩定性要求高
  • 特點: 成熟穩定、功能完整、API 簡潔
  • 依賴: PJSUA2 庫

🛠️ UDP 手刻版本 (sip_client.udp)

  • 適用場景: 學習研究、深度客製化、嵌入式系統
  • 特點: 完全控制、教育價值、輕量級
  • 依賴: 僅 Python 標準庫

快速開始

使用 Docker(推薦)

由於 PJSUA2 需要編譯 PJSIP 庫,推薦使用 Docker 快速搭建環境:

# 克隆項目
git clone <repository-url>
cd sip-client

# 使用 Docker Compose 啟動環境
cd docker
docker-compose up -d

# 或直接構建 Docker 映像
docker build -t sip-client .
docker run -it --network host sip-client /bin/bash

手動安裝

如果需要手動安裝,請參考 docker/Dockerfile 中的詳細步驟:

# 基本依賴(僅 UDP 版本)
pip install -r requirements.txt

# PJSUA2 版本需要編譯 PJSIP(複雜,建議使用 Docker)
# 詳細步驟請參考 docker/Dockerfile

基本使用

在 Docker 容器中使用

# 進入容器
docker exec -it sip-client /bin/bash

# 在容器中運行測試
cd /home/user
python3 test_pjsua2.py  # 測試 PJSUA2 版本
python3 test_udp.py     # 測試 UDP 版本

PJSUA2 版本(需要 Docker 環境)

from sip_client.pj import SipClient
import logging

# 設定日誌
logging.basicConfig(level=logging.DEBUG)

# 建立客戶端
sc = SipClient(
    domain="sip.provider.com",
    port=5060,
    username="your_username",
    password="your_password",
    transport_ip="192.168.1.100",
    transport_port=5060,
    sip_log_level=3
)

# 初始化並註冊
sc.init()

# 等待註冊成功
while not sc.account.getInfo().regIsActive:
    sc.ENDPOINT.libHandleEvents(10)

print("SIP 註冊成功")

# 撥打電話
sc.make_call("target_user")

# 主事件循環
while True:
    sc.ENDPOINT.libHandleEvents(10)
    # 其他邏輯...

UDP 手刻版本

from sip_client.udp import SipClient, CallState
import time

# 建立客戶端
sc = SipClient(
    domain="sip.provider.com",
    port=5060,
    username="your_username",
    password="your_password",
    transport_ip="192.168.1.100",
    transport_port=5060,
    rtp_port=5004,
    rtcp_port=5005
)

# 註冊 SIP 帳號
success = sc.register()
if success:
    print("註冊成功")
    
    # 撥打電話
    sc.make_call("target_user")
    
    # 檢查通話狀態
    while sc.state != CallState.CONFIRMED:
        time.sleep(0.1)
    
    print("通話已建立")

功能比較

功能 PJSUA2 版本 UDP 手刻版本
基本通話
來電處理
主動轉接
被動轉接(接收 REFER) ⚠️ ⚠️
通話保留
Digest 認證
RTP 音頻
183 智能處理
Hold-then-REFER
線程安全 ⚠️
多編解碼器 ⚠️
開發難度
資源使用
客製化程度

詳細文檔

PJSUA2 版本

詳細說明請參考:sip_client/pj/README.md

主要特色:

  • 基於成熟的 PJSIP 庫
  • 完整的線程安全支援
  • 自動通話處理(183 Session Progress)
  • 標準的 Hold-then-REFER 轉接機制
  • 多編解碼器支援

UDP 手刻版本

詳細說明請參考:sip_client/udp/README.md

主要特色:

  • 完全手工實現 SIP 協議
  • 基於 RFC 3261 的完整狀態機
  • 詳細的識別符管理說明
  • 適合學習和深度客製化
  • 輕量級,無外部依賴

音頻處理範例

兩個版本都支援音頻處理,以下是通用的音頻處理範例:

import librosa
import numpy as np

def convert_to_audio_bytes(audio, sr, norm=True):
    """將音頻轉換為 8kHz 16bit PCM 格式"""
    if sr != 8000:
        audio = librosa.resample(audio, orig_sr=sr, target_sr=8000, res_type='kaiser_fast')

    if norm:  
        # 正規化避免高頻雜音
        audio = audio * (32767 / max(0.01, np.max(np.abs(audio))))
        audio = audio.astype(np.int16)
    else:
        audio = (audio * 32767).astype(np.int16)

    return audio.tobytes()

# 播放音頻到通話中
def play_audio_to_call(sip_client, audio_file):
    audio, sr = librosa.load(audio_file, sr=None)
    audio_bytes = convert_to_audio_bytes(audio, sr)
    
    # PJSUA2 版本
    if hasattr(sip_client, 'current_call') and sip_client.current_call:
        sip_client.current_call.putFrame(audio_bytes)
    
    # UDP 版本  
    if hasattr(sip_client, 'current_call') and sip_client.current_call:
        sip_client.current_call.send_audio(audio_bytes)

測試範例

項目包含完整的測試範例:

  • test_pjsua2.py: PJSUA2 版本的完整測試
  • test_udp.py: UDP 版本的完整測試
  • test_audio.py: 音頻處理測試
# 測試 PJSUA2 版本
python test_pjsua2.py

# 測試 UDP 版本
python test_udp.py

# 測試音頻處理
python test_audio.py

已知限制與 TODO

當前限制

  • 被動轉接功能不完整: 當對方(第三方)嘗試將通話轉接到本 SIP 客戶端時,可能會出現問題
  • REFER 請求處理: 接收和處理來自外部的 REFER 請求尚未完全實現

TODO 清單

  1. 完善被動轉接機制

    • 實現接收 REFER 請求的完整處理流程
    • 支援被動轉接時的狀態機轉換
    • 處理轉接過程中的錯誤情況
  2. UDP 版本改進

    • RTP socket 的保護機制
    • Socket 發送失敗時的 FSM 調整
    • 增強線程安全性
  3. 功能擴展

    • 支援更多音頻編解碼器
    • 改進錯誤處理和恢復機制
    • 添加更完整的 SIP 特性支援

注意事項

  1. 推薦使用 Docker: 由於 PJSUA2 編譯複雜,強烈建議使用提供的 Docker 環境
  2. 網路配置: 使用 --network host 模式確保 SIP 和 RTP 端口正常通信
  3. 音頻格式: 預設使用 PCMA/8000 編解碼器
  4. 線程安全: UDP 版本在多線程環境需要額外注意
  5. 手動編譯: 如需手動編譯 PJSUA2,請參考 docker/Dockerfile 中的詳細步驟

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

nx_sip_client-1.0.1.tar.gz (21.0 kB view details)

Uploaded Source

Built Distribution

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

nx_sip_client-1.0.1-py3-none-any.whl (22.9 kB view details)

Uploaded Python 3

File details

Details for the file nx_sip_client-1.0.1.tar.gz.

File metadata

  • Download URL: nx_sip_client-1.0.1.tar.gz
  • Upload date:
  • Size: 21.0 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.8.10

File hashes

Hashes for nx_sip_client-1.0.1.tar.gz
Algorithm Hash digest
SHA256 3a69cad1fbff647f9347bc37b46d6553b0104028d8a947c123a3ce4586b167ce
MD5 69d142f4194027a092bff44a58ef8eaa
BLAKE2b-256 b9bc2e3ea0fc5c25d1add702637b4e569a32fb35d6c6a02b69571d45db06c743

See more details on using hashes here.

File details

Details for the file nx_sip_client-1.0.1-py3-none-any.whl.

File metadata

  • Download URL: nx_sip_client-1.0.1-py3-none-any.whl
  • Upload date:
  • Size: 22.9 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.8.10

File hashes

Hashes for nx_sip_client-1.0.1-py3-none-any.whl
Algorithm Hash digest
SHA256 2f655f2217ce6235ce0360e7f1890ec0033a79d59739e1abf199914ddd1ab268
MD5 95bbe5a697d4f5c8a797d90a732322b9
BLAKE2b-256 94ed0071b77676b0c334a5d025c32f2d7a331107e1dbcde44bca6c34af075195

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