Skip to content

Releases: OOI-RCA-APL/ceres

0.49.3

Choose a tag to compare

@jploskey jploskey released this 17 Oct 00:45

Engine

  • WebRTC sends video at the source's rate instead of pacing it to a bandwidth estimate, which
    held a 10 Mbit/s source 20 s behind live at fewer frames per second than HTTP. A network
    narrower than the source now makes every session skip to its next keyframe once a second of
    video waits to leave, so the picture stays within a second plus one keyframe interval of live.
  • Response compression leaves alone what a codec or an archive already compressed: video, audio,
    WOFF fonts, and zip, gzip, zstd, xz, bzip2, 7z and rar files. Another pass shrank none of them
    and spent the CPU a live video keeps busy. Text, JSON, uncompressed fonts and unknown binary
    data still compress, for the slow links ceres often runs behind.

Web Console

  • A WebRTC video whose browser stops decoding it, as when Chrome falls back to its
    NullVideoDecoder after a hardware decoder fault, reconnects after ten seconds and logs the
    decoder it had. On Auto, two such stalls within a minute switch the widget to HTTP.
  • Safari no longer reconnects a live HTTP video every few seconds. It read the stream's length
    from what it had buffered and ended playback at the newest frame, so the console now gives a
    stream that declares no length an endless duration.
  • Workspace edits follow the user across tabs and browsers. A tab writes its draft only when it
    holds an edit of its own, so reloading one no longer puts its older copy over a draft written
    elsewhere, and a tab with no edit of its own takes the newer draft once it is back in view.
    Two tabs both holding edits still to write each write theirs, and the last one wins.
  • The Transport setting reads Auto, WebRTC and HTTP, and the dialog says which one a video on
    Auto plays over, with the reason when it fell to HTTP.

0.49.2

Choose a tag to compare

@jploskey jploskey released this 16 Oct 18:48

Engine

  • WebRTC paces its media at the bandwidth it estimates the path to the browser has, rather than
    sending each keyframe at once, so a constrained path loses fewer packets and shows fewer
    freezes. A packet that finds the socket's send buffer full waits for it to drain rather than
    being dropped, and each session keeps 4096 sent packets to resend the ones the browser
    reports lost. A session logs a warning when its host's network falls so far behind that it
    drops a packet anyway, and one line on close with the packets it sent, the packets the
    browser lost, and its requests to resend them.
  • The WebRTC server's log lines reach the engine log, at the levels logging.output and
    logging.store keep. They went nowhere before, so a session that failed, ended, or never
    connected left no trace.

0.49.1

Choose a tag to compare

@jploskey jploskey released this 16 Oct 05:49

Engine

  • Websockets open over HTTPS again. A browser on an HTTP/2 connection opens its sockets with
    an extended CONNECT, which every socket route answered 405, so the web console showed no
    statuses or live updates when served over HTTPS.

0.49.0

Choose a tag to compare

@jploskey jploskey released this 16 Oct 03:27

Breaking

  • The server section names its listeners. server.bind replaces server.host,
    server.https (port, certificate, min-version) replaces server.ssl,
    and server.http (port, redirect) serves plain HTTP. server.host, server.port, and
    server.ssl are rejected, so rewrite them before upgrading. server.port: 8080 becomes
    server.http.port: 8080, or server.https.port: 8080 beside a former server.ssl. Its
    cert, key, and key-password move under certificate as path, key, and
    key-password, its version gives way to min-version, "1.2" by default or "1.3", and
    its ca-certs has no counterpart, so drop it.
  • The engine no longer creates a local/ directory in the project. A SQLite database still
    creates the directories leading to its file, and ceres service creates the directories of
    its log files.
  • The CLI finds a running engine through .ceres/server.json in the project instead of a file
    under /tmp, so restart a running engine after upgrading.
  • Serialized data objects name their fields as the YAML does, so API responses carry class
    rather than cls and an entity filter carries or and and rather than or__ and and__.
    Both spellings are still read.

Engine

  • A procedure's docstring is parsed, Google sections and Sphinx fields alike. Its arguments' text
    becomes their fields' descriptions in the arguments schema, the schema's description keeps only
    the prose, and procedures in the components listing carry returns and raises.
  • The server offers HTTP/2 over a server.https listener. Browsers then multiplex every
    console request over one connection, which lifts the six-connection limit that stalled a
    dashboard with more than a few live video widgets.
  • server.http.redirect turns the HTTP listener into one that temporarily redirects every
    request to the same path and query on the HTTPS listener, so http:// bookmarks keep
    working after a move to HTTPS.
  • An empty server.https section listens on port 443 with the certificate and key at
    .ceres/tls/server.crt and .ceres/tls/server.key. ceres check and startup fail when the
    certificate or key cannot be loaded, and name ceres generate certificate and
    certificate: auto when either file is missing.
  • server.https.certificate: auto has Ceres issue and renew the HTTPS certificate itself,
    signed by a certificate authority it creates once in .ceres/tls, or by the one auto.ca
    names, which has to exist, be allowed to sign certificates, and fit its key. Startup and a
    daily check issue a new certificate when it has less than 30 days left, or less than a third
    of its lifetime for one valid under 90 days, lacks a configured or detected name, or another
    authority signed it, and the running listener presents it without a restart. From 30 days
    before the authority itself expires, they warn that it needs replacing, since Ceres never
    renews it. auto takes ip, dns, and days, 365
    by default and at most 825.
  • Every listener serves a managed certificate's authority at /ca.crt, the redirecting one
    included, and the console's login page links to a page with the download, the authority's
    fingerprint, and steps for trusting it on each operating system.
  • Ceres keeps machine-local state in a .ceres directory next to ceres.yaml, which carries
    its own .gitignore.
  • rtsp() streams of one source share one connection to it when they use the same copy,
    transport, and stall_timeout, so a source allowing few sessions serves any number of
    viewers. A viewer joining starts from the latest keyframe, a viewer reading too slowly skips
    to the next keyframe and holds up no one else, and the connection stays open three
    seconds after its last viewer leaves so a reloaded page finds it open. A stream without
    reconnect ends on a lost source while the others reconnect.
  • rtsp() streams report what happens to the source as events: StreamLostEvent once per
    outage, StreamReconnectScheduledEvent for its first reconnect attempt,
    StreamReconnectedEvent with the attempts and length of the outage, and StreamEndedEvent
    when the stream ends on its own. A stream returned from a procedure reports on that
    procedure's component. Code reading rtsp() itself passes component= to get them.
  • Live video plays over WebRTC when the new server.webrtc section is present: port (UDP
    8189 at server.bind), hosts to advertise, max-sessions (32), and no-ice-timeout
    (10 s). A browser posts its offer to /api/components/{id}/procedures/{name}/whep for a
    procedure returning an rtsp() stream, and H.264 and H.265 are sent as the source sends them.
    Open the UDP port in the firewall, or every video plays over HTTP.
  • WebRTC refuses a source whose frames arrive out of display order, as B-frames make them, with
    409 reordered, since a browser would play them back and forth. ?reordered=drop drops the
    frames nothing references and sends the rest at a lower frame rate.
  • Moving a workspace to another component, or to the engine root, needs view on the destination
    for a private workspace and manage for a shared one. Widget addresses relative to the old
    component are rewritten so they keep pointing at the same components.

CLI

  • New ceres generate certificate issues the HTTPS certificate and key, an ECDSA P-256 pair
    signed by the certificate authority, naming localhost, the loopback addresses, the hostname,
    and the machine's interface addresses, or the auto names, plus any --ip and --dns
    names. Under certificate: auto it runs the issuance startup runs and only writes a
    certificate that is due, otherwise it refuses to replace existing files. --force replaces
    them either way and --days sets the lifetime, 365 days by default. It prints the authority
    to trust, the names, the expiry, and the SHA-256 fingerprint.
  • ceres check and engine startup warn when an HTTPS certificate Ceres does not manage expires
    within 30 days. Under certificate: auto, ceres check reports what startup is about to
    issue, and warns when the certificate authority expires within 30 days.
  • ceres run --development-source serves the engine over plain HTTP alone, leaving any
    server.https listener out, so the console dev server can proxy to it and a project
    without a certificate still runs.

Web Console

  • Video widgets reconnect on their own when the stream drops, ends, stands still for ten
    seconds, or never answers, at once and then every five seconds. The last frame stays up
    meanwhile, with a small countdown in the corner. A new "Reconnect" setting, on by default,
    brings back the error box instead.
  • Descriptions render as Markdown and are cut to three lines with a "Show more" when longer.
  • A procedure's docstring is split into its prose, its arguments' text, shown under each
    argument's field, and what it returns and raises, shown beside the result. Google sections and
    Sphinx fields are both read.
  • Control buttons can call queries as well as actions, under a "Procedure" field. A query's
    result shows under the arguments form when the button asks for arguments, or otherwise in a
    popup that can run the query again. A new query button runs without asking first. Queries
    returning a file or a stream are not offered.
  • The workspaces section says "No workspaces yet." with a create button for each kind of
    workspace on one line when it is empty, and an empty group shrinks to one line naming what
    it lacks. Create buttons sit beside their group's label.
  • A workspace's "Move" picks its location, the engine root or any component, and dragging a
    workspace onto a component in the sidebar moves it there.
  • A "Section" widget groups widgets under a collapsible header, beside tabs and carousel.
  • Live video plays over WebRTC where the server and browser allow, for the lowest latency, and
    otherwise over HTTP. A "Transport" setting picks "Automatic", "WebRTC", or "HTTP". The
    header names the transport, and clicking it cycles the setting. On "Automatic" the settings
    say why HTTP was chosen.
  • Live video over HTTP stays within seconds of its source. It plays faster, up to 3x, when
    behind, and jumps forward when more than five seconds behind.
  • Video widgets have their own controls: play, mute, a seek bar over the buffered video, a
    "Live" button that returns to the newest frame, and fullscreen. Space toggles play.
  • A video in a codec the browser cannot decode says which codec and what to try.
  • Cmd/Ctrl+S commits a workspace. A private workspace's commit can skip its confirmation, from
    the dialog or Preferences.
  • A widget with no component set uses its workspace's component, shown as "(Default)", and
    follows the workspace when it moves.

Fixes

  • Report every workspace commit. The console shows a toast while the commit runs, a success toast
    when it lands, and an error toast naming the cause when it fails. A commit or draft save the
    browser cannot send within 15 seconds, which happens when video widgets hold every connection
    the browser allows to the server, now fails with that message instead of hanging silently.
  • Dismissing the "Commit Changes" dialog with Escape no longer commits.
  • A procedure returning a stream or a file now reports how its call ended. A returned file
    completes the call. A returned stream ends it when it closes, with ProcedureCompletedEvent
    when it ran out, ProcedureExceptionEvent when reading it raised, and
    ProcedureCancelledEvent when it closed early, such as a client leaving a live video view.
    Before, such a call reported ProcedureCalledEvent and nothing after it.
  • Pressing a locked control button no longer opens its arguments popup as well as running it.

0.48.1

Choose a tag to compare

@jploskey jploskey released this 02 Oct 01:28

Fixes

  • Keep top-level components in configured order after a reload. A recreated component used to
    move to the end, so the console listed it after the components left alone.

0.48.0

Choose a tag to compare

@jploskey jploskey released this 01 Oct 18:57

Breaking

  • StreamingOutput.stream is no longer public. Read an output's bytes through
    async with output: async for chunk in output:.
  • BaseOutput.to_response() and OutputResponse are removed, and Ceres no longer depends on
    Starlette. Outputs are served by the Ceres server.
  • rtsp() no longer takes ffmpeg, tune, preset, or loglevel, since it streams through
    the FFmpeg built into Ceres.

Engine

  • Build FFmpeg 9.0.2 into Ceres and remux rtsp() streams in-process, so a host needs no
    ffmpeg on its PATH.
  • Re-encode with rtsp(copy=False) to H.264 through OpenH264 2.6.0, for 8-bit 4:2:0 sources.
  • Carry one MP4 stream across an rtsp() reconnect, ending it only when the codec, frame size,
    or codec parameters change.
  • Tag H.265 from rtsp() as hvc1, which Safari requires to play it.

Python API

  • StreamingOutput is an async context manager and an async iterable, so a procedure can read
    another's stream and its cleanup still runs (#174).
  • StreamingOutput takes http_filename, sent as Content-Disposition like FileOutput.

Web Console

  • Space the video widget's toggles in three even columns and the account page's in two.
  • Draw a boolean field without the presence bar. An unset optional boolean shows a dashed,
    empty track, and an error outlines the switch in red.

Packaging

  • Building from the sdist compiles the bundled FFmpeg and OpenH264, which needs a C and C++
    compiler, and an MSYS2 shell on Windows.

Development

  • Add ceres-rtsp-server, a test RTSP server that serves a built-in H.264 or H.265 clip and
    drops, stalls, refuses, or restarts on cue.
  • Run the release workflow with dry_run to build every wheel without publishing.

Fixes

  • Close a streaming output's producer as soon as the client leaves, which was left to garbage
    collection.
  • Stream rtsp() on hosts with FFmpeg older than 5, where -timeout opened a listening socket
    and no video played.

0.47.1

Choose a tag to compare

@jploskey jploskey released this 29 Sep 20:58

Fixes

  • Schedule a component's static pruner on Python 3.14, which failed with
    NameError: name 'PrunerConfig' is not defined.

Packaging

  • Require uuid-utils 1.0 or later, whose uuid7 takes only a keyword nanoseconds.

0.47.0

Choose a tag to compare

@jploskey jploskey released this 22 Aug 02:25

Web Console

  • Choose what shape each chart series is drawn in, so one chart can carry a line and a
    scatter together. An existing chart draws every series as a line until each one is set.
  • Draw a workspace's icon on every tab, shared as well as private, and mark an edited
    workspace beside it.
  • Show a tab's close button faintly at rest.

Fixes

  • Redraw a chart series when its shape changes, which left the chart empty until it was
    reloaded.
  • Reach zero from whichever side a chart's data leaves free when its axis is anchored there,
    so an all-negative series hangs from a zero at the top.
  • Draw a record view's connection filter with an icon that reads as a link rather than as a
    power plug.
  • Hold a color swatch round where the row it sits in runs out of room.

0.46.0

Choose a tag to compare

@jploskey jploskey released this 21 Aug 22:56

Engine

  • Record the connection a particle was parsed from, which a sieve bound to one connection
    fills in.
  • Give a connection a label and a description, the description defaulting to the
    docstring of the component field holding it.
  • Report the connections stamped on each particle type's records alongside its fields.
  • Index each record table's address alongside its timestamp, and alongside the level,
    connection, or direction a record view filters with it, so a filtered listing seeks its rows
    instead of reading back through every newer one. Migration 0010 builds these, holding each
    table closed to writes while it does, which takes minutes on a large history.
  • Answer a listing over a component's subtree as one ordered seek per branch, the branches read
    from the records so a decommissioned component's history is still reached.
  • Compile SQLite 3.51.3 into the engine, from 3.46.0.

Python API

  • Rename Source.label to Source.uri, which every source answers as a URI.
  • Accept several connections on @sieve, given separately or as a sequence.

Web Console

  • Show the connection a message or particle arrived on.
  • Filter a chart series group to one connection, and draw a line per connection for a type
    several of them produce.
  • Set how many decimal places a chart or meter reads a value to.
  • Fit a chart's Y axis to the shown series or to all of them, with a separate toggle for
    anchoring at zero.
  • Choose a connection for a meter.
  • Build a messages or particles view from a component's connections, dragged into a workspace
    or created from their context menu.
  • Build a particles view from a declared particle type the same way, selecting type headers
    with a held shift or command.
  • Build a controls widget from a component's actions, one button per action.
  • Peek a workspace into view when it is chosen from a list or from a docked tab strip.

Fixes

  • Draw every console icon from the bundle rather than fetching any from a public service,
    which left a console on an isolated network showing none of them.
  • Host the engine on the environment's own interpreter when running from a development
    source, rather than whichever one PATH offers.
  • Dismiss an inline rename opened from a menu when the pointer goes elsewhere.
  • Offer a record view's connection and address choices from the addresses its own filter
    reaches, rather than every one the engine carries.

0.45.2

Choose a tag to compare

@jploskey jploskey released this 20 Aug 02:00

Fixes

  • Reach a running engine directly over loopback, ignoring http_proxy and the
    resolver, so a proxied machine no longer reports it as stopped.