Montréal, QC·lukesidney.me·Fresh 2 · DenoAucun témoin · aucun formulaire
Planche01

La une.Ce que c'est

En chantier

La vidéothèque sans pub

Toutes mes vidéos longues au même endroit, sur un stockage qui m'appartient, sans publicité.

Elle roule sur une adresse temporaire en attendant le nom de domaine.

L'accueil de la vidéothèque, qui joue un enregistrement de jeu du propriétaire.
Planche02

Composé.La pile techno

Sur quoi ça roule

Une façade statique sur Cloudflare, une petite boîte pour les comptes, et les fichiers dans mon propre compartiment.

Façade

  • Astro7.3un catalogue pré-rendu
  • Preact10.29l'îlot du lecteur
  • Cloudflare Workersl'hébergement

Boîte

  • Bun + Hono4.13l'API
  • Better Auth1.7les comptes
  • Polarl'abonnement
  • Postgres17avec Drizzle 0.45, sur Railway

Médias

  • Cloudflare R2les fichiers, sans frais de sortie
  • Trigger.dev4.5les formats et les aperçus avec ffmpeg
  • Payloadune ligne par vidéo
  • <video>aucun lecteur tiers, aucun DRM
Planche03

Sous presse.Comment ça marche

5 étapes, dans l'ordre

D'un seul téléversement à un nombre de vues honnête.

  1. Téléverser une fois

    L'original monte par CCC, qui écrit la fiche CMS de la vidéo.

  2. Transcoder en arrière-plan

    Une tâche en arrière-plan découpe les formats et un aperçu au survol avec ffmpeg, directement dans R2.

  3. Rebâtir le catalogue

    Un envoi rebâtit chaque page du catalogue en HTML statique en environ 40 secondes.

    Le catalogue de la vidéothèque, avec des filtres par genre et par étiquette.
  4. Jouer par un lien signé

    Le lecteur demande une URL signée de courte durée. Les vidéos réservées aux membres vérifient d'abord l'abonnement.

    Une page de visionnement de la vidéothèque : le lecteur, le titre et le nombre de vues.
  5. Compter honnêtement

    Une vue compte après 3 secondes de vraie lecture, une fois par spectateur par jour.

Planche04

L'épreuve.Le code

Ce qui compte comme une vue

src/lib/views.ts · lines 1–15source réelle
// A VIEW, as the watch page reports it: the viewer pressed play and has watched at least// VIEW_SEC seconds of the video. The box counts it once per viewer per 24 hours and keeps the// rules (box/src/viewing.ts); this file only measures.export const VIEW_SEC = 3/** * Seconds actually played on this page, from `player.played` — the stretches of the video the * viewer watched. A seek adds nothing and a stretch replayed counts once, so no timer and no * per-second event is needed to know it: it is read at the moments the page already saves. */export function playedSeconds(ranges: Pick<TimeRanges, 'length' | 'start' | 'end'>): number { let sum = 0 for (let i = 0; i < ranges.length; i++) sum += ranges.end(i) - ranges.start(i) return sum}

Un saut n'ajoute rien et une reprise compte une seule fois : pas de minuterie, pas d'écriture à chaque seconde.

Planche05

La bobine.La démo

Le voir tourner

Démo du logiciel à venirEnviron 2 minutes : le téléversement dans CCC, la tâche de transcodage, la reconstruction du catalogue, un aperçu au survol qui devient le lecteur.
Planche06

Corrections.Ce que ça règle

Les problèmes que ça règle

  • La plateforme garde les fichiers et l'auditoire.

    Les fichiers sont dans mon propre compartiment, et la liste est à moi.

  • De la pub sur chaque vidéo, et moins de portée quand je renvoie vers mon propre travail.

    Pas de pub. Renvoyer vers mon travail ne coûte rien.

  • Des factures de bande passante qui grossissent à chaque vue.

    R2 ne facture pas la sortie, et le catalogue est statique.

  • Des nombres de vues que personne ne peut vérifier.

    Une vue, c'est 3 secondes, une fois par jour, et la règle est testée.

Planche07

Le mot de l'éditeur.Pourquoi je l'ai bâti

Pourquoi ça existe

Posséder les données. Tous les fournisseurs d'hébergement vidéo étaient exclus dès le départ.

Je veux faire connaître mon propre travail sans qu'une plateforme me punisse pour ça. Chaque vidéo est donc publiée ici d'abord, et les copies ailleurs renvoient vers la version sans pub.

Illustration riso : des bobines de film rangées dans un coffre qui appartient à une seule personne.
Planche08

Face au présentoir.Mieux que la moyenne

Face aux outils habituels

Face à Vimeo OTT, Uscreen et la vidéo Patreon. Leur côté a été lu sur les pages de chaque fournisseur le 2026-09-27.

QuoiLa moyenne du marchéCette appli
Où vivent les fichiersSur les serveurs du fournisseur.Dans mon propre compartiment R2.page du fournisseur
Le coût quand l'auditoire granditDes frais par abonné payant, ou une part de chaque vente.Pas de frais par abonné ni de part; R2 ne facture pas la sortie.page du fournisseur
Ce qui compte comme une vueTout démarrage de la lecture (Vimeo).3 secondes de vraie lecture, une fois par spectateur par jour, testé.page du fournisseur
Vie privéeDes témoins d'analyse du lecteur activés par défaut (Vimeo).Les adresses IP des spectateurs non connectés restent en mémoire seulement.page du fournisseur
Planche09

L'achevé d'imprimer.Le temps que ça a pris

64 commits en 11 jours

commits sur le site
64
jours avec un commit
10
jours, du premier au dernier commit
11
2026-09-09commits par jour · record : 142026-09-19
  1. Premier commit
  2. Dernier commit du site
  3. Plus 25 commits du côté de l'ingestion et du transcodage

Mesuré : git log du dépôt du site, 2026-09-27.

Planche10

Colophon.Sa place au registre

entrée
08 / 09
état
en chantier

Encore en chantier. Rien de livré n'est revendiqué pour ce projet.

← Retour au registre