• v0.7.1 ce621d8021

    v0.7.1 Stable

    builduser released this 2026-09-07 04:32:38 +02:00 | 12 commits to main since this release

    Fixes the update check for anyone whose credential is an account password
    rather than an API token. See v0.7.0 for what is new.

    The check sent its credential as an API token and nothing else. Forges accept
    either scheme but not interchangeably: a token goes in the token header, while
    an account password only works as basic auth. Setting a username under Settings
    now selects basic auth; leaving it empty sends an API token as before.

    Found by exercising the whole path against the real release server rather than
    only a fake one: downloading a release, verifying it against the published
    checksums, unpacking it and running each binary to confirm it identifies
    itself. That test now runs whenever credentials are present.

    Downloads

    File For
    streamsink-0.7.1-linux-amd64.tar.gz Linux server, client and agent
    streamsink-0.7.1-windows-agent-amd64.zip Windows agent, headless
    streamsink-0.7.1-windows-server-amd64.zip Windows server and client, with the GTK4 runtime
    streamsink-0.7.1-windows-decoder-amd64.zip Windows decoder, for the program view
    SHA256SUMS checksums, used by the updater
    Downloads
  • v0.7.0 a3b576b4c3

    v0.7.0 Stable

    builduser released this 2026-09-07 04:29:04 +02:00 | 13 commits to main since this release

    Adds a desktop client for the machines running OBS, and update checking for
    the sink. Also fixes the virtual camera audio gap and the device contention
    that made the first camera device fail.

    A client with a window

    streamsink-client does the same work as streamsink-agent and is for the
    other kind of machine: an operator's, rather than a rack. It shows whether the
    sink is reachable, whether OBS is publishing, and above all whether capture
    times are coming from OBS's timeline or merely from packet arrival, which is
    the difference between a machine that stays in step and one that drifts. It
    also shows the address to paste into OBS, with a button to copy it.

    The headless agent is unchanged and remains the right choice for a service.

    Updates

    The sink checks for newer releases and says so in Settings. Installing is
    always a decision: replacing the program someone is relying on partway through
    an event is not something to do unasked.

    Downloads are verified against the SHA256SUMS published with each release
    from this version on, and the new binaries are made to run and identify
    themselves before anything is replaced. A release without checksums cannot be
    installed automatically, and a download that does not match is discarded. The
    previous binaries stay alongside with a .old suffix until the new version has
    started. A private repository needs a token, set under Settings.

    Audio for virtual cameras

    A v4l2 loopback carries video and nothing else, so a rig on virtual cameras had
    no sound. Each source can now also play into a virtual audio device, whose
    monitor OBS takes as an ordinary Audio Input Capture. Both outputs are driven
    by one ffmpeg process, so sound stays locked to picture.

    Audio devices need no privileges and the interface creates them directly.
    Camera devices need a kernel module, so that button asks through polkit and
    prints the command to run by hand if there is no agent to ask.

    Why the first camera device did not work

    Virtual video nodes were listed by their place in sysfs and offered regardless
    of what they were. A machine can have virtual video nodes that are not
    loopbacks, and OBS takes hold of video devices when it starts, so a device it
    grabbed before StreamSink was running could never be written to.

    Devices are now interrogated with VIDIOC_QUERYCAP, so only real v4l2loopback
    nodes that accept output are offered, and StreamSink names the process holding
    a device rather than reporting "busy". Setup also places devices at
    video_nr=10,11, clear of the numbers OBS reaches for, which removes the
    start-order dependency entirely.

    Check the whole path with:

    ./streamsink -check
    

    Downloads

    File For
    streamsink-0.7.0-linux-amd64.tar.gz Linux server, client and agent
    streamsink-0.7.0-windows-agent-amd64.zip Windows agent, headless
    streamsink-0.7.0-windows-server-amd64.zip Windows server and client, with the GTK4 runtime
    streamsink-0.7.0-windows-decoder-amd64.zip Windows decoder, for the program view
    SHA256SUMS checksums, used by the updater

    Still unverified

    Virtual camera output has not been exercised end to end here, because
    v4l2loopback is not installed on the build machine; -check tests it on a
    machine that has it. The virtual audio path is tested end to end against a
    real sound server. The Windows binaries have not been executed.

    Downloads
  • v0.6.0 339eff3c04

    v0.6.0 Stable

    builduser released this 2026-09-06 17:36:56 +02:00 | 15 commits to main since this release

    Fixes virtual camera output, which did not work even with v4l2loopback
    installed correctly, and adds a command to check the path end to end.

    Why it did not work

    Two faults, both on the restart path, both invisible until a decoder had
    failed once.

    A restart could never recover. Each ffmpeg session took whatever packet
    came next from the channel it already held. That is almost never a sequence
    header, so ffmpeg received a stream with no codec configuration, could not
    decode it, exited, and was restarted into the same position. Decoders now take
    a subscriber rather than a channel and open a fresh subscription for each
    process, so every one begins with the configuration and a keyframe.

    Restarts stole each other's packets. The camera output adapted its channel
    through a goroutine with no way to stop. Each restart started another, and the
    two then split the stream between them, so even a session that did start
    correctly was fed every second packet. It now stops with its session.

    Checking it

    ./streamsink -check
    

    Works through everything a virtual camera needs, in dependency order, stopping
    at the first thing that makes the rest moot: platform, ffmpeg and its v4l2
    support, the module, exclusive_caps, the devices, whether one can be opened
    for writing, and finally a round trip that writes a test pattern to the device
    and reads a frame back. That last step is the only one proving the path rather
    than a part of it. Every failure carries the command to fix it.

    Close OBS before running it: the round trip needs to read the device back, and
    will fail if something else holds it open. Use -check-device /dev/video1 to
    exercise a particular device.

    Downloads

    File For
    streamsink-0.6.0-linux-amd64.tar.gz Linux server and agent
    streamsink-0.6.0-windows-agent-amd64.zip Windows agent, for each OBS machine
    streamsink-0.6.0-windows-server-amd64.zip Windows server, with the GTK4 runtime
    streamsink-0.6.0-windows-decoder-amd64.zip Windows decoder, only for the program view

    Still unverified

    Virtual camera output has still not been exercised end to end here, because
    v4l2loopback is not installed on the build machine. -check exists to test
    exactly that on a machine which does have it. The Windows binaries have not
    been executed either; they are verified by construction and import analysis.

    Downloads
  • v0.5.0 8d8eec48dc

    v0.5.0 Stable

    builduser released this 2026-09-06 07:00:49 +02:00 | 16 commits to main since this release

    Receives live streams from several machines running OBS, holds them until they
    line up, and passes them on synchronised.

    RTMP timestamps restart at zero on every connection and carry no shared
    reference, so a sink receiving several feeds cannot tell which frames were
    captured at the same instant. A small agent runs beside each OBS: it keeps
    an NTP-style clock offset against the sink, and reads capture times from OBS's
    own timeline over obs-websocket rather than guessing from when packets arrive.
    Nothing is transcoded on the relay path; encoded media is passed through byte
    for byte.

    Getting the output into OBS

    Delivery is usually where multi-camera rigs come apart: a player pulling a
    stream applies its own buffering, two players buffer differently, and feeds
    that left in step arrive out of step. Three options, best first:

    • Virtual camera (Linux) — each source becomes an ordinary Video Capture
      Device at its own resolution, with nothing buffering it on the way in.
      Needs v4l2loopback, the same module OBS uses for its own virtual camera.
    • Program view — sources decoded and drawn into a window for OBS to
      capture. Tiled into one window, or one window each. Works on both platforms.
    • RTMP push or pull — for a downstream that is not OBS. Subject to
      whatever buffering that downstream applies.

    Downloads

    File For
    streamsink-0.5.0-linux-amd64.tar.gz Linux server and agent
    streamsink-0.5.0-windows-agent-amd64.zip Windows agent, for each OBS machine
    streamsink-0.5.0-windows-server-amd64.zip Windows server, with the GTK4 runtime
    streamsink-0.5.0-windows-decoder-amd64.zip Windows decoder, only for the program view

    Run streamsink.exe from inside its extracted folder; GTK loads its runtime
    from alongside it. For the program view, extract the decoder archive into that
    same folder. The Linux server needs GTK4 installed; the agent is static and
    needs nothing.

    Known limitations

    • Virtual cameras are Linux only. On Windows a camera is a signed driver
      registered with administrator rights, which an application cannot supply.
    • Virtual camera output is untested end to end. v4l2loopback was not
      available on the build machine. Device discovery, permission and
      configuration checks are tested; ffmpeg writing frames into a loopback node
      is not.
    • The Windows binaries have not been executed. They are verified by
      construction and by import analysis over every bundled binary, not by
      launching them.
    • Sync reaches back as far as OBS, and no further. A capture card holding
      frames or a camera's own processing delay is invisible to StreamSink; the
      per-source offset exists for that residual.
    • Relay, not transcode. Every source must already be in a format the
      downstream accepts.
    Downloads