Skip to content

Migrate from MistServer

If you run MistServer today, you already run real media infrastructure. FrameWorks is not a drop-in replacement for every standalone MistServer workflow. It is a managed control plane and network layer around the same media-engine family, with MistServer at the edge and GraphQL, federation, analytics, billing, playback access control, and support tooling above it.

We co-maintain MistServer, so this guide starts with the uncomfortable but useful question: should you migrate at all?

Your situationBest fitWhere to start
Self-managed MistServer, full control, custom triggers, exec inputs, SCTE-35, multiview, wildcard streams, or raw JSON configStay on raw MistServermistserver.com - MistServer manual - GitHub
Your Mist or MistLoadBalancer footprint handles the media, but spike capacity is becoming operational workFrameWorks edge or hybrid path for burst capacityRun a FrameWorks edge
You already know how to do multi-region Mist, but want managed federation, telemetry, and routing controlsFrameWorks edge or hybrid path for geo coverageRun a FrameWorks edge
You want the full FrameWorks control plane, dashboard, analytics, and media stack, but on your own hardwareSovereign FrameWorks installRun full sovereign FrameWorks
You want to stop running the media engine and control planeFully managed FrameWorks SaaSMove to managed FrameWorks
You want to keep on-prem capture and add managed reachHybrid: keep Mist where it works, pull or federate outwardRun a FrameWorks edge
  • What stays: RTMP/RTMPS, E-RTMP, SRT, and WHIP ingest; HLS, LL-HLS, DASH, WebRTC/WHEP, MP4, WebM/MKV, and WebSocket playback; MistServer as the media edge.
  • What changes: Mist JSON config and HTTP API calls become GraphQL mutations; Mist triggers become GraphQL subscriptions or platform-managed webhook policies; per-node Prometheus becomes FrameWorks telemetry; pushStart and automatic pushes become stream-scoped push targets.
  • What you gain: cross-cluster routing, federation, managed GraphQL, sprite-sheet seek previews, ?jwt= playback auth across protocols, Skipper diagnostics, managed registration for Mist pull sources, wallet auth, MCP, x402, a sovereign GitOps/CLI path for the full platform, and a future marketplace path for operator-owned capacity.
  • What you give up: raw config portability, custom HTTP/exec triggers, exec inputs, FLV workflows, multiview compositor management, SCTE-35 insertion, JWT-on-ingest, wildcard stream inheritance, custom variables in recording paths, and direct Mist analyser workflows.

MistServer can scale beyond one box, and MistLoadBalancer can support serious multi-node deployments. The FrameWorks pitch is not “Mist cannot scale.” It is that the load-balancing layer has been refactored into Foghorn and wrapped in managed cluster inventory, tenant routing, telemetry, federation events, and operator workflows. When traffic spikes, you can keep hand-operating Mist capacity, or let FrameWorks place viewers across eligible edges using the managed control plane. See multi-cluster operations and the viewer routing architecture.

Raw MistServer plus MistLoadBalancer can already run large multi-region shows. FrameWorks is the managed version of that idea: Foghorn-to-Foghorn federation, stream advertisements, edge scoring, cross-cluster routing events, and dashboard/API visibility around the routing layer. Use it when you want the Mist media plane with less custom glue around regional placement. See multi-cluster operations and the federation architecture.

One branded URL across your own nodes + platform + marketplace capacity

Section titled “One branded URL across your own nodes + platform + marketplace capacity”

This is the bit no other managed video platform does, and it matters most for MistServer operators because you already run your own infrastructure.

Before (standalone MistServer): your viewers hit one server IP, or a DNS name you operate. Adding a second region means you either run another Mist + your own GeoDNS, or you build a load balancer in front. If a node goes down, the failover is whatever you wired by hand.

After (FrameWorks paid tier): your tenant gets a single branded hostname under our shared geo-routed DNS:

acme.cdn.frameworks.network
foghorn.acme.cdn.frameworks.network # HTTP playback (HLS, DASH, WHEP)
edge-ingest.acme.cdn.frameworks.network # RTMP / SRT / WHIP push
edge-egress.acme.cdn.frameworks.network # direct egress (SRT pull, etc.)

A single per-tenant TLS cert covers the whole namespace. The DNS smart record geo-routes viewers and streamers to the closest healthy edge across every cluster you subscribe to — your own self-hosted Mist nodes (running as a FrameWorks edge), any FrameWorks platform-official clusters you’ve enabled for burst coverage, and any third-party marketplace clusters you’ve added for regions you don’t operate. One URL, one cert, one operational view.

Bring your existing infrastructure in as a tenant_private cluster, optionally subscribe to one or two platform-official regions for failover or burst, and your acme.cdn.frameworks.network URL transparently spans all of it. When you add a new region (your own or via marketplace), DNS picks it up automatically — no client-side reconfiguration, no certificate juggling, no GeoDNS to operate.

For free / unbranded use, FrameWorks also exposes global root entrypoints (edge-ingest.frameworks.network, foghorn.frameworks.network, etc.) that geo-route across platform-official capacity only. See DNS architecture for the full URL tier model.

You can keep a Mist node where it already works and have FrameWorks pull from it over DTSC:

mutation CreateMistPullStream {
createStream(
input: {
name: "Existing Mist origin"
ingestMode: PULL
pullSource: {
sourceUri: "dtsc://mist-origin.example.com:4200/main?pass=shared-secret"
allowedClusters: { clusterIds: [] }
}
}
) {
... on Stream {
id
playbackId
}
}
}

DTSC is commonly exposed for Mist-to-Mist replication, but it is still a media replication endpoint. Use a DTSC passphrase, firewall it to the peers that need it, or place the FrameWorks edge where it can reach your Mist node locally. If the stream is not meant to be public, a self-hosted edge pulling from local Mist is usually cleaner than exposing a new public origin.

FrameWorks does not make pull inputs new; MistServer already does this by setting the stream source. What FrameWorks adds is a managed record for that source URI, encrypted storage, per-source placement rules, and an allow_private_pull_sources gate for self-hosted edges that may reach RFC1918 or multicast sources. See Pull-input streams.

MistServer supports a broad input surface: push inputs over RTMP, RTSP, SRT, WHIP/WebRTC, and DTSC; pull inputs over DTSC, RTSP, HLS, and TS-over-UDP or multicast; plus exec and file inputs. FrameWorks exposes the managed subset below.

MistServer featureFrameWorks path
RTMP / RTMPS / E-RTMP pushPush stream with the FrameWorks ingest URL and stream key
SRT pushPush stream with streamid carrying the stream key
WHIP pushStreamCrafter or direct WHIP URL, using MistServer’s /webrtc/{streamKey} path
RTSP pushHybrid/direct edge only when that port is intentionally exposed; not a managed SaaS ingest default
DTSC pull from another Mist nodeManaged pull-source record with dtsc://...; MistServer still performs the actual pull
RTSP pullManaged pull-source record with rtsp://...; MistServer still performs the actual pull
SRT / RIST pullManaged pull-source record with srt://... or rist://...; MistServer still performs the actual pull
HLS pullManaged pull-source record with an HTTP(S) .m3u8 source; MistServer still performs the actual pull
MPEG-TS over UDP / multicastManaged pull-source record with tsudp://...; private and multicast literals require eligible self-hosted edges
File inputUpload or manage VOD through FrameWorks APIs; raw local file inputs are not exposed as a managed stream source
Exec inputStay on raw MistServer or ask us to scope a managed input process
RTMP pullMistServer does not generally provide RTMP pull either; convert the source to SRT, RIST, RTSP, HLS, or DTSC first
FLV input / output workflowsMistServer supports FLV paths that are not exposed on the managed FrameWorks surface
MistServer outputFrameWorks path
HLS/play/{playbackId}/hls/index.m3u8
LL-HLS/play/{playbackId}/cmaf/index.m3u8
DASH/play/{playbackId}/cmaf/index.mpd
WebRTC / WHEP/play/{playbackId}/webrtc
MP4 progressive/play/{playbackId}.mp4
WebM/MKV, WS/MP4, and other direct Mist outputsAvailable where the edge exposes them and the source codecs fit; the managed player prefers the documented playback URLs

See Playback and Advanced Playback for the supported URL surface and player behavior.

If you use the bundled MistServer Meta-Player today, you can keep using it against a standalone Mist node. On FrameWorks, the recommended player is @livepeer-frameworks/player-*: a modern refactor from the same player lineage, with React, Svelte, Web Component, and vanilla packages. The original Meta-Player remains useful for fully custom standalone Mist deployments and some legacy output paths, such as FLV, that the FrameWorks player does not prioritize.

MistServer triggers can POST to URLs or execute local programs. Some are blocking and can change behavior. FrameWorks replaces the common event cases with GraphQL subscriptions and reserves blocking authorization for playback policies.

MistServer triggerFrameWorks path
STREAM_LOAD / stream lifecycleliveStreamEvents(streamId)
USER_NEW / USER_ENDliveConnectionEvents(streamId) for events, or playback policy for authorization
LIVE_TRACK_LISTliveTrackListUpdates(streamId)
RECORDING_END / DVR lifecycleliveDvrLifecycle(streamId) and liveClipLifecycle(streamId)
Push completion or failurePoll stream(id).pushTargets.status; no dedicated push subscription today
Custom HTTP trigger handlersStay on raw MistServer or ask us to scope a managed callback
Custom executable trigger handlersStay on raw MistServer
STREAM_BUFFER, STREAM_BITRATE, RTMP_PUSH_REWRITE, DEFAULT_STREAM custom routingStay on raw MistServer or ask us to scope a managed routing primitive

If your business logic depends on trigger scripts changing routing, rewriting pushes, or shelling out to local programs, stay on raw MistServer for that workload or ask us to scope a managed equivalent.

MistServer featureFrameWorks path
Manual push / pushStartcreatePushTarget(streamId, input) plus enabled target status
Automatic push when a stream goes liveStream-scoped push target; FrameWorks starts it when the stream is live
RTMP / RTMPS destinationSupported
SRT destinationSupported for custom targets
External writer URI targetsStay on raw MistServer when external writers are core to the workflow
Per-rendition target selectionNot exposed today
mutation Restream {
createPushTarget(
streamId: "stream-global-id"
input: {
platform: "custom"
name: "Backup SRT receiver"
targetUri: "srt://receiver.example.com:8889?streamid=main"
}
) {
id
status
}
}

See Multistreaming.

MistServer gives you low-level primitives: a DVR is usually a push to file plus playlist parameters such as m3u8=, split=, maxEntries=, targetAge=, append=, and noendlist. FrameWorks exposes higher-order video primitives instead: start recording, stop recording, create a clip, list the artifact, play it back, and let the platform handle storage paths and previews.

MistServer featureFrameWorks path
Record on stream startcreateStream(input: { name, record: true })
Start DVR laterstartDVR(streamId)
Stop DVRstopDVR(dvrHash)
Clip from live/DVRcreateClip(input)
HLS-compatible DVR segmentsFrameWorks DVR recording model
Sprite-sheet seek previewsGenerated automatically for streams, recordings, and clips
Custom path variables like $basename, $yday, $segmentCounterNot surfaced in managed storage paths
Direct MP4 recording as a push targetNot surfaced as a managed recording option
mutation StartDvr {
startDVR(streamId: "stream-global-id") {
... on DVRRequest {
id
dvrHash
playbackId
}
}
}

See Recordings and Thumbnails and Previews.

MistServer JWT support can authorize both contributors and viewers, including JWT-as-stream-name ingest flows. FrameWorks splits this into stream keys for ingest and playback policies for viewers.

MistServer featureFrameWorks path
Push passphrase / stream name gateStream-key validation
JWT-on-ingest with RTMP, SRT, or WHIP path/tokenStay on raw MistServer for JWT-on-ingest; FrameWorks uses stream keys
Viewer JWT as stream name, tkn parameter, or cookiePlayback policy with type: JWT; viewers usually attach ?jwt=
JWK/JWKS managementcreateSigningKey, revokeSigningKey, and setPlaybackPolicy
USER_NEW blocking trigger for viewer authorizationsetPlaybackPolicy with type: WEBHOOK
Public streamssetPlaybackPolicy with type: PUBLIC, or no restrictive policy
mutation ProtectStream {
setPlaybackPolicy(
input: {
streamId: "stream-global-id"
policy: { type: JWT, jwt: { allowedKids: ["signing-key-id"] } }
}
) {
... on Stream {
playbackPolicy {
type
}
}
}
}

See Playback Access Control.

Use this path when you want to keep your hardware and network position, but add FrameWorks control, routing, and analytics. This is the Mist-native route: the edge still runs MistServer, the engine you already know and that we co-maintain. Helmsman wraps it for config sync and trigger forwarding, while Foghorn handles validation, routing, federation, and telemetry.

Hybrid edges are available through the FrameWorks edge workflow, but they are more opinionated than raw MistServer because Helmsman syncs managed config from FrameWorks. If you need SDI workflows, UDP hole punching, custom trigger behavior, or direct Mist overrides, talk to us before treating the managed surface as a hard no.

  1. Inventory the Mist deployment you already run. Capture streams, exposed protocols, DTSC settings, pushes, trigger scripts, recording paths, JWT keys, MistLoadBalancer behavior, and which features are raw-Mist-only.
  2. Choose the relationship to FrameWorks. For a tenant-owned BYO edge, use frameworks edge deploy; for a provider/operator expanding an existing platform-managed cluster, use frameworks cluster nodes add.
  3. Provision on a separate box first. Do not replace your working Mist deployment on day one. Bring up the FrameWorks edge next to it so you can test routing, capacity, and pull behavior without risking the origin.
  4. Connect the media path. Either push directly into the FrameWorks edge, or configure a pull-input stream from your existing Mist deployment over DTSC, RTSP, SRT, RIST, HLS, or TS-over-UDP.
  5. Validate viewer routing. Watch the stream through FrameWorks playback URLs, confirm recordings and push targets if used, then compare viewer startup, rebuffering, and route selection against your current setup.
  6. Move traffic gradually. Switch player embeds, DNS, or encoder presets only after one full traffic cycle. Keep raw Mist available as rollback until the edge behavior is boring.

Tenant BYO edge path:

Terminal window
frameworks edge deploy --ssh [email protected] --email [email protected]

Attach a node to an existing platform-managed cluster:

Terminal window
frameworks cluster nodes add --ssh [email protected]

The cluster nodes add path requires a platform context with Quartermaster/Foghorn authority. BYO edge operators should use frameworks edge deploy, which goes through Bridge and an enrollment token instead of direct control-plane gRPC.

For hybrid edge nodes, the practical shape is MistServer plus Helmsman on your host, connected back to the FrameWorks network. You manage the edge box; FrameWorks manages the control plane. See Selfhosters, Connecting a node, and Edge nodes.

Use this path when you want the full FrameWorks experience on your own hardware, not just an attached edge. This is closer to operating a SaaS platform than operating MistServer: you run the control plane, media plane, data plane, dashboard, databases, Kafka, ClickHouse, and the backend Privateer mesh yourself.

Sovereign does not mean every subsystem is swappable today. The current stack is opinionated: crypto rails, wallet/x402 surfaces, Purser billing, and the Livepeer integration are part of the platform shape even when you run it yourself. Production deployments also still use S3-compatible object storage and managed DNS integrations; native Ceph-backed storage and self-hosted/Anycast DNS are on the roadmap. If you want FrameWorks without crypto, want to bring your own invoicing/billing system, or want to disable whole product areas instead of leaving them unused, talk to us first. Those are valid sovereign requirements, but the knobs are not all first-class yet.

The maintained workflow is GitOps plus the FrameWorks CLI:

  1. Check out or fork the GitOps repo. Your cluster manifests, host inventory, environment files, SOPS-encrypted secrets, release targets, and bootstrap overlays live there.
  2. Define the cluster manifest. Model central services, media clusters, hosts, domains, mesh identity, external services, and any bootstrap desired state.
  3. Validate the hosts. Run frameworks cluster detect against the manifest or GitOps checkout before provisioning.
  4. Provision with the CLI. The CLI reads GitOps, decrypts SOPS files when given an age key, applies schemas and migrations, provisions infrastructure, deploys services, seeds desired state, and verifies health.
  5. Operate through GitOps. Config changes become pull requests; frameworks cluster provision converges the approved state.

Local GitOps checkout:

Terminal window
frameworks cluster detect --gitops-dir gitops --cluster production
frameworks cluster provision --gitops-dir gitops --cluster production

GitHub-backed GitOps repo:

Terminal window
frameworks cluster provision \
--github-repo org/gitops \
--cluster production \
--age-key ~/.config/sops/age/keys.txt

See Deployment Overview, Cluster Manifest, External Services, Mesh Bootstrap, and Operations.

The cost of admission is real: this is materially heavier than a standalone Mist binary. You run the platform stack: Postgres, Kafka, ClickHouse, Redis where required, Quartermaster, Foghorn, Commodore, Decklog, Periscope, the dashboard, and the Privateer mesh for backend nodes. The direct manifest path is:

Terminal window
frameworks cluster provision --manifest cluster.yaml

Use Manual Deployment as the break-glass explainer for what the CLI configures, not as the preferred install path.

What you keep:

  • Your hardware, IP position, and data-egress policy.
  • Direct control over exposed edge ports.
  • The ability to place edges near venues, cameras, or private origins.

What you add:

  • Foghorn routing and federation.
  • GraphQL stream, playback, recording, and push-target management.
  • Cross-cluster artifact access for clips, DVR, and VOD.
  • FrameWorks player, access-control, thumbnail, analytics, and Skipper surfaces.

Use this path when you want to stop running the media engine and accept the managed surface.

  1. Inventory your MistServer setup. Export config, list streams, triggers, pushes, recordings, JWT keys, external writers, custom variables, and local scripts.
  2. Classify blockers. Anything in What you give up needs a replacement plan before you cut over.
  3. Create FrameWorks streams. Use the dashboard or createStream(input).
  4. Repoint encoders. RTMP/RTMPS, E-RTMP, SRT, and WHIP remain the normal managed ingest paths.
  5. Replace trigger scripts. Use subscriptions for events. For Mist USER_NEW authorization scripts, use setPlaybackPolicy with type: WEBHOOK so FrameWorks calls your authorization endpoint on viewer connect.
  6. Recreate push targets. Use createPushTarget(streamId, input) per stream.
  7. Recreate recording and DVR behavior. Use record: true or startDVR(streamId).
  8. Swap playback URLs or player code. If you use MistServer Meta-Player, either keep it with raw Mist or move to @livepeer-frameworks/player-* for the managed FrameWorks playback surface.
  9. Validate side by side. Run both systems for at least one full traffic cycle before changing production DNS, embeds, or encoder presets.
  • Direct JSON config editing and config-file portability.
  • Custom HTTP triggers and executable triggers.
  • Exec input, where arbitrary binaries pipe media into MistServer.
  • FLV input/output workflows exposed by raw MistServer but not by the managed FrameWorks surface.
  • Multiview compositor configuration and live layout control.
  • SCTE-35 marker insertion through Mist metadata POSTs.
  • Custom variables in recording paths.
  • JWT-on-ingest for RTMP, SRT, and WHIP.
  • Wildcard stream inheritance with stream+suffix.
  • External writer URI targets as a general-purpose recording/push surface.
  • Direct Mist analyser workflows on the managed plane.
  • Experimental C++ Foghorn / UDP hole-punching / NAT traversal workflows. If you use this, ask us; it is the kind of capability that should become explicit in MistServer and FrameWorks instead of staying an informal side path.
  • Cross-cluster routing and federation.
  • Managed GraphQL queries, mutations, and subscriptions.
  • Playback access control with ES256 signing keys and webhook policies.
  • Universal ?jwt= token transport for HLS, LL-HLS, DASH, WHEP, and MP4.
  • Managed source registration for Mist pull inputs, with encrypted URI storage and private-source opt-in on self-hosted edges.
  • Sprite-sheet seek previews for live, DVR, clips, and VOD.
  • Stream-scoped multistream targets with encrypted URI storage.
  • Skipper diagnostics for API questions, routing, rebuffering, and ingest issues.
  • Agent surfaces: MCP, wallet auth, and x402.
  • Cross-cluster artifact access through federation.
  • Cluster marketplace: publish cluster capacity, manage subscriptions, and route tenants through the same control plane.
  • Hybrid and self-hosted production cutovers need operator validation. Test DNS, TLS, firewall policy, capacity, node enrollment, and upgrade runbooks before moving production traffic.
  • Full self-hosting is materially heavier than one Mist binary. If you want sovereignty plus FrameWorks, budget for the platform services and operational footprint.
  • Sovereign installs are still opinionated. Purser does not yet act as a generic adapter for external billing/invoicing, crypto-oriented surfaces such as wallet auth and x402 are not fully removable product modules today, and native storage/DNS primitives are still roadmap work.
  • Marketplace primitives ship; the vetted public marketplace program is on the roadmap. Validate operator vetting, pricing, approval flow, and support boundaries before relying on third-party clusters for production traffic.
  • Billing rates are still maturing. Rates and allowances may change as the platform matures.
ChannelBest forWhere
SkipperAPI discovery, troubleshooting, diagnostics, after-hours helpDashboard /skipper - ⌘J in docs - MCP at /mcp
In-app ticketingAccount-specific questions, migration blockers, managed feature requestsDashboard /support
ForumLong-form Q&A and searchable recipesforum.frameworks.network
DiscordReal-time discussion and migration scopingJoin
GitHubBugs, feature requests, deeper technical reportsLivepeer-FrameWorks/monorepo
MistServer communityRaw MistServer configuration, standalone server workflows, and features FrameWorks does not exposemistserver.com - MistServer manual - DDVTech/mistserver