|
1 | 1 | use pulsebeam_agent::{ |
2 | 2 | MediaFrame, MediaKind, MediaTime, TransceiverDirection, |
3 | | - actor::{AgentBuilder, AgentEvent}, |
| 3 | + actor::{AgentBuilder, AgentEvent, TrackReceiver, TrackSender}, |
4 | 4 | media::H264Looper, |
5 | 5 | signaling::HttpSignalingClient, |
6 | 6 | }; |
7 | 7 | use std::time::Duration; |
8 | 8 | use tokio::time::Instant; |
9 | 9 |
|
| 10 | +const RAW_H264: &[u8] = include_bytes!("video.h264"); |
| 11 | + |
10 | 12 | #[tokio::main] |
11 | 13 | async fn main() { |
12 | 14 | tracing_subscriber::fmt::init(); |
13 | 15 |
|
14 | | - let raw_bytes = include_bytes!("video.h264"); |
15 | | - tracing::info!("joining"); |
16 | 16 | let signaling = HttpSignalingClient::default(); |
17 | 17 | let mut agent = AgentBuilder::new(signaling) |
18 | 18 | .with_track(MediaKind::Video, TransceiverDirection::SendOnly, None) |
19 | 19 | .join("demo") |
20 | 20 | .await |
21 | 21 | .unwrap(); |
22 | | - tracing::info!("joined"); |
23 | 22 |
|
24 | 23 | while let Some(ev) = agent.next_event().await { |
25 | 24 | tracing::info!("received event: {:?}", ev); |
26 | 25 | match ev { |
27 | | - AgentEvent::SenderAdded(sender) => { |
28 | | - tokio::spawn(async move { |
29 | | - let mut looper = H264Looper::new(raw_bytes); |
30 | | - let mut interval = |
31 | | - tokio::time::interval(Duration::from_nanos(1_000_000_000 / 30)); |
32 | | - let start = Instant::now(); |
33 | | - loop { |
34 | | - let now = interval.tick().await; |
35 | | - let elapsed = now - start; |
36 | | - |
37 | | - // Calculate TS based on actual elapsed time to prevent drift |
38 | | - let ts = (elapsed.as_secs_f64() * 90000.0) as u64; |
39 | | - |
40 | | - let frame = MediaFrame { |
41 | | - ts: MediaTime::from_90khz(ts), |
42 | | - data: looper.next().unwrap(), |
43 | | - }; |
44 | | - sender.try_send(frame); |
45 | | - } |
46 | | - }); |
47 | | - } |
| 26 | + AgentEvent::SenderAdded(sender) => handle_sender(sender), |
| 27 | + AgentEvent::ReceiverAdded(receiver) => handle_receiver(receiver), |
48 | 28 | _ => {} |
49 | 29 | } |
50 | 30 | } |
51 | 31 | } |
| 32 | + |
| 33 | +fn handle_sender(sender: TrackSender) { |
| 34 | + tokio::spawn(async move { |
| 35 | + let mut looper = H264Looper::new(RAW_H264); |
| 36 | + let mut interval = tokio::time::interval(Duration::from_nanos(1_000_000_000 / 30)); |
| 37 | + let start = Instant::now(); |
| 38 | + loop { |
| 39 | + let now = interval.tick().await; |
| 40 | + let elapsed = now - start; |
| 41 | + |
| 42 | + // Calculate TS based on actual elapsed time to prevent drift |
| 43 | + let ts = (elapsed.as_secs_f64() * 90000.0) as u64; |
| 44 | + |
| 45 | + let frame = MediaFrame { |
| 46 | + ts: MediaTime::from_90khz(ts), |
| 47 | + data: looper.next().unwrap(), |
| 48 | + }; |
| 49 | + sender.try_send(frame); |
| 50 | + } |
| 51 | + }); |
| 52 | +} |
| 53 | + |
| 54 | +fn handle_receiver(_receiver: TrackReceiver) { |
| 55 | + // TODO: |
| 56 | +} |
0 commit comments