Skip to main content
This is Tutorial 1 of 3. It covers the off-chain video transcoding path - the fastest way to understand the Gateway-Orchestrator relationship before adding AI workloads or going on-chain.
  • Tutorial 2:
  • Tutorial 3:
This tutorial runs a complete Livepeer Gateway-Orchestrator pipeline on a single machine, transcodes a sample video stream, and verifies the output - all without any Ethereum wallet, GPU, or network registration. Time: ~15 minutes | Cost: zero | Requirements: Linux (amd64), Docker or go-livepeer binary, ffmpeg

Architecture

ffmpeg (test stream)
     |  RTMP
     v
+-------------------------------------+
|  Gateway  (port 1935 in / 8935 out) |  <- receives stream, returns HLS
|  -network offchain                  |
+----------------+--------------------+
                 |  gRPC job request
                 v
+-------------------------------------+
|  Orchestrator + Transcoder          |  <- CPU transcoding, no GPU needed
|  (port 8936)                        |
|  -network offchain                  |
+-------------------------------------+
The Orchestrator transcodes the stream into multiple renditions (240p, 360p, 720p). The Gateway receives the renditions and makes them available as an HLS playlist. -network offchain means no Arbitrum RPC, no PM deposits, no staking - a fully local simulation.
-network offchain disables all on-chain operations but keeps the full job lifecycle intact: segment routing, transcoding, result delivery. The only thing missing is on-chain ETH payments - the Gateway and Orchestrator still exchange session messages and segments.

Prerequisites

go-livepeer binary (Linux amd64):
Download go-livepeer
# Replace v0.8.10 with the latest release
# https://github.com/livepeer/go-livepeer/releases
curl -LO https://github.com/livepeer/go-livepeer/releases/download/v0.8.10/livepeer-linux-amd64.tar.gz
tar -xzf livepeer-linux-amd64.tar.gz
chmod +x livepeer livepeer_cli
Prefer Docker? Use livepeer/go-livepeer:master and swap the binary commands for docker run livepeer/go-livepeer:master [flags]. Mount a host directory with -v ~/.lpData:/root/.lpData so session state persists. The flags are identical.
ffmpeg (for the test stream):
Install ffmpeg
# Ubuntu / Debian
sudo apt install ffmpeg

# macOS
brew install ffmpeg
Verify both:
Verify
./livepeer -version
ffmpeg -version
The -gateway flag replaces the old -broadcaster flag used in most pre-2024 community guides. If -broadcaster appears anywhere, substitute -gateway. The old flag still works in some builds but is deprecated.

Steps

What Happened

The full job lifecycle exercised in this tutorial:
ffmpeg
  +-> RTMP publish to Gateway port 1935
        +-> Gateway creates a session, selects Orchestrator (127.0.0.1:8936)
              +-> Gateway splits stream into ~2s segments
                    +-> Each segment sent to Orchestrator via gRPC
                          +-> Orchestrator transcodes to 240p / 360p / 720p (CPU)
                                +-> Transcoded segments returned to Gateway
                                      +-> Gateway assembles HLS playlist + segments
                                            +-> curl / ffplay pulls the HLS
Key concepts:
  • Session - the Gateway creates a session per stream key. The session persists until the publisher disconnects or the Gateway shuts down.
  • Segment - each ~2-second chunk of video. The Gateway sends segments to the Orchestrator independently and in order.
  • Off-chain job routing - without -network offchain, the Gateway would require an Arbitrum RPC and a funded PM deposit. In off-chain mode the routing is identical but the payment envelope is empty.
  • Transcoding profiles - the Orchestrator applied the default profiles: 240p30fps, 360p30fps, 720p30fps. Customise these via transcodingOptions.json passed to the Gateway.

Troubleshooting

The Orchestrator must be running before the Gateway starts. Start Step 1 first, confirm the Listening for jobs log line, then start Step 2.
The Gateway RTMP server is not running, or the wrong port is specified. Check that the Gateway terminal shows RTMP Server listening on rtmp://127.0.0.1:1935. If -rtmpAddr was changed, update the ffmpeg command to match.
Check the stream key is consistent between ffmpeg and curl. If test_stream was used in ffmpeg, the playlist is at /stream/test_stream.m3u8. Also check that ffmpeg is still running - the Gateway only creates the playlist once it has received and forwarded at least one segment.
The Gateway received the stream but the Orchestrator failed to transcode. Check the Orchestrator terminal for errors. Common cause: libx264 not available in the go-livepeer build. Try the Docker path instead.
Check Ports
lsof -i :1935   # RTMP
lsof -i :8935   # Gateway HTTP
lsof -i :8936   # Orchestrator gRPC
Kill the conflicting process, or change the -rtmpAddr, -httpAddr, and -serviceAddr flags.
Last modified on March 16, 2026