Skip to content

chrisgherbert/backchannel

Repository files navigation

Back Channel

Bridge livestreams to RTMP & HLS on macOS.

Website · GitHub Releases · Issues

Back Channel is a macOS app for turning livestream URLs into RTMP or HLS outputs that fit into production workflows. It is designed for producers, newsroom teams, and technical creators who need a dependable bridge between web livestreams and downstream ingest systems.

At a Glance

  • Converts livestream URLs into RTMP or HLS output
  • Supports both GUI and CLI workflows
  • Bundles its own core native tooling for end-user installs
  • Offers a managed Python source runtime for yt-dlp + Streamlink, plus managed support updates
  • Built for Apple Silicon Macs running macOS 13 or later

Website

The marketing/documentation site deploys automatically through GitHub Actions when changes under website/ are pushed to main.

Release Checklist

  1. Ensure standalone deno exists for managed support payloads.
  2. Optional: set a portable Python runtime URL/archive for the managed Python source runtime build, or let the script use its tested default.
  3. Create/update private release config:
cp -n scripts/release.env.example scripts/release.env
  1. Fill scripts/release.env required values (DEV_ID_APP, AC_PROFILE, DENO_BINARY).
  2. Run full signed + notarized GitHub release:
./scripts/github_release.sh --version X.Y.Z --notes-file /absolute/path/to/release-notes.md
  1. To publish newer managed support payloads without cutting a full app release:
./scripts/publish_managed_support.sh
  1. Confirm the GitHub app release includes:
  • app zip
  • app zip checksum
  • backchannel-managed-support.json
  • managed Python source runtime archive + checksum
  • managed deno archive + checksum
  1. Confirm the dedicated managed-support release was updated with the same managed assets.
  2. Distribute:
open dist

Prerequisites

  • macOS 13+
  • portable ffmpeg / ffprobe binaries available for packaging
  • standalone deno binary available for managed support packaging
  • optional portable Python runtime archive/URL for managed Python source runtime packaging

These are release-time/build-time requirements, not end-user runtime requirements. The shipped app bundles or manages its own dependencies.

Run

swift run

Build & Release Workflows

1. Local Development Build

Fast local build:

swift build

Run directly from source:

swift run

Build Self-Contained .app

This creates dist/Back Channel.app and bundles the stable native tools ffmpeg and ffprobe into:

Contents/Resources/bin/

It also bundles a CLI launcher and installer:

  • Contents/Resources/bin/backchannel
  • Contents/Resources/bin/install-cli.sh
./scripts/package_app.sh

App icon (optional):

  • Drop assets/AppIcon.png (or assets/AppIcon.icns) before packaging.
  • The script will automatically convert PNG to .icns.

You can override tool paths:

FFMPEG_BINARY=/path/to/ffmpeg FFPROBE_BINARY=/path/to/ffprobe APP_ICON_FILE=/path/to/icon.png ./scripts/package_app.sh

Install terminal command from the packaged app:

"/Users/herbert/web/youtube-live-converter/dist/Back Channel.app/Contents/Resources/bin/install-cli.sh"

This installs to ~/.local/bin/backchannel by default (no sudo). For a system-wide install, override target dir:

CLI_TARGET_DIR=/usr/local/bin "/Users/herbert/web/youtube-live-converter/dist/Back Channel.app/Contents/Resources/bin/install-cli.sh"

Then run:

backchannel --help

The managed Python source runtime (yt-dlp + Streamlink) and deno are both managed separately as app support components rather than being sealed inside the .app bundle.

2. Packaging For Local Testing

Use the packaging script directly:

./scripts/package_app.sh

It will:

  1. Build release binary.
  2. Create dist/Back Channel.app.
  3. Bundle required native tools into Contents/Resources/bin.
  4. Apply ad-hoc signing (for local execution).

3. Signed + Notarized Release

Use the current release pipeline scripts:

First-time setup:

cp scripts/release.env.example scripts/release.env

Fill required values in scripts/release.env:

  • DEV_ID_APP
  • AC_PROFILE
  • DENO_BINARY (standalone Mach-O binary for managed support payloads)

Optional managed-runtime settings:

  • PYTHON_STANDALONE_URL or PYTHON_STANDALONE_ARCHIVE
  • YTDLP_PACKAGE_SPEC

Create a notarized local release build:

./scripts/notarize_release.sh

Create or update the GitHub release, including managed support assets:

./scripts/github_release.sh --version X.Y.Z --notes-file /absolute/path/to/release-notes.md

The GitHub release script uploads:

  • notarized app zip
  • app zip checksum
  • managed support manifest
  • managed Python source runtime archive + checksum
  • managed deno archive + checksum

It also republishes those managed support assets to the dedicated managed-support release channel so the app can pick up newer source-runtime / deno payloads without waiting for a new app build.

If you only want to refresh managed support payloads:

./scripts/publish_managed_support.sh

4. Manual Notarization (Reference)

If you need to run manual notarization steps instead of scripts/notarize_release.sh:

codesign --force --options runtime --timestamp --sign "Developer ID Application: <Name> (<TEAMID>)" "dist/Back Channel.app"
ditto -c -k --keepParent "dist/Back Channel.app" "dist/Back-Channel.zip"
xcrun notarytool submit "dist/Back-Channel.zip" --keychain-profile "<profile>" --wait
xcrun stapler staple "dist/Back Channel.app"
xcrun stapler validate "dist/Back Channel.app"

Usage

  1. Enter source livestream URL.
  2. Click Load Info to fetch and preview title/thumbnail/description excerpt.
  3. Choose output format:
    • RTMP for push targets (rtmp://server/app/key)
    • HLS for local/served playlist output (/path/to/out.m3u8)
  4. For RTMP, either:
    • fill Server URL + Stream Key, or
    • paste a full RTMP URL in Full RTMP URL (optional override)
  5. Choose mode:
    • Stream Copy for lowest CPU on RTMP (Streamlink -> FFmpeg remux, best-effort passthrough)
    • Compatible for RTMP resync/transcode (Streamlink -> single FFmpeg resync/transcode, libx264 + aac, fixed GOP/CFR)
  6. Click Start.
  7. Use Status tab for parsed health/progress, and Advanced tab for raw console logs.

Repository Layout

Notes

  • The app captures source-tool (Streamlink or yt-dlp) and ffmpeg stderr logs in the UI.
  • On process failure, it retries with exponential backoff (up to 30 seconds).
  • For RTMP, Compatible uses Streamlink plus a single FFmpeg resync/transcode stage.
  • Stream Copy may fail if target/container codec compatibility does not match. Use Compatible mode in that case.
  • Runtime tool resolution prefers:
    • app-managed support components in ~/Library/Application Support/Back Channel/
    • bundled app resources in .app/Contents/Resources/bin
  • End users do not need Homebrew, Python, Xcode command line tools, or manually installed runtimes.

About

Converts livestreams into RTMP or HLS output

Resources

Stars

Watchers

Forks

Packages

 
 
 

Contributors