Repository: yt-dlp
Issue: intelligent filename trim
Labels: enhancement,triage

### 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'm running yt-dlp version **2023.03.04** ([update instructions](https://github.com/yt-dlp/yt-dlp#update)) or later (specify commit)
- [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

# problem
When a `-o` filepath\filename template consists of multiple fields, and the sum of the length of all these fields must not exceed
`OS limit - (length of the temporary files appendix + length of yt-dlp download base path)`, the problem is how to best curtail these fields, which can vary considerably in length and are therefore unpredictable.

To simplify:
It's difficult to ensure `A+B+C+D < OS limit` when `A`, `B`, `C`, `D` greatly vary in length.

While it is certainly possible to set a dumb limit for each field: `A.50+B.50+C.50+D.50 + base path + appendix < 255`
this is not a intelligent solution, if for example
```
A = 120 bytes
B = 50 bytes
C = 10 bytes
D = 20 bytes
```
because in this case `A` will be unnecessarily truncated to less than half its length.

# example
`-o "%(alt_title,title).100B\%(title).100B [%(extractor)s.%(id)s] {%(format_id)s}.%(ext)s"`

* `extractor` is quite short and doesn't require any further shortening
* cutting off `id` and `format_id` makes them useless, although they can become quite lengthy in some cases
* so that leaves us only with `alt_title` and `title` which can be shortened

The above template should work in most cases, but can still exceed the OS limit when `id` and/or `format_id` are lengthy.

# current solutions

1. So one solution would be to add further curtailing:
    `-o "%(alt_title,title).40B\%(title).100B [%(extractor)s.%(id)s] {%(format_id)s}.%(ext)s"`
    But this shortens the video directory so severely that it becomes barely readable.

2. `--trim-filenames` but #3494 and possibly broken:
      > This should produce the file `../testfolder/Me at.webm`, but instead it produces the file `testf.webm`.
      > 
      > Worse still, if the `--output` argument is an absolute path like `/home/myname/folder/folder/stuff`, yt-dlp will try to create a file in the root directory called `/home/.webm`.
      > 
      > So, I think `--trim-filenames` is broken.

   and from https://github.com/yt-dlp/yt-dlp/issues/5499#issuecomment-1311939459 :

      > the whole path will be trimmed, not only the filename. The file might end up in one of the parent directories.

     so this is [not a recommended solution](https://github.com/yt-dlp/yt-dlp/issues/3494#issuecomment-1103969834) :

      > I honestly recommend using something like [outtmpl] instead to control the filename length

     and https://github.com/yt-dlp/yt-dlp/issues/2314#issuecomment-1011295071 :

     > I am aware of this issue 😓. The `--trim-filename` option is just overall poorly implemented, making this tricky to fix. I honestly suggest using something like `%(title).30B.%(ext)s` instead

     and [here](https://github.com/yt-dlp/yt-dlp/issues/1837#issuecomment-981907118): 

     > `--trim-filename` was added in youtube-dlc and actually quite buggy. I can fix this particular issue, but I recommend using the string formatting to achieve a similar effect. Eg: `-o %(title).200s.%(ext)s`



# enhancement idea
It would really be great to be able to intelligently trim the filename, i.e. trim
1. **ONLY in case it is needed ...** 
   (The idea is a bit like in #6972 to use this enhancement **"only as a fallback"** in case it is needed.)

2. **... and at a user-defined place.**
(As opposed to `--trim-filenames` which trims at end, thereby causing the same errors in my tests as described by @axcore  above in #3494 and @Fabian42 in #1888:

> What currently happens if I use `--trim-filenames` is that the ID gets cut off completely if the title is too long. In the worst case, if I'm downloading a playlist of videos with titles like "Super long series title, episode 42: XYZ", I would get completely identical filenames and all downloads after the first one would get skipped.

# implemenation 
The user can indicate at which position this intelligent trim should occur if needed.
Something like:
* `-o "%(alt_title,title).100B+\%(title).100B [%(extractor)s.%(id)s] {%(format_id)s}.%(ext)s"` : the plus sign indicates that this field can be trimmed **further** than the 100B if otherwise the entire path\filename length exceeded OS limits.
* `-o "%(alt_title,title){100B-excesslength}\%(title).100B [%(extractor)s.%(id)s] {%(format_id)s}.%(ext)s"`

Maybe you'll find better implementation ideas.

It would also be a good idea to come up with some solution that would kick in by default (so that all users benefit from this enhancement and not just the 1% who dig into the jungle of parameters).

# benefits
* If the filepath becomes too long, this enhancement would save the download from failing.
* On the other hand, the filename length allowed by the OS can be fully used with this enhancement (as opposed to the currently possible solutions, where a "safe" filename template like `-o "%(alt_title,title).40B\%(title).40B [%(extractor)s.%(id)s] {%(format_id)s}.%(ext)s"` would waste / give away a lot of available space.
* This would allow trimming long paths at a user-defined position where it hurts less than at the end with `--trim-filenames`.

# workaround
What I currently do is essentially going back and forth between different config files:
* I have very generous length limits but therefore often run into filename-too-long problem.
* I then manually increase the length limit ristriction in my config file,
* delete the leftover files from the 1st run,
* run yt-dlp again and ...
* most of the time forget to reset the config file to its previous state,
* so that the filenames of my subsequent downloads are also truncated. 🙁

# related
* #1136 
* #3494
* #2314


### 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_