Why Graceful Shutdown Matters
When you cancel a running FFmpeg process, you have two options:- Immediate kill (SIGKILL): The process terminates instantly, but the output file may be corrupted or unplayable because headers weren’t finalized.
-
Graceful shutdown: Send FFmpeg the
qcommand via stdin, allowing it to:- Flush buffers
- Write final metadata
- Properly close the output file
- Produce a valid, playable file up to the point of cancellation
ffmpeg_graceful() function implements the second approach with a fallback: it sends the quit command and waits up to 5 seconds for clean exit, then falls back to SIGKILL if needed.
Complete Example
How It Works
Let’s look at the implementation offfmpeg_graceful() from the libffmpeg source:
The Shutdown Flow
When you cancel affmpeg_graceful() operation, here’s what happens:
-
User triggers cancellation (e.g., presses Ctrl+C)
-
Shutdown handler wakes up and sends the quit command
-
FFmpeg receives ‘q’ on stdin and begins graceful shutdown:
- Stops reading input
- Flushes encoder buffers
- Writes file trailer/metadata
- Closes output file
- Exits with status code
-
Two possible outcomes:
a. Success (within 5 seconds):
- FFmpeg exits cleanly
exit_tokenis cancelled- Output file is properly finalized
process_token.cancel()is called- SIGKILL sent to FFmpeg
- Process terminates immediately
- Output file may be incomplete
Key Differences from Standard ffmpeg()
| Feature | ffmpeg() | ffmpeg_graceful() |
|---|---|---|
| Cancellation | Immediate SIGKILL | Sends ‘q’, waits 5s, then SIGKILL |
| Output finalization | No guarantee | Output finalized if process responds |
| Cancellation latency | Instant | Up to 5 seconds |
| Output validity | May be corrupted | Valid up to cancellation point |
Using with Progress Monitoring
You can combine graceful shutdown with progress monitoring:Cancellation Token Hierarchy
A common pattern is to use child tokens for different parts of the operation:root_token.cancel() is called:
- Both
transcode_tokenandmonitor_tokenare automatically cancelled - FFmpeg begins graceful shutdown
- Monitor task stops receiving messages
- Everything cleans up in order
Testing Graceful Shutdown
To test that graceful shutdown is working:When to Use Each Function
ffmpeg_slim(): Quick operations where cancellation isn’t expected or output validity doesn’t matterffmpeg(): When you need progress monitoring but not graceful shutdown (e.g., short operations)ffmpeg_graceful(): Long-running operations where cancelled output should still be valid and playable
Best Practices
- Always use graceful shutdown for user-facing applications where Ctrl+C cancellation is expected
-
Set reasonable timeouts if 5 seconds is too long for your use case:
-
Handle both success and cancellation in your UI:
- Test cancellation behavior to ensure output files are valid
- Combine with progress monitoring to give users feedback during long operations
See Also
- Basic Transcode - Simple transcoding without graceful shutdown
- Progress Monitoring - Real-time progress tracking