[package] name = "jolt-moq" description = "freeq's AV media plane — MoQ over QUIC, Opus and H.264 — behind a C ABI" version.workspace = true edition.workspace = true license.workspace = true repository.workspace = true [lib] # The object jolt loads. `rlib` beside it so the crate's own tests — and any # Rust consumer that would rather not go through C — can use it directly. name = "joltmoq" crate-type = ["cdylib", "rlib"] [features] # cpal's native PipeWire host, on by default. Without it only ALSA PCMs are # visible ("pipewire", "sysdefault") and the real OS sources a browser would # offer — "EMEET SmartCam C960 Mono" and friends — cannot be picked at all, so # device selection in a call becomes guesswork. # # It is a feature rather than unconditional because it builds `libspa-sys`, # which needs pkg-config and PipeWire's own headers on the build machine. The # flake at the workspace root supplies them; `--no-default-features` is for a # machine that has neither and only needs the crate to compile. default = ["pipewire"] pipewire = ["cpal/pipewire"] [dependencies] jolt-abi.workspace = true log.workspace = true iroh-live = { git = "https://github.com/n0-computer/iroh-live", rev = "c329850759740e3c9c27391258a66196c1a74a22", default-features = false, features = [ "opus", "h264", ] } moq-native = { version = "0.17.1", default-features = false, features = [ "noq", "websocket", "aws-lc-rs", ] } moq-lite = { package = "moq-net", version = "0.1.11" } # aws-lc-rs rather than ring, to match what moq-native and iroh already pull in. rustls = { version = "0.23", default-features = false, features = ["aws-lc-rs"] } # JPEG only — the V4L2 path converts MJPEG frames, and nothing here reads or # writes a picture file, so the rest of the format set is dead weight. image = { version = "0.25", default-features = false, features = ["jpeg"] } # One query parameter (`inst=`) needs escaping. That is the whole use. urlencoding = "2" libc = "0.2" n0-future = "0.3" tokio = { version = "1", features = ["rt-multi-thread", "macros", "sync", "time"] } anyhow = "1" url = "2" rand = "0.8" env_logger = "0.11" # The desktop capture stack. cpal is named only so the `pipewire` feature above # can reach it — nothing here calls cpal; moq-media does, and a feature is how # you reach a dependency's dependency. [target.'cfg(not(target_os = "android"))'.dependencies] cpal = "0.18.1" # V4L2 capture: the fallback path for cameras rusty-capture mishandles. v4l2r = "0.0.7" # The camera, on a machine that has one behind an ioctl. iroh-live = { git = "https://github.com/n0-computer/iroh-live", rev = "c329850759740e3c9c27391258a66196c1a74a22", default-features = false, features = [ "capture-camera", ] } # The phone. Audio needs nothing named here — cpal's AAudio host is what it # builds on Android, and moq-media pulls cpal in either way. [target.'cfg(target_os = "android")'.dependencies] # Camera2 is Java, and `android_camera` is the JNI half of reaching it. 0.22 to # match the version libvidya binds against, so one APK holds one `jni`. jni = "0.22" # Not for this crate's own use: cpal's AAudio host reads the JavaVM out of # `ndk_context`, and its handles live in a `static` that nothing in *this* # object has ever set. `android_jni` fills it in from the same pair the glue # hands over. See the note there. ndk-context = "0.1" # NOT `capture-camera`: rusty-capture is V4L2 and friends, none of which the # phone has. The `android` feature is a different thing — it links `ndk`, which # rusty-codecs' `format.rs` references under `cfg(android)` for the MediaCodec # path, and without it the crate fails on its own imports. iroh-live = { git = "https://github.com/n0-computer/iroh-live", rev = "c329850759740e3c9c27391258a66196c1a74a22", default-features = false, features = [ "android", ] }