Skip to content

Releases: oxygenframe/oxframe-sdk

v0.23.8: Release 0.23.8: checks in the browser build (#45)

Choose a tag to compare

@github-actions github-actions released this 25 Oct 21:20
6187927

Added

  • The browser build of a project can run the checks: the wasm module exports
    check (the report and the storyboard PNG), inspect and a frame as PNG.
    The remote MCP server at mcp.oxframe.dev uses them to check a scene
    without a local install.

v0.23.7: Release 0.23.7: recorded voice-overs (#43)

Choose a tag to compare

@github-actions github-actions released this 25 Oct 19:47
6b7d678

Added

  • Voice-overs you recorded yourself: voice("…").recording("vo/intro.wav")
    plays the file instead of calling a speech provider, and the line lasts as
    long as the file. oxframe transcribe vo/intro.wav (oxframe-cli) times
    its words with whisper.cpp on your machine and writes
    vo/intro.words.json, so line.at_word("…") and .caption() follow the
    recording. Without that file the words are spread over its length.

v0.23.6: Release 0.23.6: keep MixRequest compatible; check-semver (#41)

Choose a tag to compare

@github-actions github-actions released this 25 Oct 15:42
92942f1

Fixed

  • Projects on oxframe 0.23.0–0.23.4 build again. 0.23.5 added a field to
    oxframe_export::MixRequest, and since a project's oxframe-export
    resolves to the newest 0.23.x, the older oxframe stopped compiling. The
    target loudness is now an argument: oxframe_export::mix_with_loudness.
    0.23.5 is yanked; oxframe upgrade moves a project to 0.23.6.

v0.23.5: Release 0.23.5 (#40)

Choose a tag to compare

@github-actions github-actions released this 25 Oct 14:42
2bbf9c4

Added

  • No ffmpeg installed? oxframe render downloads a static build once into
    the oxframe cache and uses it (oxframe-cli); oxframe ffmpeg does it
    ahead of time.

  • Six more blocks for oxframe add (oxframe-cli), 24 in all: metric-row,
    key-combo, steps, social-post, split-screen and search-bar.

  • voice("…").caption(): the line is shown at the bottom of the frame
    while it is spoken, up to seven words at a time, each part on screen
    while its words are said (word timings from the provider, or the
    estimate). Captions burned into the video, for feeds that play muted.

  • oxframe check: most issues carry fix, the change that clears them with
    the numbers worked out — move by dx/dy pixels, shrink to a size,
    a text color (the same hue, lightened or darkened) and the contrast it
    reaches, widen by pixels or a font_scale, hold or slow in seconds.
    The hints say the same in words ("Move it 140 px to the left"). lint::Fix
    in Rust.

  • Project::loudness, say at -14 LUFS: the rendered sound (music, voice
    and effects) is brought to that integrated loudness (EBU R128) before the
    -1 dBFS limiter, so a video plays as loud as others on YouTube or in a feed.
    render prints the loudness of every mix; oxframe_export::loudness
    measures one.

  • GIF export: render --format gif (or --out demo.gif) writes a looping
    GIF with one palette for the whole clip and an ordered dither that does
    not shimmer. It is 720 pixels wide and 15 fps unless --size and --fps
    say otherwise; frames are taken from the project's rate, so only the
    frames the GIF shows are rendered. No sound. Format::Gif in
    oxframe-export.

v0.23.4: Release 0.23.4 (#33)

Choose a tag to compare

@github-actions github-actions released this 25 Oct 12:38
08c7414

Added

  • oxframe mcp --dir (oxframe-cli): serve the project at a given path, not the
    current directory, for MCP clients that start servers elsewhere.

Fixed

  • oxframe check no longer reports dead_time while a Video plays: the
    clip frame it shows counts as change (inspect lists it as the frame
    param). A paused or finished clip still counts as a still shot.

v0.23.3: Merge pull request #31 from oxygenframe/release-0.23.3

Choose a tag to compare

@github-actions github-actions released this 24 Oct 22:16
7f60a60

Added

  • Six more blocks for oxframe add (oxframe-cli): feature-grid,
    checklist, comparison, chat-messages, pull-request and
    countdown, eighteen in all, every one passing oxframe check.
  • The agent skill: a request to explain or show something means a scene,
    not an answer in chat; hints for the compile errors seen most in the
    0.23.2 agent eval. No SDK code changed.

v0.23.2: Merge pull request #30 from oxygenframe/release-0.23.2

Choose a tag to compare

@github-actions github-actions released this 24 Oct 20:04
a6dbc29

Added

  • oxframe publish (oxframe-cli): renders the project, or takes an MP4,
    uploads it to oxframe.dev and prints a link with a player that unfolds as
    a video in Discord and Slack. Up to 30 s and 16 MB (a larger render is
    re-encoded at 720p); kept for 30 days. --title names the page. No SDK
    code changed; the agent skill knows the command.

v0.23.1: Merge pull request #29 from oxygenframe/release/0.23.1

Choose a tag to compare

@github-actions github-actions released this 24 Oct 14:11
c878dc2

Added

  • Custom WGSL shaders (Shader::source, Shader::file, and their
    Input::frame() and Input::node inputs) paint in the browser
    playground too: the CPU interpreter is built for wasm. A 1080p frame
    takes about 0.3 s there; playback skips frames to keep time. The browser
    bundle grows by about 360 KB gzipped.

v0.23.0

Choose a tag to compare

@github-actions github-actions released this 24 Oct 10:36
4c18bc6

Added

  • Components convert to Node (From<X> and From<&X>): Axes, Callout,
    CodeExplainer, FlowDiagram, LowerThird, ChapterMarker, Matrix,
    Table, TitleCard, EndCard, BulletList go wherever a node does, e.g.
    caption.next_to(&end_card, Side::Bottom).
  • Txt::font_size, Txt::weight and Code::font_size take integers too:
    .font_size(64).
  • .scale(..) on a builder takes one number, a pair or a Vec2:
    .scale(1.5), .scale((2.0, 0.5)), .scale(2).
  • oxframe check: low_contrast reads the pixels behind text that lies
    over a shader, an image, a video, Custom, particles or 3D. The frame is
    drawn without text and the ratio is the median over the text's box; it
    must last 0.5 s to count, so something moving past a label is not
    reported. Text over plain fills is judged as before.
  • A custom WGSL shade (Shader::source, Shader::file) is painted, not
    only checked: an interpreter over naga's IR runs it on the CPU, a tile of
    pixels at a time, with the same bytes on every OS (about 0.13 s for a
    1080p frame in a release build). Textures, samplers and derivatives are
    a shader_error. The playground does not paint it.
  • Inputs of a custom shader: .input("photo", Input::file("photo.png"))
    (or Input::image(include_bytes!(..))) is read in WGSL with
    sample_photo(uv). With .input("scene", Input::frame()) the shader
    reads what was drawn before it and is painted over it inside its box,
    e.g. sample_scene(i.screen / ox.resolution). Calling sample_x with no
    input x is a shader_error that says how to add it.
  • Shader::size(width, height), like width and height together.
  • Example magnifier: a lens written in WGSL that reads the frame.
  • .offscreen() on any node: it is drawn only for a shader that reads it
    with Input::node(handle) (sample_<name>(uv), uv across the node's
    box), never on screen, and check skips it.

Changed

  • lens_drops, node.effect(..) and a frame-reading shader work inside a
    group with opacity below 1, a blur, a clip, a blend, a shadow or another
    effect. The group is drawn in parts on its own, then faded or blurred as
    a whole; a shader in it reads what the group drew before it. check no
    longer reports input_cycle.

Fixed

  • check no longer reports covers_text for a custom shader that reads
    the frame (Input::frame()): the text shows through it, as under
    lens_drops. InspectNode has a reads_frame field.
  • A vector's label (axes.vector(..).label("i")) sits off to the side of
    the tip, so a vector along an axis no longer puts its label on the axis
    line.

Breaking

  • Signal::set takes impl Into<T>, like Signal::to, so
    text.set("Done") and fill.set(Accent) work. A value converted with a
    bare .into() no longer infers its type: drop the .into().
    Before: m.cell(0, 1).text().set("7".into()); → after:
    m.cell(0, 1).text().set("7");
  • Node::scale() returns ScaleSignal, a Signal<Vec2> (it derefs to one)
    whose to and set also take one number for both axes:
    node.scale().to(1.2, 0.3). Code that names the type changes.
    Before: let s: Signal<Vec2> = node.scale(); → after:
    let s: Signal<Vec2> = node.scale().signal(); (or .into()).
  • lint::Sample has a contrast field (measured contrast per text node).
    Before: Sample { time, nodes } → after:
    Sample { time, nodes, contrast: Vec::new() }.
  • Input is no longer Copy (it can hold an image); Input::name takes
    &self. Clone it where it was copied.
  • InspectNode has a reads_frame field; add reads_frame: false where
    you build one.

v0.22.0

Choose a tag to compare

@github-actions github-actions released this 23 Oct 18:13
4551854

Added

  • oxframe check --against (a directory) compares this check's frames with an
    earlier oxframe check --frames output: each frame that changed gets a
    share of changed pixels and diff/<time>.png, the frame dimmed with the
    changed pixels in red; report.json gets a comparison (changed, the
    same, added, removed). Check whether an edit changed only what it meant to.
  • oxframe check reports where things move: report.json gets motion,
    each node that travels with its file:line, the stretches of time it
    moves visibly (moves, its keyframes), where it starts and ends, and the
    length of its path; a child that only rides with its parent is left out.
    out/check/trajectories/<scene>.png draws the paths on the scene's last
    frame, numbered as in motion.
  • The storyboard shows both sides of a hard cut between scenes: the last
    frame of a scene and the first of the next.
  • Image::decode_png.
  • The quickstart example: install, oxframe init and oxframe render in a
    terminal, then the rendered scene plays. It is the animation in the
    README's quickstart (scripts/readme-gif.sh makes the GIF).

Tested

  • CPU frames are byte-for-byte the same on Linux (x86_64 and arm64), macOS
    (Apple Silicon) and Windows: CI renders ten examples on each and compares
    the hashes.