use anyhow::{Context, Result}; use iroh::Endpoint; use iroh::endpoint::presets; use iroh_tickets::endpoint::EndpointTicket; use tokio::net::TcpListener; use crate::cli::ViewerOpts; use crate::common::{alpn::ALPN, signal}; pub async fn run(ticket: EndpointTicket, opts: ViewerOpts) -> Result<()> { let cancel = signal::install_ctrl_c(); let endpoint = Endpoint::builder(presets::N0) .alpns(vec![ALPN.to_vec()]) .bind() .await?; let addr = ticket.endpoint_addr().clone(); tracing::info!(remote = %addr.id, "connecting to host"); let conn = endpoint.connect(addr, ALPN).await?; let (quic_send, quic_recv) = conn.open_bi().await?; let listener = TcpListener::bind(("127.0.0.1", opts.port)).await?; let port = listener.local_addr()?.port(); let url = format!("http://127.0.0.1:{port}"); if opts.interactive { let player = crate::interactive::prompt_player()?; player .spawn(&url) .with_context(|| "failed to launch player")?; print_viewer_banner_interactive(); } else { print_viewer_banner(&url); } let result = tokio::select! { accepted = listener.accept() => { let (tcp, peer) = accepted?; tracing::info!(%peer, "local viewer connected"); crate::common::tunnel::bridge(quic_send, quic_recv, tcp).await } _ = cancel.cancelled() => { tracing::info!("ctrl-c received before local viewer connected"); Ok(()) } }; endpoint.close().await; result } fn print_viewer_banner(url: &str) { eprintln!(); eprintln!("┌─ PixelPass · viewer ───────────────────────────────────────"); eprintln!("│ Connected to host. Open the stream in your player:"); eprintln!("│"); eprintln!( "│ mpv --profile=low-latency --untimed --audio-buffer=0.2 --demuxer-max-bytes=2M --demuxer-readahead-secs=0.5 {url}" ); eprintln!("│ vlc --network-caching=200 --live-caching=200 {url}"); eprintln!("│"); eprintln!("│ Press Ctrl+C to disconnect."); eprintln!("└────────────────────────────────────────────────────────────"); eprintln!(); } fn print_viewer_banner_interactive() { eprintln!(); eprintln!("┌─ PixelPass · viewer ───────────────────────────────────────"); eprintln!("│ Player launched. Close it (or press Ctrl+C here) to"); eprintln!("│ disconnect."); eprintln!("└────────────────────────────────────────────────────────────"); eprintln!(); }