fix: SRT/RTMP ingest + thumbnail crashes #1

Closed
zgaetano wants to merge 1 commit from fix/srt-rtmp-thumbnail into main
Owner

Resolved in commits 508e978, 1afb150, 7a62965.

Diagnosis was three-part: (a) old recorder-captured assets had a hi-res original_s3_key but no proxy_s3_key, so /stream returned {url:null, reason:'no_proxy'} and the player showed nothing; (b) the proxy worker would happily accept an SVG as a video input and fail with "codec=svg, 0x0"; (c) /live HLS dirs accumulated on disk with no owning DB row.

Fixes:

  • POST /assets/:id/retry now accepts proxy-less assets in any status (ready/archived), not just error.
  • /stream returns has_source so the UI can decide intelligently.
  • Asset detail player shows a "Generate proxy" CTA when the stream lookup returns no_proxy and the source exists.
  • Proxy worker routes SVG (and any DB media_type='image') through the JPEG-poster path.
  • New POST /assets/cleanup-live-orphans endpoint reaps /live/<uuid>/ dirs whose UUID doesn't match a DB row. Ran it once during deploy and reaped 6 orphans.

Verified end-to-end against an archived sRT Test_… asset: /stream returned no_proxy → /retry queued the job → worker downloaded the master from S3 → emitted the clear-error path for the 1255-byte ftyp-only garbage MOV. A real-size master will produce a playable MP4 proxy when retried.

SRT source at srt://10.0.0.104:9999?mode=caller confirmed live (1920x1080 H.264 + AAC, 59.94fps) so new captures will work normally.

Resolved in commits 508e978, 1afb150, 7a62965. Diagnosis was three-part: (a) old recorder-captured assets had a hi-res `original_s3_key` but no `proxy_s3_key`, so `/stream` returned `{url:null, reason:'no_proxy'}` and the player showed nothing; (b) the proxy worker would happily accept an SVG as a video input and fail with "codec=svg, 0x0"; (c) /live HLS dirs accumulated on disk with no owning DB row. Fixes: - `POST /assets/:id/retry` now accepts proxy-less assets in any status (ready/archived), not just `error`. - `/stream` returns `has_source` so the UI can decide intelligently. - Asset detail player shows a "Generate proxy" CTA when the stream lookup returns `no_proxy` and the source exists. - Proxy worker routes SVG (and any DB `media_type='image'`) through the JPEG-poster path. - New `POST /assets/cleanup-live-orphans` endpoint reaps `/live/<uuid>/` dirs whose UUID doesn't match a DB row. Ran it once during deploy and reaped 6 orphans. Verified end-to-end against an archived `sRT Test_…` asset: `/stream` returned no_proxy → `/retry` queued the job → worker downloaded the master from S3 → emitted the clear-error path for the 1255-byte ftyp-only garbage MOV. A real-size master will produce a playable MP4 proxy when retried. SRT source at `srt://10.0.0.104:9999?mode=caller` confirmed live (1920x1080 H.264 + AAC, 59.94fps) so new captures will work normally.
zgaetano added 1 commit 2026-05-17 07:02:37 -04:00
Recorder model was creating capture containers but ffmpeg never spawned
inside them, so SRT/RTMP listeners bound the host port without ingesting
anything. Thumbnail extraction was also crashing on yuv444p sources,
leaving uploaded assets stuck at status=processing forever.

* capture/src/index.js: read RECORDER_ID/SOURCE_TYPE/LISTEN/LISTEN_PORT/
  STREAM_KEY/SOURCE_URL from env on startup and call captureManager.start()
  immediately. SIGTERM handler now flushes ffmpeg + S3 upload and POSTs the
  asset to mam-api before exiting.
* worker/ffmpeg/executor.js: force -pix_fmt yuv420p on proxy transcode and
  -pix_fmt yuvj420p on thumbnail extraction so mjpeg encoder accepts the
  input regardless of source pixel format.
* mam-api/routes/assets.js: when capture posts proxyKey=null but hiresKey
  is set (SRT/RTMP case), enqueue a proxy job from the hires so the asset
  ends up with a browser-playable proxy + thumbnail instead of stuck-ready.
* mam-api/routes/recorders.js: accept UI field aliases (codec/resolution/
  proxy_config), clean up unstarted containers on port collision, bump the
  docker stop timeout to 5min so long uploads can flush.
* web-ui/recorders.html: change default ports from 1935/9000 to 41936/49001
  to avoid common collisions with other RTMP/SRT services.
zgaetano closed this pull request 2026-05-23 13:20:22 -04:00

Pull request closed

Sign in to join this conversation.
No reviewers
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference: WildDragonLLC/dragonflight#1
No description provided.