VOIP Calls + Resample + PHP

Collapse
X
 
  • Time
  • Show
Clear All
new posts
  • MyrinNew
    Senior Member
    • Feb 2024
    • 5168

    #1

    VOIP Calls + Resample + PHP

    VoIP Real-Time e Áudio 48 kHz no PHP: Guia Hands-On com Swoole


    Nota de arquitetura: o fluxo documentado do SpechPhone sobe dois serviços PHP (middleware.php e audio.php) e entrega áudio por RTP (backend) + WebSocket (PCM pro browser) — sem depender do caminho clássico de Asterisk/AGI (no sentido de: não existe “passo” de AGI na execução descrita no README).


    Referência: https://github.com/spechshop/spechph...-dev/README.md


    O que você vai montar (na prática)

    • Um softphone web que faz SIP/RTP em tempo real, com UI no browser via WebSocket.
    • Um pipeline de mídia onde o backend recebe RTP, decodifica e manda PCM em chunks pro cliente.
    • Um “ponto de prova” bem direto de por que Swoole muda o jogo em PHP (I/O assíncrono + corrotinas por sessão).


    1) Arquitetura em 60 segundos (2 processos, um objetivo)

    O próprio README descreve o projeto como PHP + Swoole, com mídia em RTP/UDP no backend e PCM via WebSocket pro browser (sem WebRTC/SRTP/ICE/DTLS).


    Referência: https://github.com/spechshop/spechph...-dev/README.md


    Papéis (documentados no README):
    2) “Ok, mas cadê o Swoole nessa história?”

    A parte “cala-boca” aqui é simples: corrotinas. O README afirma que o SpechPhone abre uma coroutine dedicada por trunkController e que isso permite várias chamadas simultâneas sem bloquear o processo principal.


    Referência: https://github.com/spechshop/spechph...-dev/README.md


    Se você já ouviu “PHP não aguenta real-time”, o ponto é: a crítica geralmente mira no PHP “bloqueante”; aqui a pilha gira em I/O assíncrono com Swoole.


    Importante: aqui é Swoole (extensão/runtime Swoole), não OpenSwoole.

    3) Mão na massa: subir o SpechPhone localmente

    O README do SpechPhone já entrega o caminho “clone → runtime → start”:






    # deps
    sudo apt update && sudo apt install -y openssl

    # repo + lib
    git clone https://github.com/spechshop/spechphone && cd spechphone
    git clone https://github.com/spechshop/libspech

    # runtime php otimizado (pcg729)
    curl -L https://github.com/spechshop/pcg729/...ad/current/php -o php
    chmod +x ./php
    sudo cp php /usr/local/bin/php

    # start (em terminais separados)
    php middleware.php
    php audio.php







    Referência do trecho acima: https://github.com/spechshop/spechph...-dev/README.md


    4) Áudio 48 kHz: onde entra (de verdade) e por que chama atenção

    Tem duas peças documentadas que se complementam:


    1) Oferta de Opus/48kHz via SDP no trunkController (libspech). O README mostra explicitamente:






    // Oferecer codec Opus em SDP
    $phone->mountLineCodecSDP('opus/48000/2');







    Referência do snippet: https://github.com/spechshop/libspec...pech/README.md


    2) Decodificação dinâmica + PCM em chunks pro browser. O README do SpechPhone descreve que os pacotes RTP chegam, são processados pela libspech (com funções nativas via runtime pcg729) e o áudio decodificado é entregue ao controlador WebSocket em PCM, pra ser consumido no browser via webkitAudioContext.


    Referência: https://github.com/spechshop/spechph...-dev/README.md


    Ou seja: “48 kHz” aparece naturalmente quando você negocia Opus e trata a mídia como mídia de verdade (não só “telecom 8 kHz”).

    5) Um exemplo mínimo de chamada (libspech) — com corrotinas e eventos

    Esse exemplo (do README do libspech) é o “hello world” da stack: registrar, oferecer codec, reagir a eventos e receber áudio.







    use libspech\Sip\trunkController;

    include 'plugins/autoloader.php';

    \Swoole\Coroutine\run(function () {
    $username = getenv('SIP_USERNAME');
    $password = getenv('SIP_PASSWORD');
    $domain = getenv('SIP_DOMAIN');
    $host = gethostbyname($domain);

    $phone = new trunkController($username, $password, $host, 5060);

    if (!$phone->register(2)) {
    throw new \Exception('Falha no registro');
    }

    // Oferecer codec Opus em SDP (48 kHz)
    $phone->mountLineCodecSDP('opus/48000/2');

    $phone->onRinging(function ($phone) {
    echo "Tocando...\n";
    });

    $phone->onAnswer(function (trunkController $phone) {
    echo "Atendido. Recebendo mídia...\n";
    $phone->receiveMedia();
    \Swoole\Coroutine::sleep(10);
    });

    $phone->onReceiveAudio(function ($pcmData, $peer, trunkController $phone) {
    echo "Recebido: " . strlen($pcmData) . " bytes\n";
    });

    $phone->onHangup(function (trunkController $phone) {
    echo "Chamada finalizada\n";
    $phone->close();
    });

    $phone->call('5511999999999');
    });







    Referência (onde esse exemplo está documentado): https://github.com/spechshop/libspec...pech/README.md


    Referência do exemplo completo: https://github.com/spechshop/libspec...ch/example.php


    6) Três exercícios rápidos (pra você “entrar no código”, não só ler)

    1) Troque o codec ofertado

    2) Instrumente o fluxo de PCM

    3) Faça o UI “sentir” o estado

    Links principais (pra você não se perder no labirinto)





    More...
Working...