feat: Phase 2 — relay daemon and client library with integration pipelines
wzp-relay: - RelayPipeline: ingest → FEC decode → jitter buffer → FEC encode → send - SessionManager: tracks active calls, idle expiry - RelayConfig: TOML-based configuration - Binary: accepts QUIC connections, receives media packets wzp-client: - CallEncoder: mic PCM → Opus encode → FEC → MediaPackets - CallDecoder: MediaPackets → FEC decode → jitter → Opus decode → PCM - CLI binary: connects to relay, sends test silence frames 99 tests passing across all 7 crates. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
56
crates/wzp-client/src/cli.rs
Normal file
56
crates/wzp-client/src/cli.rs
Normal file
@@ -0,0 +1,56 @@
|
||||
//! WarzonePhone CLI test client.
|
||||
//!
|
||||
//! Usage: wzp-client <relay-addr>
|
||||
//!
|
||||
//! Connects to a relay and sends silence frames for testing.
|
||||
|
||||
use std::net::SocketAddr;
|
||||
|
||||
use tracing::{error, info};
|
||||
|
||||
use wzp_client::call::{CallConfig, CallEncoder};
|
||||
use wzp_proto::MediaTransport;
|
||||
|
||||
#[tokio::main]
|
||||
async fn main() -> anyhow::Result<()> {
|
||||
tracing_subscriber::fmt().init();
|
||||
|
||||
let relay_addr: SocketAddr = std::env::args()
|
||||
.nth(1)
|
||||
.unwrap_or_else(|| "127.0.0.1:4433".to_string())
|
||||
.parse()?;
|
||||
|
||||
info!(%relay_addr, "WarzonePhone client connecting");
|
||||
|
||||
let client_config = wzp_transport::client_config();
|
||||
let endpoint = wzp_transport::create_endpoint("0.0.0.0:0".parse()?, None)?;
|
||||
let connection =
|
||||
wzp_transport::connect(&endpoint, relay_addr, "localhost", client_config).await?;
|
||||
|
||||
info!("Connected to relay");
|
||||
|
||||
let transport = wzp_transport::QuinnTransport::new(connection);
|
||||
let config = CallConfig::default();
|
||||
let mut encoder = CallEncoder::new(&config);
|
||||
|
||||
let frame_duration = tokio::time::Duration::from_millis(20);
|
||||
let pcm = vec![0i16; 960]; // 20ms @ 48kHz silence
|
||||
|
||||
for i in 0..250u32 {
|
||||
let packets = encoder.encode_frame(&pcm)?;
|
||||
for pkt in &packets {
|
||||
if let Err(e) = transport.send_media(pkt).await {
|
||||
error!("send error: {e}");
|
||||
break;
|
||||
}
|
||||
}
|
||||
if i % 50 == 0 {
|
||||
info!(frame = i, packets = packets.len(), "sent");
|
||||
}
|
||||
tokio::time::sleep(frame_duration).await;
|
||||
}
|
||||
|
||||
info!("Done, closing");
|
||||
transport.close().await?;
|
||||
Ok(())
|
||||
}
|
||||
Reference in New Issue
Block a user