-
Notifications
You must be signed in to change notification settings - Fork 135
feat: iroh support #794
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat: iroh support #794
Changes from all commits
cf57c18
ecb6473
4479711
ae10087
3396963
0a6e925
c4995e0
32725d8
c1b9a4f
45fc066
a1d7905
68f79ad
ca3ce89
6e341a9
cb770d0
9535833
8e44da9
a90f5dd
8b17e3d
3cb0569
f47b6e1
0b642a1
68bc45f
8c47525
3a089de
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Large diffs are not rendered by default.
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -31,10 +31,11 @@ dev: | |
| "sleep 1 && just pub bbb http://localhost:4443/anon" \ | ||
| "sleep 2 && just web http://localhost:4443/anon" | ||
|
|
||
|
|
||
| # Run a localhost relay server without authentication. | ||
| relay: | ||
| relay *args: | ||
| # Run the relay server overriding the provided configuration file. | ||
| TOKIO_CONSOLE_BIND=127.0.0.1:6680 cargo run --bin moq-relay -- dev/relay.toml | ||
| TOKIO_CONSOLE_BIND=127.0.0.1:6680 cargo run --bin moq-relay -- dev/relay.toml {{args}} | ||
|
|
||
| # Run a cluster of relay servers | ||
| cluster: | ||
|
|
@@ -128,23 +129,26 @@ download-url name: | |
| *) echo "unknown" && exit 1 ;; \ | ||
| esac | ||
|
|
||
| # Convert an h264 input file to CMAF (fmp4) format to stdout. | ||
| ffmpeg-cmaf input output='-' *args: | ||
| ffmpeg -hide_banner -v quiet \ | ||
| -stream_loop -1 -re \ | ||
| -i "{{input}}" \ | ||
| -c copy \ | ||
| -f mp4 -movflags cmaf+separate_moof+delay_moov+skip_trailer+frag_every_frame {{args}} {{output}} | ||
|
|
||
| # Publish a video using ffmpeg to the localhost relay server | ||
| # NOTE: The `http` means that we perform insecure certificate verification. | ||
| # Switch it to `https` when you're ready to use a real certificate. | ||
| pub name url="http://localhost:4443/anon" *args: | ||
| pub name url="http://localhost:4443/anon" prefix="" *args: | ||
| # Download the sample media. | ||
| just download "{{name}}" | ||
|
|
||
| # Pre-build the binary so we don't queue media while compiling. | ||
| cargo build --bin hang | ||
|
|
||
| # Run ffmpeg and pipe the output to hang | ||
| ffmpeg -hide_banner -v quiet \ | ||
| -stream_loop -1 -re \ | ||
| -i "dev/{{name}}.fmp4" \ | ||
| -c copy \ | ||
| -f mp4 -movflags cmaf+separate_moof+delay_moov+skip_trailer+frag_every_frame \ | ||
| - | TOKIO_CONSOLE_BIND=127.0.0.1:6681 cargo run --bin hang -- publish --url "{{url}}" --name "{{name}}" fmp4 {{args}} | ||
| # Publish the media with the hang cli. | ||
| just ffmpeg-cmaf "dev/{{name}}.fmp4" |\ | ||
| cargo run --bin hang -- \ | ||
| publish --url "{{url}}" --name "{{prefix}}{{name}}" {{args}} fmp4 | ||
|
|
||
| # Generate and ingest an HLS stream from a video file. | ||
| pub-hls name relay="http://localhost:4443/anon": | ||
|
|
@@ -241,20 +245,19 @@ sub name url='http://localhost:4443/anon': | |
| @echo "Install and use hang-gst directly for GStreamer functionality" | ||
|
|
||
| # Publish a video using ffmpeg directly from hang to the localhost | ||
| serve name: | ||
| # To also serve via iroh, pass --iroh-enabled as last argument. | ||
| serve name *args: | ||
| # Download the sample media. | ||
| just download "{{name}}" | ||
|
|
||
| # Pre-build the binary so we don't queue media while compiling. | ||
| cargo build --bin hang | ||
|
|
||
| # Run ffmpeg and pipe the output to hang | ||
| ffmpeg -hide_banner -v quiet \ | ||
| -stream_loop -1 -re \ | ||
| -i "dev/{{name}}.fmp4" \ | ||
| -c copy \ | ||
| -f mp4 -movflags cmaf+separate_moof+delay_moov+skip_trailer+frag_every_frame \ | ||
| - | cargo run --bin hang -- serve --listen "[::]:4443" --tls-generate "localhost" --name "{{name}}" | ||
| just ffmpeg-cmaf "dev/{{name}}.fmp4" |\ | ||
| cargo run --bin hang -- \ | ||
| {{args}} serve --listen "[::]:4443" --tls-generate "localhost" \ | ||
| --name "{{name}}" fmp4 | ||
|
Comment on lines
+248
to
+260
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Clarify the comment about argument placement. The comment states "pass --iroh-enabled as last argument" but the placement of For example, cargo run --bin hang -- --iroh-enabled serve --listen "[::]:4443" ...The wording "last argument" typically suggests the flag appears at the end of the command, which could confuse users. 📝 Suggested comment clarification-# Publish a video using ffmpeg directly from hang to the localhost
-# To also serve via iroh, pass --iroh-enabled as last argument.
+# Publish a video using ffmpeg directly from hang to the localhost
+# To also serve via iroh, pass --iroh-enabled (e.g., just serve bbb --iroh-enabled).🤖 Prompt for AI Agents |
||
|
|
||
| # Run the web server | ||
| web url='http://localhost:4443/anon': | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,59 @@ | ||
| use anyhow::Context; | ||
| use axum::handler::HandlerWithoutStateExt; | ||
| use axum::http::StatusCode; | ||
| use axum::response::IntoResponse; | ||
| use axum::{http::Method, routing::get, Router}; | ||
| use std::net::SocketAddr; | ||
| use std::path::PathBuf; | ||
| use std::sync::{Arc, RwLock}; | ||
| use tower_http::cors::{Any, CorsLayer}; | ||
| use tower_http::services::ServeDir; | ||
|
|
||
| // Initialize the HTTP server (but don't serve yet). | ||
| pub async fn run_web( | ||
| bind: SocketAddr, | ||
| tls_info: Arc<RwLock<moq_native::TlsInfo>>, | ||
| public: Option<PathBuf>, | ||
| ) -> anyhow::Result<()> { | ||
| let listen = tokio::net::lookup_host(bind) | ||
| .await | ||
| .context("invalid listen address")? | ||
| .next() | ||
| .context("invalid listen address")?; | ||
|
|
||
| async fn handle_404() -> impl IntoResponse { | ||
| (StatusCode::NOT_FOUND, "Not found") | ||
| } | ||
|
|
||
| let fingerprint_handler = move || async move { | ||
| // Get the first certificate's fingerprint. | ||
| // TODO serve all of them so we can support multiple signature algorithms. | ||
| tls_info | ||
| .read() | ||
| .expect("tls_info read lock poisoned") | ||
| .fingerprints | ||
| .first() | ||
| .expect("missing certificate") | ||
| .clone() | ||
| }; | ||
|
Comment on lines
+28
to
+38
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Potential panic if no certificates are configured. The Consider returning a proper HTTP error instead: 🔎 Proposed fix let fingerprint_handler = move || async move {
// Get the first certificate's fingerprint.
// TODO serve all of them so we can support multiple signature algorithms.
- tls_info
+ match tls_info
.read()
.expect("tls_info read lock poisoned")
.fingerprints
.first()
- .expect("missing certificate")
.clone()
+ {
+ Some(fp) => (StatusCode::OK, fp).into_response(),
+ None => (StatusCode::SERVICE_UNAVAILABLE, "no certificate available").into_response(),
+ }
};
|
||
|
|
||
| let mut app = Router::new() | ||
| .route("/certificate.sha256", get(fingerprint_handler)) | ||
| .layer(CorsLayer::new().allow_origin(Any).allow_methods([Method::GET])); | ||
|
|
||
| // If a public directory is provided, serve it. | ||
| // We use this for local development to serve the index.html file and friends. | ||
| if let Some(public) = public.as_ref() { | ||
| tracing::info!(public = %public.display(), "serving directory"); | ||
|
|
||
| let public = ServeDir::new(public).not_found_service(handle_404.into_service()); | ||
| app = app.fallback_service(public); | ||
| } else { | ||
| app = app.fallback_service(handle_404.into_service()); | ||
| } | ||
|
|
||
| let server = axum_server::bind(listen); | ||
| server.serve(app.into_make_service()).await?; | ||
|
|
||
| Ok(()) | ||
| } | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fix terminal numbering in the explanation.
The description incorrectly states "pushed from terminal 1 via iroh to the relay running in terminal 2". Terminal 1 runs the relay, and terminal 2 publishes. The correct flow is: terminal 2 (publisher) → terminal 1 (relay) → browser.
📝 Proposed fix
📝 Committable suggestion
🤖 Prompt for AI Agents