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?
Pick the right path
Section titled “Pick the right path”| Your situation | Best fit | Where to start |
|---|---|---|
| Self-managed MistServer, full control, custom triggers, exec inputs, SCTE-35, multiview, wildcard streams, or raw JSON config | Stay on raw MistServer | mistserver.com - MistServer manual - GitHub |
| Your Mist or MistLoadBalancer footprint handles the media, but spike capacity is becoming operational work | FrameWorks edge or hybrid path for burst capacity | Run a FrameWorks edge |
| You already know how to do multi-region Mist, but want managed federation, telemetry, and routing controls | FrameWorks edge or hybrid path for geo coverage | Run a FrameWorks edge |
| You want the full FrameWorks control plane, dashboard, analytics, and media stack, but on your own hardware | Sovereign FrameWorks install | Run full sovereign FrameWorks |
| You want to stop running the media engine and control plane | Fully managed FrameWorks SaaS | Move to managed FrameWorks |
| You want to keep on-prem capture and add managed reach | Hybrid: keep Mist where it works, pull or federate outward | Run 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;
pushStartand 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.
Why a Mist operator might use FrameWorks
Section titled “Why a Mist operator might use FrameWorks”Burst capacity
Section titled “Burst capacity”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.
Geo coverage
Section titled “Geo coverage”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.networkfoghorn.acme.cdn.frameworks.network # HTTP playback (HLS, DASH, WHEP)edge-ingest.acme.cdn.frameworks.network # RTMP / SRT / WHIP pushedge-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.
Hybrid reach
Section titled “Hybrid reach”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.
Translation tables
Section titled “Translation tables”Ingest and pull inputs
Section titled “Ingest and pull inputs”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 feature | FrameWorks path |
|---|---|
| RTMP / RTMPS / E-RTMP push | Push stream with the FrameWorks ingest URL and stream key |
| SRT push | Push stream with streamid carrying the stream key |
| WHIP push | StreamCrafter or direct WHIP URL, using MistServer’s /webrtc/{streamKey} path |
| RTSP push | Hybrid/direct edge only when that port is intentionally exposed; not a managed SaaS ingest default |
| DTSC pull from another Mist node | Managed pull-source record with dtsc://...; MistServer still performs the actual pull |
| RTSP pull | Managed pull-source record with rtsp://...; MistServer still performs the actual pull |
| SRT / RIST pull | Managed pull-source record with srt://... or rist://...; MistServer still performs the actual pull |
| HLS pull | Managed pull-source record with an HTTP(S) .m3u8 source; MistServer still performs the actual pull |
| MPEG-TS over UDP / multicast | Managed pull-source record with tsudp://...; private and multicast literals require eligible self-hosted edges |
| File input | Upload or manage VOD through FrameWorks APIs; raw local file inputs are not exposed as a managed stream source |
| Exec input | Stay on raw MistServer or ask us to scope a managed input process |
| RTMP pull | MistServer does not generally provide RTMP pull either; convert the source to SRT, RIST, RTSP, HLS, or DTSC first |
| FLV input / output workflows | MistServer supports FLV paths that are not exposed on the managed FrameWorks surface |
Playback outputs
Section titled “Playback outputs”| MistServer output | FrameWorks 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 outputs | Available 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.
Triggers and events
Section titled “Triggers and events”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 trigger | FrameWorks path |
|---|---|
STREAM_LOAD / stream lifecycle | liveStreamEvents(streamId) |
USER_NEW / USER_END | liveConnectionEvents(streamId) for events, or playback policy for authorization |
LIVE_TRACK_LIST | liveTrackListUpdates(streamId) |
RECORDING_END / DVR lifecycle | liveDvrLifecycle(streamId) and liveClipLifecycle(streamId) |
| Push completion or failure | Poll stream(id).pushTargets.status; no dedicated push subscription today |
| Custom HTTP trigger handlers | Stay on raw MistServer or ask us to scope a managed callback |
| Custom executable trigger handlers | Stay on raw MistServer |
STREAM_BUFFER, STREAM_BITRATE, RTMP_PUSH_REWRITE, DEFAULT_STREAM custom routing | Stay 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.
Push targets and multistreaming
Section titled “Push targets and multistreaming”| MistServer feature | FrameWorks path |
|---|---|
Manual push / pushStart | createPushTarget(streamId, input) plus enabled target status |
| Automatic push when a stream goes live | Stream-scoped push target; FrameWorks starts it when the stream is live |
| RTMP / RTMPS destination | Supported |
| SRT destination | Supported for custom targets |
| External writer URI targets | Stay on raw MistServer when external writers are core to the workflow |
| Per-rendition target selection | Not 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.
Recording, DVR, clips, and VOD
Section titled “Recording, DVR, clips, and VOD”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 feature | FrameWorks path |
|---|---|
| Record on stream start | createStream(input: { name, record: true }) |
| Start DVR later | startDVR(streamId) |
| Stop DVR | stopDVR(dvrHash) |
| Clip from live/DVR | createClip(input) |
| HLS-compatible DVR segments | FrameWorks DVR recording model |
| Sprite-sheet seek previews | Generated automatically for streams, recordings, and clips |
Custom path variables like $basename, $yday, $segmentCounter | Not surfaced in managed storage paths |
| Direct MP4 recording as a push target | Not surfaced as a managed recording option |
mutation StartDvr { startDVR(streamId: "stream-global-id") { ... on DVRRequest { id dvrHash playbackId } }}See Recordings and Thumbnails and Previews.
Auth and access control
Section titled “Auth and access control”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 feature | FrameWorks path |
|---|---|
| Push passphrase / stream name gate | Stream-key validation |
| JWT-on-ingest with RTMP, SRT, or WHIP path/token | Stay on raw MistServer for JWT-on-ingest; FrameWorks uses stream keys |
Viewer JWT as stream name, tkn parameter, or cookie | Playback policy with type: JWT; viewers usually attach ?jwt= |
| JWK/JWKS management | createSigningKey, revokeSigningKey, and setPlaybackPolicy |
USER_NEW blocking trigger for viewer authorization | setPlaybackPolicy with type: WEBHOOK |
| Public streams | setPlaybackPolicy 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 } } }}Run a FrameWorks edge
Section titled “Run a FrameWorks edge”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.
Edge walkthrough
Section titled “Edge walkthrough”- 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.
- 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, useframeworks cluster nodes add. - 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.
- 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.
- 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.
- 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:
Attach a node to an existing platform-managed cluster:
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.
Run full sovereign FrameWorks
Section titled “Run full sovereign FrameWorks”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:
- Check out or fork the GitOps repo. Your cluster manifests, host inventory, environment files, SOPS-encrypted secrets, release targets, and bootstrap overlays live there.
- Define the cluster manifest. Model central services, media clusters, hosts, domains, mesh identity, external services, and any bootstrap desired state.
- Validate the hosts. Run
frameworks cluster detectagainst the manifest or GitOps checkout before provisioning. - 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.
- Operate through GitOps. Config changes become pull requests;
frameworks cluster provisionconverges the approved state.
Local GitOps checkout:
frameworks cluster detect --gitops-dir gitops --cluster productionframeworks cluster provision --gitops-dir gitops --cluster productionGitHub-backed GitOps repo:
frameworks cluster provision \ --github-repo org/gitops \ --cluster production \ --age-key ~/.config/sops/age/keys.txtSee 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:
frameworks cluster provision --manifest cluster.yamlUse 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.
Move to managed FrameWorks
Section titled “Move to managed FrameWorks”Use this path when you want to stop running the media engine and accept the managed surface.
- Inventory your MistServer setup. Export config, list streams, triggers, pushes, recordings, JWT keys, external writers, custom variables, and local scripts.
- Classify blockers. Anything in What you give up needs a replacement plan before you cut over.
- Create FrameWorks streams. Use the dashboard or
createStream(input). - Repoint encoders. RTMP/RTMPS, E-RTMP, SRT, and WHIP remain the normal managed ingest paths.
- Replace trigger scripts. Use subscriptions for events. For Mist
USER_NEWauthorization scripts, usesetPlaybackPolicywithtype: WEBHOOKso FrameWorks calls your authorization endpoint on viewer connect. - Recreate push targets. Use
createPushTarget(streamId, input)per stream. - Recreate recording and DVR behavior. Use
record: trueorstartDVR(streamId). - 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. - Validate side by side. Run both systems for at least one full traffic cycle before changing production DNS, embeds, or encoder presets.
What you give up vs raw MistServer
Section titled “What you give up vs raw MistServer”- 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.
What you gain on FrameWorks
Section titled “What you gain on FrameWorks”- 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.
Beta and tricky bits
Section titled “Beta and tricky bits”- 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.
Get help
Section titled “Get help”| Channel | Best for | Where |
|---|---|---|
| Skipper | API discovery, troubleshooting, diagnostics, after-hours help | Dashboard /skipper - ⌘J in docs - MCP at /mcp |
| In-app ticketing | Account-specific questions, migration blockers, managed feature requests | Dashboard /support |
| Forum | Long-form Q&A and searchable recipes | forum.frameworks.network |
| Discord | Real-time discussion and migration scoping | Join |
| GitHub | Bugs, feature requests, deeper technical reports | Livepeer-FrameWorks/monorepo |
| MistServer community | Raw MistServer configuration, standalone server workflows, and features FrameWorks does not expose | mistserver.com - MistServer manual - DDVTech/mistserver |