MattMcManis / Axiom

An FFmpeg GUI for Windows
https://axiomui.github.io
GNU General Public License v3.0
1.53k stars 118 forks source link

[FEATURE REQ] Variables/tokens in output file name #50

Open jorgebr opened 4 years ago

jorgebr commented 4 years ago

Ok, I submitted two issues and you solved them within a couple of days. Blown away! So I'm probably over-reaching now :-), but here's another enhancement idea.

When I'm trying different permutations to see what quality/space/time tradeoffs are best in different situations, I end up naming my output files with the encoding parameters, e.g.: "outfilename 1080p x265 crf35 p-superfast opus.mp4" "outfilename 1080p x265 crf30 p-superfast opus.mp4" "outfilename 1080p x265 crf25 p-medium opus.mp4" etc.

Variable/token placeholders in the output filename would remove the need to edit the output filename in the script manually. For example: "outfilename \<size> \<vcodec> crf\<crf> p-\<preset> \<audiocodec>.mp4"

I chose the "<>" signs as the delimiters because a) those two characters are not allowed in Windows filenames , b) makes it easy to read, and c) thought it would be easier for a parsing routine than using the same character before and after the token (e.g. :crf: :size:). But I don't know if that's the best choice, or there is a more "standard" syntax that should be used.

Alternatives:

Can't say this enough -- thank you for this wonderful piece of work! ffmpeg syntax is so overwhelming at first glance. Without Axiom, I never would have gotten started using it.

References: https://docs.microsoft.com/en-us/windows/win32/msi/filename https://ffmpeg.org/ffmpeg-all.html#Syntax https://blog.frame.io/2017/11/22/9-premiere-pro-export-settings/ https://workflow.frame.io/guide/file-naming

MattMcManis commented 4 years ago

I've never used variable tokens with ffmpeg before, I'm not sure if it supports that, I will have to ask.

What if I had an output naming section with checkboxes that let you select which settings you want displayed in the output filename? I would have C# variables generate the output filename automatically in the script, then you wouldn't need ffmpeg syntax.

[x] hwaccel
[x] vcodec
[x] pass (1, 2, crf)
[x] bitrate (bv/qv)
[ ] preset
[x] pixelformat
[ ] framerate
[x] size
[ ] scaling

[x] acodec
[ ] channel
[x] bitrate (ba/qa)
[ ] compression
[ ] samplerate
[ ] bitdepth

outfilename.mp4

outfilename Intel-QSV x265 CRF25 yuvj420p 1080p AAC 320k.mp4

jorgebr commented 4 years ago

That's a great idea. It eliminates the work of parsing the output filename.

I have one more thought, to avoid typing or copy/paste into the Output filename field altogether -- split the Output Naming Section in two, adding a section to copy parts of the input filename: -------------------------------------------------------------------------------------------- Copy from Input filename [ ] path   [ ] filename   [ ] extension

Suffixes Inserted after (if any) the input path, input filename, and Output textfield. [ ] ... your list ... --------------------------------------------------------------------------------------------

The final output filename would be a concatenation, in order, of:

[input path if checked] 
[text in Output field, if not blank and contains at least one backslash "\\"] 
[input filename if checked] 
[text in Output field, if not blank and does not contain any backslashes "\\"]
[any suffixes checked]
[input extension if checked, otherwise automatically generated given "Container"]

Notes

Examples

All the examples below assume:

Input
path
Input
filename
Input
extension
Output
textbox
Suffixes Result
[x] [x] [x] pass C:\path\to\infile CRF25.mkv
[x] outText [x] pass C:\path\to\outText CRF25.mkv
----- ---- -------- ------------ ---- ----
[x] [x] outText [x] pass C:\path\to\infileoutText CRF25.mkv
* outText does not have a leading space.
[x] [x] ˽outText [x] pass C:\path\to\infile outText CRF25.mkv
* I use "˽" to indicate a leading space.
----- ---- -------- ------------ ---- ----
[x] outText [x] pass \infileoutText CRF25.mkv
* You already catch this and prepend a backslash "\". Thus it's saved in root directory.
----- ---- -------- ------------ ---- ----
[x] C:\new\path\ [x] pass C:\new\path\infile CRF25.mkv
* Output filename has at least one backslash "\", indicating a path, and a trailing backslash, so it appears before the input filename, if checked.
C:\new\path\outfile [x] pass C:\new\path\outfile CRF25.mkv
* Output filename has at least one backslash "\", indicating a path, with no trailing backslash, and [ ] input filename not checked. Output filename is the combined path\filename.
[x] C:\new\path\outfile [x] pass C:\new\path\infileoutfile CRF25.mkv
* Corner case: Output filename has at least one backslash "\", indicating a path, with no trailing backslash, but [x] input filename is checked. You would have to catch this special case and split the Output textbox value into its path and filename components. The result is then [path][infile][filename].
----- ---- -------- ------------ ---- ----
[x] [x] [x] C:\path\to\infile.mp4
* Beware! Output filename same as input filename.
\.mkv
* Beware! You prepend backslash "\" but still, empty filename.
[x] C:\path\to\.mkv
* Beware! Empty filename.

Notes:

MattMcManis commented 4 years ago

@jorgebr

I will go over this and try to add these features.

The first release might be more simplified until it is complete.

The Output File Namer in Axiom might already handle some of the path issues. It also has a File Renamer that appends (1) to the name if it already exists, to avoid accidental overwrite.

The File Settings Namer will work similar to how the Subtitle menu works. You'll be able to position the settings in the order that you want if needed. Checked settings will be applied to the output filename. You can also Select All, Deselect All, and Load Defaults.

It will take some time to complete, I have to make it work with the axiom.conf config file, so it saves the selected settings on exit.

MattMcManis commented 4 years ago

@jorgebr

I've released an update here
https://github.com/MattMcManis/Axiom/releases
https://github.com/MattMcManis/Axiom/releases/download/v1.9.1.3-alpha/Axiom.zip

I have not uploaded the version file yet, so it will not notify users, and the update button in the program won't detect it.

If you will test it for me first, then I will release the official update in 2 days.


Example Output File Naming

Format Input Ext mpg

Video HW Accel Intel-QSV Video Codec x264 Pass 2-Pass Video Bit Rate 1234K/1.234M Video CRF CRF25 Preset p-medium Pixel Format yuv420p Frame Rate 30fps Size 1080p Scaling sa-gauss

Audio Audio Codec FLAC Channel CH-Stereo Audio Bit Rate 500k/500kVBR Sample Rate 48kHz Bit Depth 32-bit

MyFile mpg Intel-QSV x264 1234K CRF25 p-medium yuv420p 30fps 1080p sa-gauss FLAC CH-Stereo 500k 48kHz 32-bit.mkv

Instructions

  1. Go to the Settings Tab

  2. Under OutputNaming, check the settings you want to appear in the Output Filename

  3. Select an Input file

  4. Select your Quality settings

  5. Press the Output button to save the file, or press Script to generate, the output filename and path will be automatically filled in

  6. Your chosen setting should appear in the output filename

  7. Settings you choose with menus and controls will be applied to the filename in real-time

  8. Flip through the Presets to watch the output textbox filename quickly change

jorgebr commented 4 years ago

It's looking great! I like how you did the interface.

I did a couple of quick tests, but unfortunately I won't be able to do more extensive testing for a few days. So far, I found:

But overall, this is a phenomenal first version!

MattMcManis commented 4 years ago

@jorgebr

Thanks for testing, I will take a look at these issues and re-upload some improved versions over the next 2 days. I'll notify you when I release a fix.

MattMcManis commented 4 years ago

@jorgebr

I've updated the v1.9.1.0 release file, download it again and replace your Axiom.exe.

https://github.com/MattMcManis/Axiom/releases https://github.com/MattMcManis/Axiom/releases/download/v1.9.1.3-alpha/Axiom.zip


With the new version fixes:

Output Name Edits

Only edit the Output Filename in the Save File Dialog Window. When you click Save, Axiom will save the original name to a variable outputFileName_Original. Then Tokens will be applied on top of that and saved to a new variable outputFileName_Tokens. This way, there are 2 variables, original name and name+tokens. Now Axiom can always reference the original name when it makes name changes.

But if you edit the name in the Output TextBox while it already has Name Tokens VP8 CRF25 etc. applied, it will think those Tokens are part of the original output filename, and new ones will be applied on top, duplicating them.

The only way to fix this is to have some regex Token remover that backwards engineers the original output filename from the Output TextBox's text. That is possible to do, but will take some time, and may not always work 100%. It has a chance to accidentally strip character sequences that it thinks are Tokens but are not, depending on the filename.


New Token Additions

Video Codec Copy cv-copy Audio Codec Copy ca-copy Size Source sz-source Channel now renders 1CH(mono), 2CH (stereo/joint stereo), 5.1CH, etc.

You'll see them in the Settings Tab Output Naming section, at the bottom of the list. They are separate settings from Video Codec, Audio Codec, Size, so that you can choose to disable them completely for fine tuning the naming.

Press the Load Defaults ↺ button to automatically reorder the list. Doing this will uncheck them all, so you'll have to re-check the ones you want. I would find a way to make it insert newly added token imports in the correct order, but I don't plan on adding many more token types, so it shouldn't be an issue in the future.

MattMcManis commented 4 years ago

@jorgebr

I've added the Regex Token Remover.

https://github.com/MattMcManis/Axiom/releases


When you edit the file name in the Output TextBox, the program can't see what part of the text you changed, so it doesn't understand there's a new file name.

So now I have it backwards engineer the new name by stripping the tokens.


You edit output name text: Donkey Kong mp4 VP8 CRF16.webm -> New Name mp4 VP8 CRF16.webm


The Regex Token Remover:

1. Strips the tags, leaving only your new file name text. New Name mp4 VP8 CRF16New Name

2. Saves the name to a variable. New NameoutputFileName_Original

3. Re-applies the Tokens. outputFileName_Original + TokensNew Name mp4 VP8 CRF16.webm

It does this in a split second as you type.


Here's an example of regex rules it generates and filters. The actual code in the program covers all the possible dropdown menu tokens, as it dynamically generates them from the menu items.

https://regex101.com/r/iepwCq/1

jorgebr commented 4 years ago

I did a quick test and it's working. What you did with the regex token remover is brilliant! I can edit the filename in the Output field and it still works.

However, I'm not convinced that should be the interface. There are too many corner cases that could confuse users. They could expect, for example, that if they edit some of the tokens, those changes would be maintained. It's just too much of a new concept, and I fear you'll get a lot of confused people.

Is it not possible to have a separate read-only field which displays the generated name, and thus the Output field would only be used for text that is intended to be edited by the user?


Regardless, the improvement so far is incredible. In fact, it is so good, and it makes it so easy to kick-start multiple processes, that I had to figure out how to "title" the CMD windows so I could easily identify which window is what. I ended up adding a title command, prior to the start command, as follows: title "CRF35 .. " & start "" /b /wait /low....

The resulting window looks like this: image

The 1st argument to the start command is supposed to be the window title, but if I just use that, as follows: start "CRF30 ..." /b /wait /low ...

the window looks like:

image

Note the whole pathname to cmd.exe appears first, and that makes it difficult on the eyes.

I really like this and I use it a lot. But I can't really think of a good user interface other than having yet another field called "Shell window title". It's not really possible to auto derive which text is the best reminder of what a particular window is doing, and so it's best left to the user to enter it in, or leave it blank. Is this something that you'd consider?


I'm sorry but I won't be able to do more testing until the weekend. Best!

MattMcManis commented 4 years ago

@jorgebr

Thanks for testing. I'm making more improvements.

I'm not sure I want to add another field for the naming, I'm trying to keep the program compact. I'll see if I can make some adjustments so you can edit the tokens.

For Process Priority, I could add a Shell Title menu. What if I had a toggle with the options for User Custom, which leaves it blank title "" and Tokens, which injects them into the title title " VP8 1300K CRF16"?

MattMcManis commented 4 years ago

@jorgebr

I've attached an update v1.9.1.4 to this post for you, before I release it.

Axiom.zip


I overhauled all the code behind the Output Button and OutputPath() method to make functionality more logical.


I added the Shell Title Menu with options:


There were a few bugs in the regex, such missing input file formats, and fps with decimal 23.976.


I have not yet tested it all extensively.

jorgebr commented 4 years ago

I was able to do a quick run, and found a bug:

  1. Enter in Input filename: c:\path\to\Wild.Kratts S03E02 Where The Bison Roam 1080p x264.mkv Output filename: leave blank. Other settings: x265 crf30 AAC Preset=superfast Pixel format=yuv420p Output naming checkboxes (in case that matters): Video Codec, Video Codec Copy, Video CRF, Preset, Pixel Format, Audio Codec

  2. Click "Script". Output filename field becomes: " c:\path\to\Wild.Kratts S03E02 Where The Bison Roam 1080p x264 x265 CRF32 p-super-fast yuv420p AAC.mkv" So far so good.

  3. In Output filename field, delete the word "x264" and hit Delete. The Regex Token Remover seems to work...output name field value is as expected (same as before but without the "x264").

  4. But now click "Script" and filename in Output field becomes: "Wild.Kt S03E02 Where The Bison Roam 1080p x265 CRF32 p-super-fast yuv420p AAC.mkv" ("Kratt" became "Kt")

Just fyi, I was about to report this bug on version 1.9.1.3, for which the filename became: "Wild x265 CRF32 p-super-fast yuv420p AAC.mkv" (Anything after the "." got lost)


Really like the options on the drop-down for window title, but I would change the word "Job" to "Filename". I almost didn't try it, thinking it would be "process number". I was going to write here that I didn't like the options, but figured I better try it first. And then I was surprised to see that it really is the filename. Now I love it, and the fact that you give options for filename only, tokens only, or both, is really useful!

jorgebr commented 4 years ago

Minor issue: Same setup as above, but tried to change the extension in the Output field to ".mp4". It gets over-written back to ".mkv" when "Script" is clicked. Would need to make clear that can't edit anything after the 1st auto-generated token?

jorgebr commented 4 years ago

On the prior bug, another case, same sequence, this time without a period in the filename: Input filename: "Wild Kratts S03E03 Bandito The Black Footed Ferret 1080p x264.mkv" w/blank Output field, clicking "Script" auto-generates: "Wild Kratts S03E03 Bandito The Black Footed Ferret 1080p x264 x265 CRF30 p-super-fast yuv420p AAC.mp4"

Then manually deleting "x264" in the Output text, then click "Script", results in : "Wild Kt S03E03 Bandito The Black Footed Ferret 1080p x265 CRF30 p-super-fast yuv420p AAC.mp4" (Same issue: "Kratts" becomes "Kt", but note the original filename did not have a "." in it. There must be something else going on.)

MattMcManis commented 4 years ago

@jorgebr

It's regex errors, catching the wrong sections of the text. The regex rules for file formats ra and ts were applied to the filename. I think I can isolate it so it doesn't catch partial text.

Here's the regex generated for your selected options: https://regex101.com/r/Q3tBJB/1


My new idea is to remove the Tokens Display from the Output TextBox and have them only appear in the Script. That way user can edit the original name in the Output TextBox without the Regex Remover messing it up.

Then if you want to edit any Tokens, you can do so in the Script and the Regex Remover won't interfere. Then press Run and it will use your custom changes.


Another thing is that I did not anticipate using Input Files that already have tokens in the name. Maybe I will extend the Token Remover to remove other Tokens that were applied by users or other programs, to prevent Tokens from doubling up.

MattMcManis commented 4 years ago

@jorgebr

I've redesigned the Token system.

Axiom.zip


Tags will be the term I use for Input Filename Settings.
Tokens will be the term I use for Output Filename Settings.


In the Settings Tab, I added an Input section, with a Tags Menu. You can set it to Keep or Remove.

This will try to strip all possible Tags out of the Input Filename, revealing the Original Filename.

Mario NES mpg x264 CRF25 p-medium yuv420p 720p AAC 2CH 256k.mp4Mario NES.mp4

Now the Output Filename can have new Tokens applied to the Original Filename.

Mario NES.webmMario NES mp4 VP8 1300K CRF16 yuv420p Vorbis 192kVBR.webm


Converting mpg (no tags)mp4+tokens

Converting mp4+tagswebm+tokens

jorgebr commented 4 years ago

Hmmm... I think this is confusing.

First, removing the Output Tokens from the Output TextBox, and showing them only in the script, is definitely better, because the user now won't think the tokens are editable. And showing the output result in the script is a good compromise to avoid having to create an extra read-only field.

On the other hand, I find the name of "Tags" for the input confusing, because it is a non-standard use of the word. "Tags" are used for many other purposes (i.e. tagging), and this makes it hard to think of that word in this context.

But also, why is this even necessary? Now that you don't have tokens in the Output field, you don't need the Regex Token Remover at all. You have the "Input" field:

OR, perhaps a better idea, don't worry about auto-filling the Output field at all. Have a small button (an arrow pointing from the Input field to Output field) that "copies Input field to Output field", except substituting the extension given the "Container" selection. And that's it.

Sequence for most use cases:

  1. Drag new file to Input field
  2. Click that new arrow button, which replaces whatever is in the Output field with the new value in the Input field (except for the extension replacement).

That's it! User can click "Script" or "Convert". This is a really fast workflow.


Separate thought that may no longer be applicable since I'm suggesting you no longer need the Regex Token Remover. You regex expression is trying to filter out all possible tokens individually. That's partly why it's so hard to cover all the cases. But, in the simple case, you know the entire token string (all the tokens) to be generated. Why not search and replace that entire string, instead of on a token by token basis?

jorgebr commented 4 years ago

Wow... I just found a trick you may be interested in. It's really cool I have to search for these new tricks because your improvements have made it so easy to kickstart a bunch of processes and let them run.

If "Quick Edit" is turned on, simply selecting text in the cmd window will pause the process!
This actually works, unlike "Ctrl-S/Ctrl-Q" which only pauses the display update but not the process. Found it here: https://medium.com/@harshg0910/click-to-pause-execution-in-windows-powershell-b451044501ac

Alternatively, could use resmon, the Resource Manager, which provides a GUI option to suspend a process. The standard Task Manager does not have that option.

MattMcManis commented 4 years ago

@jorgebr

I can change Tags to Tokens.

You will need the Regex Token Remover because if the Input Filename has existing Tokens, the Output Naming will add the new Tokens alongside the existing ones.

mp4 to webm

Doubled Up x264/AAC and VP8/Vorbis Tokens Input: File x264 CRF20 AAC 320k.mp4
Output: File x264 CRF20 AAC 320k VP8 1300K CRF25 Vorbis 224k.webm

Removed with Regex Input: File x264 CRF20 AAC 320k.mp4
Output: File VP8 1300K CRF25 Vorbis 224k.webm


If the Input Filename has custom Tokens by users or other programs:

mp4 to webm

Removed with Regex Input: File 1920x1080 [x264] Dolby Digital 5.1 Eng-Subs.mp4Output: File VP8 1300K CRF25 Vorbis 224k.webm


I'll see about having it clear the Output TextBox every time the Input TextBox is changed.

jorgebr commented 4 years ago

I don't understand why the first example is a problem: File x264 CRF20 AAC 320k VP8 1300K CRF25 Vorbis 224k.webm

The "conflicting" tokens (eg x264 vs VP8, CRF20 vs CRF25) are just a happenstance that the Input file name has tokens, and so it's up to the user to deal with it. The ability to edit the Script is a good way to do that.

In return, you gain simplicity, for both the user and you. You remove the chance that a user could be confused by the original filename being "changed" by the auto-fill. And you don't need the Regex Token Remover anymore.

And if you want to retain the ability to remove tokens from the input (I can definitely imagine times when it could be useful) , I would make that a separate button, perhaps using an icon of a broom or some other "cleaning" icon.

MattMcManis commented 4 years ago

@jorgebr

Axiom.zip

Updates:


Output Filename Spacing

This can convert all spaces into periods, dashes, or underscores, if needed.
I would just leave it on Original if not needed.

spaces to periods/dashes/underscores Input: File x264 CRF25 AAC 123k 44.1kHz.mp4
Output: File.x264.CRF25.AAC.123k.44.1kHz.mp4

It cannot yet however convert periods into dashes, etc., I still need to write the regex rules to handle preserving number decimal points in tokens like 44.1kHz.

periods to dashes/underscores/spaces (doesn't work yet) Input: File.x264.CRF25.AAC.123k 44.1kHz.mp4
Output: File-x264-CRF25-AAC-123k-44.1kHz.mp4

jorgebr commented 4 years ago

Hi... 1:40am here. Just glanced at this. Won't have time to download it and try it till tomorrow, but quick thoughts:

Good night!

jorgebr commented 4 years ago

One more idea: is it easy to edit the Windows properties of the file? It would be great to add the tokens to the "Comments" property of the file. Here is a screenshot of the field I'm talking about. Just in case, to get this dialog, right-click on a file and select "Properties".

image

MattMcManis commented 4 years ago

Remember that the Spacing option can only do spacesperiods, but not periodsspaces until I can work out the advanced regex rules to preserve number decimal points. Or else 44.1kHz will end up 44 1kHz.

Update: Someone has given me a regex code that allows converting between all spaces, periods, dashes, underscores while preserving number decimals.

Axiom.zip


For Windows Properties Comments, I had looked into it before, but I think it was too complicated because there were many different file types that had different metadata tables, and some that Windows can't recognize. I think that since it's C# and uses some built-in Windows features to make file changes, it wouldn't work without some external library, such as FLAC. I will have to look into it again.

jorgebr commented 4 years ago

Downloaded the new version:

jorgebr commented 4 years ago

For the Windows Properties Comments, I agree with your decision that it's not worth that much effort. You are right, there's a lot of different permutations. I found out the hard way, for example, that I can edit the properties of mp4 files but not of Matroska (mkv) containers.

MattMcManis commented 4 years ago

I'll fix those issue.


I only added the Output TextBox clear on Input Button Press, I forgot to add it to Drag and Drop.


I'll have to add those Tokens, Amazon and DD, as well as many others, to the Remover.
It won't work 100% of the time unless I can cover all tokens.

Example, regex rules for Dolby Tokens alone need to cover:
Dolby (Digital, Pro, Pro II, TrueHD, Vision, etc), DDP, DD+, DD, 2.0, 5.1, 7.1, etc.

https://regex101.com/r/ggH54O/1


I'll have to see why it's combining leftover tags with no spaces nameAmazonDD.

MattMcManis commented 4 years ago

Added Input Drag and Drop clears Output TextBox
Added more Token types to the Regex Remover Fixed leftover Tokens combining without spaces.

https://github.com/MattMcManis/Axiom/releases/download/v1.9.2.0-alpha/Axiom.zip


Input Token Remover

  1. Filename File x264 CRF20 XYZ AAC 320k.mp4

  2. Regex identifies and removes tokens. It does not recognize XYZ (an example uncommon token, not in the regex rules). File x264 CRF20 XYZ AAC 320k.mp4

  3. New Filename without tokens. The uncommon token was left in. File XYZ.mp4

Output Token Appender

  1. Tokens are added to the end of the filename. File XYZ VP8 1300K CRF25 Vorbis 128k.webm

Here's the regex. Let me know if you find any tokens that don't work.

https://regex101.com/r/vcufKK/2

jorgebr commented 4 years ago

It's working great! One more token: YIFY

MattMcManis commented 4 years ago

@jorgebr

Try out this version
Axiom.zip

I want to avoid adding names of piracy groups into the code and program. I've only added general tokens. But I've added a text field where the user can add their own custom tokens and it will save/load them from the axiom.conf config file.

I've also added Input and Output Clear TextBox Buttons.

jorgebr commented 4 years ago

You are totally right -- adding a field for user tokens is a much better solution.
The ClearText box buttons work. And overall, it works great!

I mean, WHAT A JOB YOU'VE DONE! Right now, this is such a good tool! My workflow is exponentially faster. THANK YOU!

Right now, I can't think of any more improvement ideas for the one-file-at-a-time use case.


Just for the sake of contributing ideas for the future -- the next improvements I can think of are for queuing multiple runs. I will create a new issue for that titled "Queues"

MattMcManis commented 4 years ago

@jorgebr

Thanks for testing. We really took the program far.

The Remove option will still try to remove all general Tokens on its own, even if the Custom TextBox is empty, but the Custom TextBox will remove any extra Tokens you want to add.

I've done a little more work on it and released it v1.9.2.2.

There will probably always be hidden bugs, as the program is so big it's hard for me to test on my own, that's why it's still in alpha. By v2.0, once most of all the main features have been added I'd like to switch it to beta.