OBS → din egen VPS

Den här sidan visar tittarna en HLS-stream (.m3u8). Eftersom Lovable inte själv kan ta emot RTMP behöver du en liten media-server på en VPS (t.ex. Hetzner CX22 ~€4/mån, DigitalOcean, Contabo). Här är hela flödet.

  1. 1. Hyr en VPS

    Ubuntu 22.04 eller 24.04, minst 2 vCPU och 4 GB RAM. Peka ett subdomän som stream.dindoman.se mot serverns IP via DNS A-record.

  2. 2. Installera nginx med RTMP-modulen

    sudo apt update
    sudo apt install -y libnginx-mod-rtmp nginx ffmpeg
  3. 3. Konfigurera nginx

    Lägg det här i /etc/nginx/nginx.conf (på toppnivå, utanför http{}):

    rtmp {
      server {
        listen 1935;
        chunk_size 4096;
    
        application live {
          live on;
          record off;
    
          # Bara din nyckel får streama in
          on_publish http://127.0.0.1/auth;
    
          # Generera HLS för uppspelning i webbläsare
          hls on;
          hls_path /var/www/hls;
          hls_fragment 2s;
          hls_playlist_length 10s;
    
          # Spela inte upp RTMP direkt
          allow play 127.0.0.1;
          deny play all;
        }
      }
    }

    Och i HTTP-blocket — servera HLS-filerna med CORS så att din Lovable-sajt får hämta dem:

    server {
      listen 443 ssl http2;
      server_name stream.dindoman.se;
    
      # ssl_certificate / ssl_certificate_key fyller certbot i (se steg 5)
    
      location /hls/ {
        types {
          application/vnd.apple.mpegurl m3u8;
          video/mp2t ts;
        }
        alias /var/www/hls/;
        add_header Cache-Control no-cache;
        add_header Access-Control-Allow-Origin *;
      }
    
      # Enkel skydd för on_publish — kontrollerar streamnyckel
      location = /auth {
        if ($arg_name != "DIN_HEMLIGA_STREAMNYCKEL") { return 403; }
        return 200;
      }
    }

    Skapa HLS-mappen: sudo mkdir -p /var/www/hls && sudo chown www-data:www-data /var/www/hls

  4. 4. Öppna brandväggen

    sudo ufw allow 1935/tcp   # RTMP från OBS
    sudo ufw allow 80/tcp
    sudo ufw allow 443/tcp
  5. 5. SSL med Let's Encrypt

    sudo apt install -y certbot python3-certbot-nginx
    sudo certbot --nginx -d stream.dindoman.se
    sudo systemctl reload nginx
  6. 6. Konfigurera OBS

    I OBS: Inställningar → Ström:

    • Tjänst: Anpassad
    • Server: rtmp://stream.dindoman.se/live
    • Stream-nyckel: live?name=DIN_HEMLIGA_STREAMNYCKEL

    Tryck "Starta sändning" — nginx tar emot RTMP och genererar /var/www/hls/live.m3u8.

  7. 7. Lägg in HLS-URL i adminpanelen

    Gå till /admin på den här sajten och klistra in:

    https://stream.dindoman.se/hls/live.m3u8

    Markera "LIVE" när du börjar streama. Det är allt — tittarna ser dig live.

  8. 8. Auto-spara varje stream som VOD

    Lägg till inspelning och webhook-anrop i application live-blocket. Nginx-RTMP pingar Lovable när du går live och när du slutar — sajten togglar is_live och skapar en VOD-post automatiskt.

    application live {
      live on;
    
      # Spara hela streamen som .flv
      record all;
      record_path /var/www/recordings;
      record_unique on;
      record_suffix _%Y-%m-%d_%H-%M-%S.flv;
    
      # När stream startar: säg åt Lovable att gå LIVE
      exec_publish bash -c "curl -sS -X POST https://live.raskengaming.xyz/api/public/stream-hooks \
        -H 'Content-Type: application/json' \
        -H 'x-stream-secret: DIN_VPS_CLIP_SECRET' \
        -d '{\"event\":\"publish\"}'";
    
      # När inspelningen är klar: konvertera FLV→MP4 + skapa VOD i Lovable
      exec_record_done bash -c "ffmpeg -y -i $path -c copy /var/www/recordings/$basename.mp4 && \
        DUR=$(ffprobe -v error -show_entries format=duration -of default=nw=1:nk=1 /var/www/recordings/$basename.mp4 | cut -d. -f1) && \
        curl -sS -X POST https://live.raskengaming.xyz/api/public/stream-hooks \
          -H 'Content-Type: application/json' \
          -H 'x-stream-secret: DIN_VPS_CLIP_SECRET' \
          -d \"{\\\"event\\\":\\\"publish_done\\\",\\\"recording_url\\\":\\\"https://server.raskengaming.xyz/recordings/$basename.mp4\\\",\\\"duration_seconds\\\":$DUR}\"";
    
      # ... HLS-config från steg 3
    }

    Servera /recordings/ som statisk katalog via samma nginx server {}-block som /hls/, så MP4-filerna är publikt åtkomliga. Hemligheten är samma som VPS_CLIP_SECRET (återanvänds för båda hooks).

    Resultat: starta OBS → sajten går automatiskt LIVE. Stoppa OBS → live-flaggan av, MP4:n dyker upp i VOD-arkivet med stream-titel + tidsstämpel.

  9. 7. AI-klippare: endpoint på VPS:en

    Admin-panelen anropar en HTTP-endpoint på din VPS som klipper ut ett segment ur recordingen med ffmpeg och returnerar en publik URL. Skapa /opt/clipper/server.js:

    // bun install express
    const express = require("express");
    const { spawn } = require("child_process");
    const fs = require("fs");
    const path = require("path");
    const crypto = require("crypto");
    
    const SECRET = process.env.CLIP_SECRET;          // matchar VPS_CLIP_SECRET i Lovable
    const REC_DIR = "/var/www/recordings";            // där nginx-rtmp sparar .flv
    const OUT_DIR = "/var/www/clips";                 // serveras via nginx
    const PUBLIC_BASE = "https://stream.dindoman.se/clips";
    
    const app = express();
    app.use(express.json());
    
    app.post("/clip", async (req, res) => {
      if (req.headers["x-clip-secret"] !== SECRET) return res.status(401).end();
      const { offset_seconds, duration_seconds, marker_id } = req.body;
    
      // Hitta senaste recordingen
      const files = fs.readdirSync(REC_DIR).filter(f => f.endsWith(".flv"))
        .map(f => ({ f, t: fs.statSync(path.join(REC_DIR, f)).mtimeMs }))
        .sort((a, b) => b.t - a.t);
      if (!files.length) return res.status(404).json({ error: "ingen recording" });
      const src = path.join(REC_DIR, files[0].f);
    
      const id = marker_id || crypto.randomUUID();
      const out = path.join(OUT_DIR, id + ".mp4");
    
      const ff = spawn("ffmpeg", [
        "-y", "-ss", String(offset_seconds), "-i", src,
        "-t", String(duration_seconds), "-c:v", "libx264", "-preset", "veryfast",
        "-c:a", "aac", "-movflags", "+faststart", out,
      ]);
      ff.on("close", code => {
        if (code !== 0) return res.status(500).json({ error: "ffmpeg fail" });
        res.json({ video_url: PUBLIC_BASE + "/" + id + ".mp4", duration_seconds });
      });
    });
    
    app.listen(8787, "127.0.0.1");

    Proxy:a /clip via nginx och servera /clips/ som statisk katalog. Kör som systemd-tjänst. Lägg sedan din endpoint-URL i VPS_CLIP_URL och hemligheten i VPS_CLIP_SECRET (Cloud-secrets).

Tips: För bättre kvalitet, kör 720p60 vid 4500–6000 kbps och keyframe-intervall 2s i OBS — annars laggar HLS-segmenten.