Repository: yt-dlp
Issue: Change the order of PostProcessors (Or add another PostProcessor stage)
Labels: enhancement,triage,core:post-processor

### DO NOT REMOVE OR SKIP THE ISSUE TEMPLATE

- [X] I understand that I will be **blocked** if I *intentionally* remove or skip any mandatory\* field

### Checklist

- [X] I'm requesting a feature unrelated to a specific site
- [X] I've looked through the [README](https://github.com/yt-dlp/yt-dlp#readme)
- [X] I've verified that I have **updated yt-dlp to nightly or master** ([update instructions](https://github.com/yt-dlp/yt-dlp#update-channels))
- [X] I've searched [known issues](https://github.com/yt-dlp/yt-dlp/issues/3766) and the [bugtracker](https://github.com/yt-dlp/yt-dlp/issues?q=) for similar issues **including closed ones**. DO NOT post duplicates
- [X] I've read the [guidelines for opening an issue](https://github.com/yt-dlp/yt-dlp/blob/master/CONTRIBUTING.md#opening-an-issue)

### Provide a description that is worded well enough to be understood

Looking at the code,

https://github.com/yt-dlp/yt-dlp/blob/111b61ddef305584d45a48e7b7c73ffcedf062a2/yt_dlp/__init__.py#L598-L725

Custom post-processors are set to execute before built-in post-processors.

I wonder if it would be possible (aka, not a massive breaking change) if the user supplied post-processors could execute after the built-ins. If not possible, would a new `when` stage (?) be acceptable e.g. `post_post_process` or `before_move`?

For example, here:

https://github.com/yt-dlp/yt-dlp/blob/111b61ddef305584d45a48e7b7c73ffcedf062a2/yt_dlp/YoutubeDL.py#L3715-L3722

## Why?

So right now, removing segments with sponsorblock causes artifacts in the resulting video file (e.g. sound with no video), as mentioned in https://github.com/yt-dlp/yt-dlp/issues/3766 (FAQ). The ultimate fix is to recreate valid keyframes (hence, `--force-keyframes-at-cuts`), if any keyframes were in the removed segments (if I understand FFmpeg's docs correctly). 

Since yt-dlp can't possibly know this, yt-dlp adds the `ModifyChapters` post-processor to re-encode the video with keyframes at the timestamps known to yt-dlp.

While the solution is completely valid, it can double post-processing time, if say, you are using the FFmpegCopyStream post-processor to convert the downloaded video into a usable format (say, downloading YouTube for Plex, which requires videos using the mainline profile, which requires both audio and video re-encoding, in most-cases). Given the order mentioned above, the cutting occurs after converting to the final format - causing a double encode.

To my knowledge, re-encoding after removing segments is all that's needed for this use-case (ignoring the use-case of ensuring chapters are along keyframe "lines"), as FFmpeg should generate keyframes as appropriate (to avoid the generation loss problem). Preferably, this could be done in a single pass - on the file with segments removed, aka, running the FFmpegCopyStream post-processor after cutting.

_Note that the exec post-procesor would work, since that one executes after all other post-processors in each stage. It would just be nice to use the existing plumbing._

### Provide verbose output that clearly demonstrates the problem

- [ ] Run **your** yt-dlp command with **-vU** flag added (`yt-dlp -vU <your command line>`)
- [ ] If using API, add `'verbose': True` to `YoutubeDL` params instead
- [ ] Copy the WHOLE output (starting with `[debug] Command-line config`) and insert it below

### Complete Verbose Output

_No response_