Sluby

Build with Sluby

Upload a video from your server, wait until it is ready, and play it in a React app.

In this walkthrough you upload a video from a Node.js script with @sluby/sdk, wait until Sluby has transcoded it and stored it on Sia, and play it in the browser with @sluby/player. The API key stays on your server; the browser plays the public video without one.

You need the address of a Sluby server, for example https://sluby.example.com, and a Studio account on it.

Create an API key

In the Studio, open API keys under Developers and click Create key. Give the key a name and keep the scopes upload and read selected: upload sends the file and read checks when it is ready. Click Create key and copy the key. The Studio shows it only once.

Keep the key on your server, for example in an environment variable:

.env
SLUBY_URL=https://sluby.example.com
SLUBY_API_KEY=sluby_...

Create and manage API keys covers the page in detail, and API conventions lists what each scope allows.

Install the packages

On the server, install the SDK. Check that your Node.js version is one the SDK supports (package facts).

npm install @sluby/sdk

In your React app, install the SDK and the player (supported React versions):

npm install @sluby/sdk @sluby/player

Upload the video and wait until it is ready

This script runs on your server. It uploads video.mp4, prints the id of the new video asset, and waits until processing has finished.

upload.mjs (server)
import { openAsBlob } from 'node:fs';
import { SlubyClient } from '@sluby/sdk';

const { SLUBY_URL, SLUBY_API_KEY } = process.env;
if (!SLUBY_URL || !SLUBY_API_KEY) throw new Error('Set SLUBY_URL and SLUBY_API_KEY.');

const client = new SlubyClient({ baseUrl: SLUBY_URL, apiKey: SLUBY_API_KEY });

// a Blob backed by the file: the SDK reads it one chunk at a time
const file = await openAsBlob('./video.mp4');

const upload = client.uploads.upload(file, {
  title: 'My first video',
  onProgress: (percent) => console.log(`uploaded ${percent}%`),
});

const assetId = await upload.assetId;
console.log(`asset ${assetId} created`);
await upload;

const asset = await client.assets.waitForReady(assetId, { timeout: 30 * 60_000 });
console.log(`ready: ${asset.id}, ${asset.resolution}`);

Run it with your environment loaded:

node --env-file=.env upload.mjs

upload.assetId resolves as soon as the server has created the upload, before the bytes finish. waitForReady polls the asset until its status is ready, and the 30 minute timeout gives a long video time to process. Wait for processing covers its defaults and errors.

Play the video

A public video plays from its stream URL, which the SDK builds without a request and without a key. This component runs in the browser:

Video.tsx (browser)
import { SlubyClient } from '@sluby/sdk';
import { SlubyPlayer } from '@sluby/player';

// no API key: a public video plays from its stream URL
const client = new SlubyClient({ baseUrl: 'https://sluby.example.com' });

export function Video({ assetId }: { assetId: string }) {
  return (
    <SlubyPlayer src={client.playback.streamUrl(assetId)} controls style={{ width: '100%' }} />
  );
}

Render <Video assetId="..." /> with the id the script printed.

Next steps

Reference

To learn how Sluby works inside, start with Architecture.

On this page