Nearglass

Quickstart

From nothing to your video playing in a web page at low latency, with packages only.

From nothing to your video playing in a browser at low latency, with no build and nothing to run on a server. You send video to our ingest, and a web page plays it through our relays.

You need:

  • a terminal with curl;
  • something that sends H.264 video: OBS, ffmpeg, a hardware encoder, or just an H.264 file and the nearglass command line tool (step 3);
  • Chrome or Edge on a desktop (Firefox works too; iPhone and Safari play through the compatibility mode, see Concepts).

1. Get your keys

Sign up and copy your two keys from the dashboard:

KeyLooks likeWhere it goes
Secret keysk_ and 43 charactersyour terminal and your backend only, never a web page
Publishable keypk_ and 43 characterssafe in a web page: it can only ask for a seat on a public stream

Put them in a file with our API's address, and load it into your shell (run . ./quickstart.env again in any second terminal you open later):

cat > quickstart.env <<'END'
export API=https://api.nearglass.com
export SK=sk_...        # your secret key
export PK=pk_...        # your publishable key
END
chmod 600 quickstart.env && . ./quickstart.env

2. Create a stream

curl -s $API/v1/streams -H "Authorization: Bearer $SK" -H "Content-Type: application/json" \
  -d '{"name":"hello","admission":"public"}' | tee stream.json

The answer (shortened):

{
  "id": "st_8f2c41d09a7be3105c6e2d77",
  "namespace": "live/st_8f2c41d09a7be3105c6e2d77",
  "admission": "public",
  "viewer_cap": 100,
  "publish": {
    "stream_key": "stk_...",
    "srt": "srt://ingest.nearglass.com:9000?streamid=stk_...",
    "rtmp": "rtmp://ingest.nearglass.com:1935/live/stk_..."
  }
}

Keep id, and the srt or rtmp address: it holds the stream key, which is shown only in this answer (lost it? POST /v1/streams/{id}/stream-key makes a new one). "admission":"public" lets any page with your publishable key take a seat, which is what this quickstart needs; for viewers who sign in to your site, see Mint viewer tokens on your server.

echo "export ID=$(python3 -c 'import json; print(json.load(open("stream.json"))["id"])')" >> quickstart.env
. ./quickstart.env && echo $ID      # or by hand: export ID=st_...

3. Send video

Pick one.

OBS. Settings, Stream: Service "Custom...", Server: the whole srt address from step 2, Stream Key: leave empty. Settings, Output (Advanced), Streaming: Rate Control "CBR", Keyframe Interval "1", and Tune "zerolatency" (x264) or B-Frames 0 (NVENC). Press Start Streaming. More settings and hardware encoders: OBS and SRT; every other way to send video: Publish.

ffmpeg (more recipes), with any video file (put the srt address in quotes):

ffmpeg -re -stream_loop -1 -i film.mp4 -an -c:v libx264 -preset veryfast -tune zerolatency \
  -bf 0 -force_key_frames "expr:gte(t,n_forced*1)" -b:v 3M -f mpegts "srt://ingest.nearglass.com:9000?streamid=stk_..."

No encoder at hand: the nearglass command line tool replays an H.264 file (MPEG-TS, or a raw .h264/.264 Annex B stream) in real time, straight to our relays. Unpack the tool for your system, then publish your file (its path in place of film.ts):

tar -xzf nearglass-0.1.0-rc.1-linux-x86_64.tar.gz      # makes nearglass-0.1.0-rc.1-linux-x86_64/nearglass
echo "$SK" > sk.txt && chmod 600 sk.txt
nearglass-0.1.0-rc.1-linux-x86_64/nearglass publish --api $API --secret-key-file sk.txt --stream $ID --file film.ts --loop

It keeps running until you press Ctrl-C, so open a second terminal for step 4. Its log line with event=Session(Connected means a relay took the stream.

The file replay sends the picture only. For sound, publish from an encoder (Publish, and Audio): AAC-LC (most encoders' default) and Opus are both carried. Keep the keyframe interval at 1 second (2 at most) and B-frames off: a viewer starts at a keyframe, and B-frames add delay.

4. Watch it in a page

Save this as hello.html, with your stream id and publishable key in place of st_... and pk_...:

<!doctype html>
<meta charset="utf-8">
<title>hello</title>
<script type="module" src="https://cdn.nearglass.com/player@0.1.0-rc.1/src/element.js"></script>
<nearglass-player api="https://api.nearglass.com" stream="st_..." publishable-key="pk_..." auto-join></nearglass-player>

Open it in Chrome (double-click the file, or serve the folder with any web server). Within a few seconds the bar under the picture says Low latency and the video plays. Without auto-join, the player waits for the viewer to press Join when a seat is offered (within 10 s), so a tab nobody is watching cannot hold a seat.

What happened: the page asked our API for a seat with your publishable key, got a short-lived viewer token for this stream, picked the nearest relay and played the stream over MoQ (WebTransport and WebCodecs in the browser). It keeps its seat with a heartbeat every 5 seconds and gives it up when closed.

Or let the shell write it with your values:

. ./quickstart.env
cat > hello.html <<END
<!doctype html>
<meta charset="utf-8">
<title>hello</title>
<script type="module" src="https://cdn.nearglass.com/player@0.1.0-rc.1/src/element.js"></script>
<nearglass-player api="$API" stream="$ID" publishable-key="$PK" auto-join></nearglass-player>
END

If it does not play

The bar saysWhat to do
Set token-url, or api, stream and publishable-key.an attribute is missing or misspelled
Cannot play: admission: HTTP 401the publishable key is wrong, or belongs to another account
Cannot play: admission: HTTP 403 server_admissionthe stream was created without "admission":"public": PATCH is not available yet, so create a new stream with it
Cannot play: admission: HTTP 404the stream id is wrong, or the stream was deleted
Connecting... for more than 10 snothing is being sent yet: check the encoder (step 3)
The stream is full. Waiting for a seat...the stream's viewer_cap is reached (default 100); create the stream with a larger viewer_cap
Compatibility mode, about 1 s behindthis browser cannot play MoQ (Safari, iPhone) or UDP is blocked: it plays LL-HLS instead (Concepts)

To see what the stream is doing: curl -s $API/v1/streams/$ID/stats -H "Authorization: Bearer $SK" (seats taken, people in line, when the ingest last connected).

Next

  • Concepts: streams, keys, seats and tokens, the viewer cap and the waiting room, controllers, metering, fallback.
  • Embed the player in your own page or React app.
  • Mint viewer tokens on your server, so only your signed-in users get a seat.
  • Samples: seven small programs, each one run by the SDK's smoke test.
  • Delete the stream when you are done: curl -s -X DELETE $API/v1/streams/$ID -H "Authorization: Bearer $SK".

On this page