feat: add --from/--to video clipping flags#15
Conversation
…ect clip semantics
Co-authored-by: devin-ai-integration[bot] <158243242+devin-ai-integration[bot]@users.noreply.github.com>
|
|
||
| const timeoutMs = timeout ?? 120000; | ||
| const noProgressTimeoutMs = 30000; | ||
| const noProgressTimeoutMs = 60000; |
There was a problem hiding this comment.
🔴 No-progress timeout kills ffmpeg during slow HLS seek before encoding can start
When clipping an HLS stream with --from, the code uses slow/accurate seek (-ss after -i), which requires ffmpeg to download and decode the entire HLS stream up to the seek point before writing any output. During this seek phase, the output file either doesn't exist or contains only a tiny header and does not grow. The 60-second noProgressTimeoutMs poll at src/ffmpeg.ts:75-107 monitors output file size growth and will kill ffmpeg after 60 seconds of no growth, even though ffmpeg is actively downloading and decoding HLS segments.
Root Cause and Impact
The timeline for --from 05:00 on an HLS stream is:
lastProgressTimeinitialized toDate.now()at line 38- ffmpeg spawned — begins downloading HLS segments and decoding
- Output file either doesn't exist yet or has a tiny ftyp header (~32 bytes)
- 60 seconds later, poll at line 86/96 fires:
now - lastProgressTime > noProgressTimeoutMs→ ffmpeg killed with error "FFMPEG stuck: no progress for 60 seconds"
The previous 30-second timeout was fine because non-clipping HLS downloads use -c copy (stream copy), which writes output immediately. The PR increased it to 60s, but slow seek on HLS requires downloading the full input up to the seek point, which can take minutes for non-trivial --from values.
Impact: The HLS clipping feature is broken for any --from value where the HLS content before the seek point takes more than ~60 seconds to download and decode. For example, --from 05:00 would require downloading ~5 minutes of HLS segments before producing output, but ffmpeg is killed after 60 seconds.
Prompt for agents
In src/ffmpeg.ts, the noProgressTimeoutMs at line 36 needs to account for HLS slow seek. When clipping is active (clipFromSecs is defined), ffmpeg uses -ss after -i which means it must download and decode the entire stream up to the seek point before any output is written. The 60-second no-progress timeout kills ffmpeg before it can start encoding.
Possible fixes:
1. When isClipping is true (line 42), either disable the no-progress polling entirely, or scale the noProgressTimeoutMs based on clipFromSecs (e.g. clipFromSecs * 2 * 1000 + 60000) to give ffmpeg enough time to seek through the input.
2. Alternatively, monitor ffmpeg's stderr for progress information instead of polling output file size, since ffmpeg can report processing progress even during the seek phase.
3. As a simpler fix, set noProgressTimeoutMs to a much larger value (e.g. the full timeoutMs) when clipping is active, and rely solely on the overall timeout.
Was this helpful? React with 👍 or 👎 to provide feedback.
Summary
--from <MM:SS>and--to <MM:SS>CLI flags to clip downloaded videos to a time range_clipsuffix (e.g.username_123_clip.mp4)-ssafter-i) with re-encode to h264/aac for QuickTime compatibilityshowVersion()now reads frompackage.jsoninstead of a hardcoded stringTest Plan
x-dl --from 00:05 --to 00:10 <tweet-url>produces a ~5s clip in~/Downloads*_clip.mp4and opens in QuickTime Playerx-dl --helpshows--fromand--toin OPTIONS and CLIP EXAMPLESx-dl -vshows0.4.4--from/--toare unchanged🤖 Generated with Claude Code