use rustrtc::media::MediaStreamTrack;
use rustrtc::*;
use std::sync::Arc;
use std::time::Duration;
use tokio::time::sleep;
#[tokio::main]
async fn main() {
tracing_subscriber::fmt()
.with_max_level(tracing::Level::DEBUG)
.init();
println!("=== RTP Mode Track Event Example ===\n");
let mut config = RtcConfiguration::default();
config.transport_mode = TransportMode::Rtp;
let pc = Arc::new(PeerConnection::new(config));
println!("✓ Created PeerConnection in RTP mode");
let transceiver = pc.add_transceiver(MediaKind::Audio, TransceiverDirection::RecvOnly);
println!("✓ Added audio transceiver (RecvOnly for incoming call)");
let remote_sdp = "\
v=0
o=- 123456 123456 IN IP4 10.0.1.100
s=SIP Call
c=IN IP4 10.0.1.100
t=0 0
m=audio 5004 RTP/AVP 8 101
a=rtpmap:8 PCMA/8000
a=rtpmap:101 telephone-event/8000
a=fmtp:101 0-15
a=sendonly
a=mid:0
";
println!("\n📥 Received remote SDP (simulated SIP INVITE):");
println!("{}", remote_sdp);
let remote_offer = SessionDescription::parse(SdpType::Offer, remote_sdp).unwrap();
pc.set_remote_description(remote_offer).await.unwrap();
println!("✓ Set remote description");
if let Some(receiver) = transceiver.receiver() {
let ssrc = receiver.ssrc();
println!("\n📊 Initial SSRC: {} (provisional, range 2000-2999)", ssrc);
assert!(ssrc >= 2000 && ssrc < 3000, "Should be provisional SSRC");
}
let answer = pc.create_answer().await.unwrap();
pc.set_local_description(answer.clone()).unwrap();
println!("\n📤 Created and set local answer (200 OK):");
println!("{}\n", answer.to_sdp_string());
println!("🎧 Starting event loop to monitor Track events...");
println!(" In real SIP scenario:");
println!(" 1. Caller sends RTP packets with actual SSRC (e.g., 4233615230)");
println!(" 2. rustrtc performs SSRC latching");
println!(" 3. PeerConnectionEvent::Track is fired");
println!(" 4. Application spawns track handler to process audio");
let pc_clone = pc.clone();
let event_task = tokio::spawn(async move {
let mut event_count = 0;
loop {
if let Some(event) = pc_clone.recv().await {
event_count += 1;
match event {
PeerConnectionEvent::Track(transceiver) => {
println!("\n🎉 EVENT: Track event received! (event #{})", event_count);
if let Some(receiver) = transceiver.receiver() {
let track = receiver.track();
let ssrc = receiver.ssrc();
println!(" Track kind: {:?}", track.kind());
println!(" Final SSRC: {} (latched from RTP packet)", ssrc);
println!(" ✓ Application can now spawn track handler");
return;
}
}
PeerConnectionEvent::DataChannel(_) => {
}
}
} else {
break;
}
}
});
println!("\n⏳ Waiting for RTP packets (in real scenario)...");
println!(" Note: This example doesn't send actual RTP packets");
println!(" In production:");
println!(" - SIP endpoint sends RTP to our address");
println!(" - rustrtc receives packets and performs SSRC latching");
println!(" - Track event fires automatically");
sleep(Duration::from_secs(2)).await;
println!("\n✅ Example complete!");
println!("\nKey Takeaways:");
println!(" • RTP mode uses provisional SSRC (2000-2999) initially");
println!(" • Actual SSRC is learned from first RTP packet (SSRC latching)");
println!(" • Track event fires AFTER latching completes");
println!(" • Application should wait for Track event before spawning handlers");
event_task.abort();
}