| Filename | Latest commit message | Latest commit date |
|---|---|---|
|
Some checks failed
wai-app and Create / wai-app · does this change touch it (push) Successful in 17s
joule-moq-web browser client / joule-moq-web · does this change touch it (push) Successful in 16s
joule-moq-room room service / joule-moq-room · does this change touch it (push) Successful in 36s
joule-moq-remote host agent / joule-moq-remote · does this change touch it (push) Successful in 39s
wai-audit collector and player integration / does this change touch it (push) Successful in 21s
WAI operation catalogue / does this change touch it (push) Successful in 21s
wai-ledger service / does this change touch it (push) Successful in 19s
wai-fleet service / does this change touch it (push) Successful in 20s
wai-quantum studio and desktop / does this change touch it (push) Successful in 21s
wai-quantum for JavaScript / does this change touch it (push) Successful in 22s
wai-sink-swift native sink package / does this change touch it (push) Successful in 21s
wai-sink-android native sink library / does this change touch it (push) Successful in 20s
WAI Studio / does this change touch it (push) Successful in 24s
repository checks / lockfiles, advisories, tests in CI, workflow hygiene, spec and section references, public text (push) Has been cancelled
WAI operation catalogue / the catalogue and every door · linux (push) Has been cancelled
wai-sink-android native sink library / the JNI layer and the platform-free half on the host JVM · linux-arm64 (push) Has been cancelled
wai-sink-android native sink library / every ABI, the AAR, and the instrumented tests in a headless emulator · macos (push) Has been cancelled
joule-code conformance gate / joule-moq-relay, its own energy on a counter (macos) (push) Successful in 43s
joule-moq-remote host agent / joule-moq-remote, every target (macos) (push) Successful in 1m11s
wai-fleet service / service · macos (push) Successful in 1m2s
wai-audit collector and player integration / collector, player integration and the browser end to end · macos (push) Successful in 1m28s
wai-ledger service / service · macos (push) Successful in 1m34s
wai-app and Create / wai-app · Create, browser end-to-end (macos) (push) Successful in 6m8s
wai-quantum studio and desktop / desktop app · macos (push) Successful in 4m12s
WAI Studio / Studio in Chromium and Firefox · macos (push) Successful in 9m11s
wai-sink-swift native sink package / libwai slices, desktop tests, simulator tests · macos (push) Successful in 11m10s
joule-moq-web browser client / joule-moq-web · browser end-to-end (macos) (push) Successful in 15m15s
wai release binaries build on Windows / the seven release binaries · windows (push) Successful in 16m54s
wai-quantum studio and desktop / desktop app · windows (push) Successful in 10m27s
WAI breaking changes and the conformance runner / WAI breaking · does this change touch WAI (push) Successful in 11s
wai-app and Create / wai-app · tests, clippy, the line language's verifier (linux) (push) Successful in 49s
wai-audit collector and player integration / collector · linux (push) Successful in 1m33s
WAI Studio / the catalogue's actions, the unit tests and the core · linux (push) Successful in 57s
wai-ledger service / service · linux (push) Successful in 1m53s
wai-quantum for JavaScript / javascript · linux (push) Has been cancelled
WAI Studio / Studio in WebKit · linux (push) Has been cancelled
wai-quantum studio and desktop / desktop app · linux (push) Has been cancelled
wai-quantum studio and desktop / studio · browser (push) Has been cancelled
wai-fleet service / service · linux (push) Successful in 4m1s
joule-code conformance gate / Build + round-trip C1-C4 vectors (push) Successful in 5m4s
WAI breaking changes and the conformance runner / WAI breaking · wire, record and API against main · linux (push) Successful in 2m46s
WAI breaking changes and the conformance runner / WAI breaking and conform · their tests, and the independent verifiers through wai conform · linux (push) Successful in 7m20s
joule-moq-remote host agent / joule-moq-remote, every target (linux-arm64) (push) Has been cancelled
joule-moq-room room service / joule-moq-room, every target (push) Has been cancelled
joule-code conformance gate / joule-moq-relay, every target (push) Has been cancelled
joule-code conformance gate / joule-moq-ingest, every target (push) Has been cancelled
One release, four kinds of artefact, from wai-release.yml on a wai-v* tag: - C: each Linux job attaches libwai-<version>-<triple>.tar.gz for x86_64- and aarch64-unknown-linux-gnu (wai/quickstart/build-libwai.sh): lib/libwai.a, the feature native_sink, built for the glibc target without crt-static; the committed include/wai.h; lib/pkgconfig/wai.pc, relocatable, its Libs naming rustc's native-static-libs. Static, so a program carries it and looks for nothing at run time. Before the attach: the header the build regenerates is the committed one, the library defines exactly the envelope's and the native sink's functions, and a C program compiles, links and runs against the archive through pkg-config (wai/quickstart/test/c-library.sh). - Swift: Package.swift names WaiFFI by URL and checksum once a release has written them, and build/WaiFFI.xcframework while it is built there. The swift job attaches the zipped framework and wai-sink-swift-<version>.zip, the package naming it by download URL and SwiftPM checksum; scripts/check-release-package.sh resolves, builds and runs an application against it (before the attach through a mirror of the URL, after from the URL) and requires a wrong checksum to be refused. wai-sink-swift.yml runs the first on every change. - Kotlin: maven-publish as science.transaction.wai:wai-sink:<version>, manifest package science.transaction.wai.sink (the Kotlin classes keep wai.sink). The android job checks the publication (scripts/check-publication.sh), attaches the AAR and publishes it to the forge's Maven registry; wai-sink-android.yml writes and checks it on every change. - OCI: Containerfiles and check-image.sh for the relay and the room service (deploy/ beside each crate). The images job, on a runner labelled oci, builds and checks both and pushes them to the forge's container registry (wai/quickstart/release-images.sh, oci-push.py); an image that fails its check is not pushed. The forge's job token reads the organisation's packages and cannot write them, so the Maven publication and the images read the repository secret WAI_PACKAGES_TOKEN (scope write:package). Every upload goes to the forge over the private network. The release body names the new files. Co-Authored-By: Claude Opus 5.5 <[email protected]> |
||
| .. | ||
| scripts | ||
| Sources/WaiSink | ||
| TestHost | ||
| Tests/WaiSinkTests | ||
| .gitignore | ||
| Package.swift | ||
| README.md | ||
wai-sink-swift — the native sink for the platform player, in Swift
The native sink of extensions/native-sink.md for phones and
tablets, televisions and set-top boxes, and desktops whose native player an application reaches
from Swift. The player is not changed and decodes on the platform's media engine; the sink sits on
the path of its requests and, for one playback session:
- verifies a media playlist against its playlist receipt and the chain of its live revisions (http-delivery §8.6), and every object whose name states its content hash against that hash, and withholds from the player whatever does not verify;
- signs, under a fresh key per session, stream-audit's acknowledgements of every object received,
a presentation claim for each marked ad, and the session record, and posts the bundle to the
owner's collector (
wai-audit serve), with its Event-mode CMCD while it plays; - ends a session nobody can see, or whose viewer has gone idle, and stops the player's requests.
Everything that decides is libwai's C interface (native-sink §9), the same on every native
platform; this package is the platform's half: the loopback relay, the player, and the signals of
who can see it.
Layout
| path | what |
|---|---|
Package.swift |
the package: library WaiSink, binary target WaiFFI (the C interface): a release's framework by URL and checksum, or the one built here |
Sources/WaiSink/Sink.swift |
WaiSink: one session, every call of the C interface, JSON in and out |
Sources/WaiSink/Relay.swift |
WaiRelay: the loopback server the player is given (native-sink §4.4) |
Sources/WaiSink/PlayerSession.swift |
WaiPlayerSession: the platform player through the relay, observed every 200 ms (§5, §6) |
Sources/WaiSink/Attention.swift |
WaiViewAttention: whether the application is shown, the player view's area in view, the viewer's input (§6.2); WaiFixedAttention for hosts that decide it themselves |
Sources/WaiSink/Collector.swift |
WaiCollector: v1/sessions and v1/cmcd (stream-audit §12) |
scripts/build-xcframework.sh |
builds build/WaiFFI.xcframework from ../wai-rs |
scripts/package-release.sh |
the framework zipped, and the copy of the package that names the zip by URL and checksum, for a release |
scripts/check-release-package.sh |
that copy resolved, built and run as an application uses it, and refused with a wrong checksum |
scripts/test-simulator.sh |
runs the tests hosted in TestHost/ in a fresh simulator it creates, boots and deletes, every step under a hard limit |
Tests/WaiSinkTests |
the corpus through the wrapper; the relay over the reference package's floor; the player end to end |
TestHost/ |
a minimal application the same tests run inside on a phone or tablet, where no tool-hosted test bundle runs: an Xcode project that depends on this package by its path; consumers never see it |
Use
import WaiSink
let cfg = WaiSink.Config(channel: "news-east", owner: "<the collector's key, 64 hex>")
let session = try WaiPlayerSession(url: URL(string: "https://media.example/ch/7/v.m3u8")!,
config: cfg,
attention: WaiViewAttention(view: playerView),
collector: WaiCollector(base: URL(string: "https://collector.example/")!))
playerLayer.player = session.player // the host shows the player as it always has
session.onEnd = { bundle, ended in /* posted already; kept here if the host wants it */ }
session.start()
For a stream the owner's packager seals (playlist receipts, segments named by their SHA-256,
packaging §7), set requireSigned: true (or contentAddressed: true), and nothing the
publisher did not sign reaches the decoder. For a stream another service delivers, leave both
off: it is acknowledged and evidenced, never refused for what its names look like.
Build and test
On the build host (Xcode with the phone, television and desktop SDKs; Rust with the targets
scripts/build-xcframework.sh names):
cd wai/wai-sink-swift
scripts/build-xcframework.sh # every slice; WAI_SINK_SLICES="macos ios-sim" for some
swift test # the desktop: corpus, relay, player end to end
scripts/test-simulator.sh ios # the same tests, hosted in TestHost, in a fresh phone simulator
scripts/test-simulator.sh tvos # and in a fresh television simulator
On a phone or tablet, the tests run hosted in TestHost/ (signed with the team configured in Xcode):
xcodebuild build-for-testing -project TestHost/WaiSinkTestHost.xcodeproj -scheme WaiSinkTestHost \
-destination 'generic/platform=iOS' -allowProvisioningUpdates DEVELOPMENT_TEAM=<team>
xcodebuild test-without-building -xctestrun <the .xctestrun it wrote> -destination 'platform=iOS,id=<device>'
The player tests make their presentation at run time with the platform's own encoder (AVC, ISO/IEC 14496-10, in fragmented MP4, a segment a second), serve it from an origin on loopback, and play it through the relay with a video output attached, since no layer is on screen in a test.
Distribution
A release attaches WaiFFI-<version>.xcframework.zip, the framework with every slice, and
wai-sink-swift-<version>.zip, this package with its Package.swift naming that zip by its
download URL and its SwiftPM checksum (.binaryTarget(name: "WaiFFI", url: …, checksum: …),
the archive's SHA-256, as swift package compute-checksum gives it). scripts/package-release.sh
writes both. An application adds the package from that folder, as a local package or a copy in a
repository of its own; SwiftPM fetches the framework from the URL and refuses it unless its
checksum is the one named.
Before the release attaches them, scripts/check-release-package.sh resolves, builds and runs an
application that depends on the package, the framework served from the release's own files
through a mirror of its URL, and requires the package with one digit of its checksum changed to
be refused; once they are attached, it does both again from the URL itself. In this repository,
Package.swift names build/WaiFFI.xcframework while scripts/build-xcframework.sh has built it
there, so the tests run against the libwai of their checkout.
The library holds no codec: the platform's player decodes, and its codecs are the platform's, licensed with it.
Energy
The platform's player decodes in a process of the platform's, on its fixed-function decoder, which no counter an application can read covers. The session therefore states the sink decode and the display as the unmetered marker (native-sink §7), never the application's own counter as either.