VOIP 통화 + 리샘플 + PHP
Source: Dev.to
개요
이 가이드는 Swoole을 사용하여 PHP에서 48 kHz 오디오를 실시간으로 전송하는 VoIP 통화를 구현하는 방법을 보여줍니다. SpechPhone 프로젝트는 백엔드에서 SIP/RTP를 처리하고, WebSocket을 통해 PCM 오디오를 브라우저에 전달하는 웹 소프트폰을 제공하며, Asterisk/AGI에 의존하지 않습니다.
아키텍처
- middleware.php – UI를 제공하고 통화를 제어하는 HTTP/WebSocket 서버.
- audio.php – 오디오 패킷을 믹싱하고 스트리밍하는 오디오 서버.
미디어 흐름은 다음과 같이 동작합니다:
- 백엔드가 RTP 패킷을 수신합니다.
- libspech 라이브러리가 패킷을 디코딩합니다(
pcg729런타임 사용). - 디코딩된 오디오는 PCM 청크 형태로 WebSocket 클라이언트에 전송되고, 브라우저의
AudioContext를 통해 재생됩니다.
실시간 성능의 핵심은 Swoole의 코루틴을 활용하는 것으로, 이를 통해 메인 프로세스를 차단하지 않고 다중 통화를 동시에 처리할 수 있습니다.
전제 조건 및 설치
# 시스템 의존성
sudo apt update && sudo apt install -y openssl
# 리포지토리 복제
git clone https://github.com/spechshop/spechphone && cd spechphone
git clone https://github.com/spechshop/libspech
# 최적화된 PHP 런타임 (pcg729)
curl -L https://github.com/spechshop/pcg729/releases/download/current/php -o php
chmod +x ./php
sudo cp php /usr/local/bin/php
별도의 터미널에서 두 서비스를 실행합니다:
php middleware.php
php audio.php
중요: 이 프로젝트는 Swoole 확장을 사용합니다( OpenSwoole 아님).
Opus 코덱 제공 / 48 kHz
trunkController는 SDP를 통해 다양한 코덱을 제안할 수 있습니다. Opus를 48 kHz로 사용하려면 다음과 같이 설정합니다:
$phone->mountLineCodecSDP('opus/48000/2');
이 설정은 RTP 스트림이 48 kHz로 협상되도록 하여 고품질 오디오를 제공합니다.
PHP 전체 예제
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');
});
예제는 다음에 문서화되어 있습니다:
제안된 실험
1. 제공 코덱 교체
코덱 제공 라인을 L16/8000으로 바꾸고 onReceiveAudio에서 수신된 바이트 수를 비교해 보세요.
$phone->mountLineCodecSDP('L16/8000');
2. PCM 흐름 계측
수신된 각 PCM 청크의 크기(strlen)를 기록하고, 크기, 주파수, 지터 패턴을 관찰합니다.
3. UI 업데이트
ringing, answered, hangup 이벤트에 반응하여 화면에 간단한 메시지를 표시하는 “thin” WebSocket 클라이언트를 구현합니다.
주요 링크
- SpechPhone (repo) –
- SpechPhone README (branch volume-dev) –
- libspech (repo) –
- libspech README (branch spech) –
- libspech example.php –
- pcg729 runtime release –