Help

How to run the viewer, add videos, and rebuild the library.

Quick start

Run these from the project root (mxrrr):

# 1. Build the video index (run after adding posts)
python scripts/build_posts_index.py

# 2. Start the local server
python serve.py

# 3. Open in your browser
http://localhost:8080/mxr-viewer/index.html

Use a different port if 8080 is busy:

python serve.py --port 3000

Hostinger subdomain (mxr.manish.rocks)

  1. In Hostinger hPanel, create subdomain mxr for manish.rocks.
  2. Set the subdomain document root to a folder (e.g. public_html/mxr).
  3. On your PC, run python scripts/build_posts_index.py.
  4. Upload everything inside mxr-viewer/ into that folder (not the mxr-viewer folder itself).
  5. Open https://mxr.manish.rocks/

Do not upload mmoxreview - MxR/ or serve.py. Rebuild on your PC when you add posts, then re-upload data/ and new cache/thumbs/ files.

Account sync (PC + mobile)

The viewer supports login-based sync for favorites, history, playlists, and resume playback across devices.

  1. Create a Supabase project.
  2. In Supabase SQL editor, run:
create table if not exists public.user_library_state (
  user_id uuid primary key references auth.users(id) on delete cascade,
  favorites jsonb not null default '[]'::jsonb,
  history jsonb not null default '[]'::jsonb,
  playlists jsonb not null default '{"order":[],"byId":{}}'::jsonb,
  playback jsonb not null default '{}'::jsonb,
  updated_at timestamptz not null default now()
);

alter table public.user_library_state enable row level security;

create policy "users_select_own_state"
on public.user_library_state
for select
using (auth.uid() = user_id);

create policy "users_upsert_own_state"
on public.user_library_state
for insert
with check (auth.uid() = user_id);

create policy "users_update_own_state"
on public.user_library_state
for update
using (auth.uid() = user_id);
  1. Open mxr-viewer/js/sync-config.js and set your Supabase URL + anon key.
  2. Add resume support (run once in SQL Editor):
alter table public.user_library_state
add column if not exists playback jsonb not null default '{}'::jsonb;
  1. Upload updated files to Hostinger and hard refresh.
  2. Login with the same account on PC and mobile.

While logged in, playback position is saved every few seconds. Open the same video on another device to resume where you left off.

Disable email confirmation in Supabase Auth if you want instant signup/login without OTP emails.

Add new videos

  1. Download or add a new post folder under mmoxreview - MxR/posts/. Folder name format: POST_ID - Video Title (example: 161526233 - why women's pockets are smaller).
  2. Make sure the post has a Cloudflare Stream link in either:
    • post_info/post-api.json (in content or content_json_string)
    • post_info/info.txt (in the Content line)
    Link format: https://customer-u1hok16au7q8ozt4.cloudflarestream.com/STREAM_ID/watch
  3. Add a thumbnail image in images/ inside the post folder. Best name: maxresdefault.jpg. Other images work too — the build script picks the best one.
  4. Rebuild the index (see below), refresh the browser with Ctrl+Shift+R.

Posts without a Cloudflare Stream link are skipped and will not appear in the viewer.

Rebuild the index

Run this any time you add, remove, or update post folders:

python scripts/build_posts_index.py

This script:

  • Scans every folder in mmoxreview - MxR/posts/
  • Finds Cloudflare Stream links from post-api.json and info.txt
  • Generates optimized thumbnails in mxr-viewer/cache/thumbs/
  • Writes mxr-viewer/data/posts.min.json (used by the site)

Requirement: Python with Pillow installed (pip install pillow).

Folder structure

mxrrr/
├── serve.py                          # local web server
├── scripts/
│   └── build_posts_index.py          # builds index + thumbnails
├── mmoxreview - MxR/
│   └── posts/
│       └── 120915689 - Video Title/
│           ├── images/
│           │   └── maxresdefault.jpg
│           └── post_info/
│               ├── post-api.json
│               └── info.txt
└── mxr-viewer/
    ├── index.html                    # home page
    ├── watch.html                    # video player
    ├── help.html                     # this page
    ├── data/posts.min.json           # generated catalog
    └── cache/thumbs/                 # generated thumbnails

Keyboard shortcuts

On the home page:

  • / — focus search

On the watch page (lowercase, no Shift):

  • t — theater mode
  • f — fullscreen
  • j — previous video
  • k — next video

Without login, favorites and history stay local. With login enabled, they sync across devices.

Troubleshooting

New video not showing?
Run python scripts/build_posts_index.py, then hard-refresh the page.
Thumbnail missing or slow?
Rebuild the index. Thumbnails are auto-generated at ~480px width in mxr-viewer/cache/thumbs/.
Page won't load / images broken?
You must use python serve.py. Opening HTML files directly (file://) will not work.
Port already in use?
Stop the old server or run python serve.py --port 3000.
Multiple stream links in one post?
If a post has a "New link:" line, that link is used. Otherwise the first link found is used. On the watch page you can switch streams when multiple exist.