Content, HLS and CDN.
From upload to playback.
Add series in the Library, upload videos that the server converts to HLS with ffmpeg, or point episodes at an HLS address you host elsewhere. Locked episodes are only ever served from signed, expiring addresses.
01Add a series
Everything on this page is done in the console in your browser, on any system. The few server commands (ffmpeg, npm run seed:sample, openssl) are for Linux or macOS; on Windows run them in WSL (Windows Subsystem for Linux) or Git Bash.
- Console → Library → New series. Title, tagline, synopsis, genres and tags, language, poster and cover.
- Pricing. Leave empty to use the defaults from Economy, or set a price and a number of free episodes for this series, and an optional bundle price for the rest of the series.
- Extras. Cast and crew (up to 20), age rating, trailer episode, characters for the character chat (up to 8), a release date for Coming soon.
- Rights. Record the rights holder, territories and end date (why).
- Publish when the episodes are ready.
02Add episodes
For each episode set a title, an optional price override, whether it follows the series' free count or is always free or locked, and its visibility. Then give it a video in one of two ways:
- Upload a file (MP4 or MOV, vertical 9:16). The server converts it to HLS in the background. Progress and errors are on Media jobs.
- External HLS or MP4 address (https). Use this for video you host with a streaming provider. No ffmpeg needed.
External addresses are handed to viewers who may watch the episode. Use your provider's own token protection for them.
03How conversion works
ffmpeg converts each upload into an HLS ladder of the renditions chosen in Media & CDN → Renditions (default 540×960 and 720×1280; 360×640 and 1080×1920 can be added) and makes a thumbnail. One minute of the default ladder is roughly 25 MB on disk. The largest upload is set in Largest upload (MB) (default 500).
Each playback address carries the server's signature and an expiry (Playback address lifetime, default 360 minutes). A forged, changed or expired address is refused with 403.
04Subtitles and audio tracks
Upload a WebVTT file per language in the episode drawer (SRT-style timings with a comma are read too), or let AI create them (AI). AI tracks are labelled "AI" for viewers and can be edited or replaced in the Library.
05Import many episodes from CSV
Library → Import CSV creates series by title and one episode per row with an external https video address. The first row must name the columns:
| Column | |
|---|---|
series_title, episode_number, video_url | required |
episode_title, duration_s, synopsis, genres, language, poster_url, rights_holder | optional |
series_title,episode_number,video_url,episode_title
My Series,1,https://cdn.example.com/my-series/1/master.m3u8,The beginning
New series are created as drafts. Rows with an episode that already exists are skipped and listed.
06CDN for video
Two ways, both set in Media & CDN. First set Public server address to your https domain.
1. Any pull CDN (simple)
- Create a pull zone at your CDN whose origin is your server.
- Put its address in CDN address (pull zone).
Playback addresses keep the server's short-lived signature in the path, so the CDN caches each episode's files and the server still refuses expired or forged links.
2. BunnyCDN token authentication (strongest)
- Enable token authentication on the Bunny pull zone and paste its key into BunnyCDN token authentication key.
- Set
ORIGIN_PULL_SECRETin.env(openssl rand -hex 32) and restart. - Add an edge rule in Bunny that sends that secret as the request header
x-origin-secretto the origin.
Bunny then checks every request at the edge and pulls from /media/origin/…, which answers only when that header is present.
07The sample catalogue
npm run seed:sample generates six placeholder series on your machine from colour gradients and the bundled fonts, with fictional cast, characters, starter missions and collections. Every sample series is marked "Sample". Remove it before you launch:
npm run seed:sample -- --reset # removes and rebuilds the sample
Deleting the sample series in the Library removes them for good.
08Content rights
Reelora is the platform; the series are yours. The package contains no third-party video, poster, music or text. You need a licence for everything you publish that covers streaming, the territories, the period, and any dubbing or subtitling you add. Re-uploading episodes taken from other apps or video sites is copyright infringement, and app stores remove apps for it.
Legitimate ways to build a catalogue: produce your own, license from producers and distributors, open the creator studio under an agreement with each creator, or use AI-generated series where the generation service's terms and your local laws allow it (label them where required).
- Record each series' rights holder, territories and end date in the Library.
- Close the service where you hold no rights: Access → Blocked countries (needs
COUNTRY_HEADER). - Set Content & languages → Address for content and rights reports; it is shown in the app.
- To take a series down at once, archive it in the Library. Unlocked episodes of an archived series stop playing too, so consider a goodwill grant of bonus coins to viewers who paid (Viewers page).