Commit graph

8 commits

Author SHA1 Message Date
opencode
a86c1c72f9 fix(player): stitch S3 ranges around RustFS empty-body bug (#143)
RustFS returns empty bodies for ranged GETs whose start offset is past
~5.9 MB on single-file proxy MP4s. HEAD reports correct size, full GET
(`bytes=0-`) works, but `bytes=8179166-` comes back 206 + correct
Content-Range header with zero bytes. Confirmed via direct S3 probe
against broadcastmgmt.cloud/dragonmam (see scratch tests).

Workaround in mam-api `GET /api/v1/assets/:id/video` until the proxy
worker emits HLS (planned v1.2.1):

  - HEAD the object first to learn total size (also gives ETag /
    Last-Modified for conditional requests).
  - No-Range / unparseable-Range / pre-EOF requests \u2192 plain pipe.
  - Parsed `bytes=N-M` requests below RUSTFS_RANGE_SAFE_START
    (default 5_500_000) \u2192 direct ranged GET, RustFS handles fine.
  - Anything reaching into the broken zone \u2192 stream from offset 0,
    drop bytes below start, stop at end. Memory stays flat; extra
    bandwidth = (end+1 - requested-size) per seek.
  - Genuinely out-of-range \u2192 416 with Cache-Control: no-store so the
    browser doesn't poison its cache.

Also stashes (not yet wired up) the HLS pieces we'll need for the
follow-up: `segmentToHls` ffmpeg helper + `uploadDirectoryToS3`
worker s3 helper. Harmless additions; not referenced by any code path
yet.

Confirmed against the affected asset (a72aaa03-...): bytes=0-100k +
50% +100k native pass-through; 70% +100k and near-EOF previously hung
the browser, now stream correctly via the stitched path.

Refs #143.
2026-05-27 02:38:42 +00:00
e4d4c00f52 feat(proxy): VBR 500k-1M encoding for proxy generation
executor.js:
- transcodeVideo() now accepts videoMinRate, videoMaxRate, videoBufSize
- When set, passes -minrate/-maxrate/-bufsize to FFmpeg for ABR/VBR mode
- libx264 operates with per-scene quality variation within the envelope

proxy.js:
- Target average: 750k (gpu_bitrate_mbps=0.75)
- Min: 375k (50% of target), Max: 998k (~133%), Buffer: 2× max
- Gives effective range of ~500k-1M depending on scene complexity
- Log now shows VBR min-max-avg
- GPU fallback also passes VBR params
- Default videoBitrate changed from 10M to 750k in executor.js
2026-05-26 17:44:18 +00:00
c312991bac feat: implement advanced features (conform, auto-relink, GUI redesign, docs, tests)
- #30 FCP XML Export & Conform: slide panel UI, preset system, FCP XML generation,
  conform job submission with progress polling via BullMQ
- #31 Hi-Res Auto-Relink: clip list with checkboxes, batch-trim server endpoint,
  trimWorker with frame-accurate FFmpeg trimming, auto-relink in Premiere via
  ExtendScript, temp segment signed URL endpoint
- #32 GUI Redesign: complete rewrite with Wild Dragon OKLCH design tokens
  (accent oklch(45% 0.20 266)), slide panels, preset cards, chip components
- #34 Cleanup Task: existing task validated and properly registered
- #35 Testing: comprehensive 33-scenario E2E test plan
- #36 Documentation: advanced features guide with workflows, troubleshooting,
  presets table, and architecture overview
- #24 PR merge: verified mergeable

All server endpoints, worker queues, and ExtendScript functions wired together
2026-05-24 13:19:24 -04:00
claude
6398879b56 feat: SDK deployment UI, proxy encoding global settings, S3 env fallback
- Settings: drop AMPP tab, rename GPU/Transcoding → Proxy encoding
  with explicit 'applied to every ingested file' wording, expose
  CPU codec/preset options when GPU is off
- New Capture SDKs tab (Settings): upload Blackmagic / AJA / Deltacast
  SDK archives (.zip / .tar.gz) staged to /sdk/<vendor>/ inside mam-api;
  BMD is fully wired into the FFmpeg build pipeline, AJA + Deltacast
  staging-only pending FFmpeg patches
- mam-api: new /api/v1/sdk routes (multer upload, extract, list, delete);
  Dockerfile gets unzip+tar; docker-compose mounts /mnt/NVME/MAM/sdk:/sdk
- proxy worker now reads proxy-encoding settings from DB on every job,
  builds args for libx264 / NVENC / VAAPI, falls back to libx264 on
  hardware-encode failure
- settings GET /s3 falls back to S3_* env vars when DB is empty so the
  UI reflects what's actually wired (fixes 'not configured' false alarm)
2026-05-23 02:58:32 +00:00
328f7b4f31 feat: live HLS preview, proxy worker fixes, Settings tabs, growing-files + Premier panel
- worker/proxy: scale-to-even filter, analyzeduration 100M, skip images, hasAudio
- worker/promotion: SMB landing zone -> S3 on idle, queues proxy job, status='ready'
- web-ui screens-ingest: HlsPreview component replaces fake LiveStrip/FauxFrame
- web-ui screens-admin: functional Settings tabs (S3, GPU, Growing, SDI, AMPP)
- mam-api /settings/growing: GET/PUT growing-files config
- mam-api /assets/:id/live-path: SMB UNC/POSIX path for live growing assets
- capture-manager: GROWING_ENABLED -> write hires to /growing instead of S3 stream
- recorders.js: pass GROWING_ENABLED to capture container, bind /growing mount
- docker-compose: mount /mnt/NVME/MAM/wild-dragon-growing on mam-api + worker
- premiere-plugin: Mount Live button, Relink-to-HiRes, live->ready status poll
2026-05-22 19:12:53 -04:00
817eaff8b1 feat: add getMediaInfo to executor.js using ffprobe JSON output
Exposes video stream fps/codec/resolution and container duration/size
so the proxy worker can populate asset metadata after transcoding.
2026-05-18 23:22:26 -04:00
8be9c20124 fix(infra+workers): S3 creds, ffprobe, BullMQ awaits, thumbnail seek, bin optional, docker-compose vars, jobs Redis, recorders stop codes: executor.js 2026-05-16 00:29:49 -04:00
5bc6cf7c17 add services/worker/src/ffmpeg/executor.js 2026-04-07 21:58:21 -04:00