Skip to content

RTMP Streaming Guide

Learn how to push RTMP streams to Lunar Stream using various encoders.

RTMP Flow Overview

RTMP URL Format

rtmp://{host}/live/{streamKey}?pushToken={pushToken}

Example:

rtmp://ingest.lunarstream.kozow.com/live/ee04affe2a669854052102fe762bd715?pushToken=eyJhbGciOiJSUzI1NiIs...

OBS Studio Configuration

Step 1: Open Stream Settings

  1. Open OBS Studio
  2. Go to SettingsStream

Step 2: Configure Custom Server

SettingValue
ServiceCustom...
Serverrtmp://ingest.lunarstream.kozow.com/live
Stream Key{streamKey}?pushToken={pushToken}

TIP

Use the streamKeyWithToken value from the Create Livestream API response directly.

Go to SettingsOutputStreaming:

SettingRecommended Value
Video Bitrate2500-6000 Kbps
Encoderx264 or NVENC
Audio Bitrate128-320 Kbps
Keyframe Interval2 seconds

Step 4: Video Settings

Go to SettingsVideo:

SettingRecommended Value
Base Resolution1920x1080
Output Resolution1920x1080 or 1280x720
FPS30 or 60

Supported Input Formats

Lunar Stream accepts the following input specifications:

ParameterSupported Values
Video CodecH.264 (AVC)
Audio CodecAAC
ResolutionUp to 1920x1080
Frame RateUp to 60 fps
Video BitrateUp to 8 Mbps
Audio BitrateUp to 320 Kbps

Important

Always use H.264 video codec and AAC audio codec for best compatibility.

FFmpeg Command

For automated streaming or testing:

bash
ffmpeg -re -i input.mp4 \
  -c:v libx264 -preset veryfast -b:v 3000k -maxrate 3000k -bufsize 6000k \
  -c:a aac -b:a 128k -ar 44100 \
  -f flv "rtmp://ingest.lunarstream.kozow.com/live/YOUR_STREAM_KEY?pushToken=YOUR_PUSH_TOKEN"

FFmpeg Options Explained

OptionDescription
-reRead input at native frame rate
-c:v libx264Use H.264 video codec
-preset veryfastEncoding speed/quality tradeoff
-b:v 3000kVideo bitrate
-c:a aacUse AAC audio codec
-f flvOutput format for RTMP

Mobile SDK Integration

React Native Example

javascript
import { LiveStreamView } from 'react-native-live-stream';

const BroadcasterScreen = ({ streamConfig }) => {
  const rtmpUrl = `${streamConfig.rtmpServer}/${streamConfig.streamKeyWithToken}`;

  return (
    <LiveStreamView
      style={{ flex: 1 }}
      rtmpUrl={rtmpUrl}
      videoSettings={{
        width: 1280,
        height: 720,
        bitrate: 3000000,
        fps: 30
      }}
      audioSettings={{
        bitrate: 128000,
        sampleRate: 44100
      }}
      onStreamStateChanged={(state) => console.log('State:', state)}
      onError={(error) => console.error('Error:', error)}
    />
  );
};

Push Token Management

Token Lifecycle

Token Expiration

Push tokens expire after 1 hour by default. When expired:

  1. Stream status changes to TOKEN_EXPIRED
  2. Broadcaster is disconnected
  3. You need to generate a new token

Best Practice

Monitor token expiration and refresh tokens before they expire to ensure uninterrupted streaming.

Generate New Push Token

bash
curl -X POST https://api.xxxxxx.xxx/api/v1/livestream/generate-push-token \
  -H "ls-api-key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "projectId": "YOUR_PROJECT_ID",
    "streamKey": "ee04affe2a669854052102fe762bd715",
    "expiresIn": 7200
  }'

Response:

json
{
  "data": {
    "livestreamId": "d926da37-56ae-4212-83bc-f20d9de64d6b",
    "pushToken": "eyJhbGciOiJSUzI1NiIs...",
    "streamKey": "ee04affe2a669854052102fe762bd715",
    "expiresAt": "2026-01-12T20:12:59.000Z",
    "rtmpUrl": "rtmp://ingest.lunarstream.kozow.com/live/ee04affe2a669854052102fe762bd715?pushToken=eyJhbGci...",
    "streamKeyWithToken": "ee04affe2a669854052102fe762bd715?pushToken=eyJhbGci..."
  }
}

Troubleshooting

IssuePossible CauseSolution
Connection refusedInvalid RTMP URLVerify URL format and server address
Authentication failedInvalid or expired tokenGenerate a new push token
Stream drops frequentlyNetwork instabilityReduce bitrate, check connection
Poor video qualityLow bitrate settingIncrease video bitrate
Audio out of syncIncorrect encoder settingsSet keyframe interval to 2 seconds

Next Steps

Released under the MIT License.