Avidemux Forum

Avidemux => Windows => Topic started by: pulsarstar on April 14, 2021, 08:57:30 AM

Title: How_To_Batch_File_Proccessing?
Post by: pulsarstar on April 14, 2021, 08:57:30 AM
Hi Guys,
I am a newbie to this forum,
I just installed Avidemux 2.7.8 the other day.
I have never worked with this program before.
I have been editing video films to change their volume.
I loaded in a video film titled "Taboo.mp4"
I changed Audio Output to AAC (FDK)
I changed Filters Gain Manual (DB)
And put Gain Value: 10
I changed the FDK-AAC configuration Bitrate from 128 to 192 (in the hope of improving the sound quality) ( not sure about that)?
Output Format was set for MKV Muxer
Then I saved my Video File as"Taboo.mkv"
On playing back the video I found the gain in the volume to be perfect for my needs.
I then looked at the software to process multiple video one after the other, so I could go to bed and leave it running overnight.
In the GUI interface I could not find this option! But I understand from reading online that a *.Bat file or script can be written to accomplish this task.
So here is my question to you Guys:
Can someone write me an example down, that I can cut and paste into my Windows 10 Notepad and save it as a *.Bat file ?
Thank you for your help:
Title: Re: How_To_Batch_File_Proccessing?
Post by: butterw on April 14, 2021, 09:32:04 AM
Quote from: pulsarstar on April 14, 2021, 08:57:30 AMI have been editing video films to change their volume.
I loaded in a video film titled "Taboo.mp4"
I changed Audio Output to AAC (FDK)
I changed Filters Gain Manual (DB)
And put Gain Value: 10
I changed the FDK-AAC configuration Bitrate from 128 to 192 (in the hope of improving the sound quality) ( not sure about that)?

You are re-encoding the audio (to add 10dB Gain).
- Quality is degraded vs the original. By increasing the bitrate you limit this degradation. 192kbps in FDK-AAC should achieve near transparency for stereo.
- Also be aware that applying gain blindly could lead to saturation of peaks.

IMO it would be preferable to use something like replaygain which normalizes the audio perceived loudness (foobar2K can modify mp4/m4a files without re-encoding them).

 
Title: Re: How_To_Batch_File_Proccessing?
Post by: pulsarstar on April 14, 2021, 09:48:02 AM
Thanks Butterw for the info on bitrate,
and on the advice of use of software foobar2k.
I will take a look at it.
If anyone else can answer the rest of my the question on batch file processing please do!
I would appreciate that.
Thanks for your contributions.

Title: Re: How_To_Batch_File_Proccessing?
Post by: butterw on April 14, 2021, 10:44:42 AM
for batch processing in Avidemux (ex: process all files in a directory):
- load one file, setup your filters/encoders/muxer as desired, save as project script.

Then modify the project script (.py) for batch processing with automated output filename save.
Title: Re: How_To_Batch_File_Proccessing?
Post by: pulsarstar on April 14, 2021, 12:41:14 PM
Hi butterw,
I have created my script (.py) file.
I don't understand the last line of your advice ?

Then modify the project script (.py) for batch processing with automated output filename save?

Is it an option on the GUI I have missed or should I edit the script file in notepad ?
this is my script (.py).

#PY  <- Needed to identify #
#--automatically built--

adm = Avidemux()
if not adm.loadVideo("G:/TABOO/Taboo_1._Episode_1.mp4"):
    raise("Cannot load G:/TABOO/Taboo_1._Episode_1.mp4")
adm.clearSegments()
adm.addSegment(0, 0, 3302200000)
adm.markerA = 0
adm.markerB = 3302200000
adm.setPostProc(3, 3, 0)
adm.videoCodec("Copy")
adm.audioClearTracks()
adm.setSourceTrackLanguage(0,"und")
if adm.audioTotalTracksCount() <= 0:
    raise("Cannot add audio track 0, total tracks: " + str(adm.audioTotalTracksCount()))
adm.audioAddTrack(0)
adm.audioCodec(0, "FDK_AAC", "bitrate=192", "afterburner=True", "profile=2", "sbr=False")
adm.audioSetDrc(0, 0)
adm.audioSetShift(0, 0, 0)
adm.audioSetNormalize2(0, 2, 120, -30)
adm.setContainer("MKV", "forceAspectRatio=False", "displayWidth=1280", "displayAspectRatio=2", "addColourInfo=False", "colMatrixCoeff=2", "colRange=0", "colTransfer=2", "colPrimaries=2")


Title: Re: How_To_Batch_File_Proccessing?
Post by: butterw on April 14, 2021, 02:37:56 PM
there are 2 different possible approaches:
- the first uses avidemux_cli and a bat file (I'm not familiar with this)
- the second is based on Tinypy scripting https://avidemux.org/smif/index.php/topic,19390.0.html : you need to edit the script to load the input files and save the output with the command adm.save(filepath).

Title: Re: How_To_Batch_File_Proccessing?
Post by: pulsarstar on April 14, 2021, 03:24:13 PM
OK.Thank you for your assistance.
I will give that a try, and see where it lands me.
I hope in future update versions of Avidemux the R & D Department include batch file processing in the GUI options.
This takes me back to the days of D.O.S. :'(  :'(  :'(
Title: Re: How_To_Batch_File_Proccessing?
Post by: eumagga0x2a on April 17, 2021, 01:11:59 PM
Quote from: pulsarstar on April 14, 2021, 03:24:13 PMI hope in future update versions of Avidemux the R & D Department include batch file processing in the GUI options.

You can queue tasks for later batch processing using Avidemux Jobs GUI, but the R & D Department doesn't think that inflating GUI is the way to go.

For your task, you could use the following untested script (copy and paste it into the Avidemux script console or save as a .py file and pass to the executable on the command line as the argument of the --run option:

#PY  <- Needed to identify #
#
ui = Gui()
adm = Avidemux()
ext = "mp4"
sep = "\\"
#
# Function to convert an individual video
#
def convert(filein,out):
    if not adm.loadVideo(filein):
        ui.displayError("oops","cannot load "+filein)
        return 0

    adm.videoCodec("Copy")
    if adm.audioTracksCount() > 0:
        adm.audioClearTracks()
        adm.audioAddTrack(0)
        adm.audioCodec(0, "FDK_AAC", "bitrate=192", "afterburner=True", "profile=2", "sbr=False")
        adm.audioSetDrc(0, 0)
        adm.audioSetShift(0, 0, 0)
        adm.audioSetNormalize2(0, 2, 120, -30)
    adm.setContainer("MKV", "forceAspectRatio=False", "displayWidth=1280", "displayAspectRatio=2", "addColourInfo=False", "colMatrixCoeff=2", "colRange=0", "colTransfer=2", "colPrimaries=2")

    filename = (splitext(filein))[0]
    filename += ".mkv"
    filename = basename(filename)
    return adm.save(out + sep + filename)
#
# Main
#
# -------- select extension --------
extensions = ["avi","m2ts","mkv","mov","mp4","mpg","ts","vob","webm","wmv"]
mx = len(extensions)

menuExt = DFMenu("Select extension:")
for entry in range(0, mx):
    menuExt.addItem(extensions[entry])
dia = DialogFactory("Filter directory content")
dia.addControl(menuExt)
if not dia.show():
    return

idx = menuExt.index

if idx < 0 or idx >= mx:
    ui.displayError("Oops", "Internal error: invalid menu index")
    return

ext = extensions[idx]

# -------- select input directory --------
inputFolder = ui.dirSelect("Select source folder")
if inputFolder is None:
    ui.displayError("Oops", "No source folder selected")
    return

# -------- read content --------
list = get_folder_content(inputFolder, ext)
if list is None:
    ui.displayError("Oops", "No " + ext + " files found in \"" + inputFolder + "\"")
    return

# -------- select output directory --------
outputFolder = ui.dirSelect("Select output folder")
if outputFolder is None:
    ui.displayError("Oops", "No output folder selected")
    return

if(inputFolder == outputFolder):
    ui.displayError("Error","Output folder cannot be the same as the input one")
    return

# -------- process --------
total = 0
counter = 0

for i in list:
    total += 1
    counter += convert(i, outputFolder)

if not counter:
    ui.displayInfo("Warning", "No files converted")
    return

if counter == 1:
    ui.displayInfo("Finished", "One file out of " + str(total) + " converted")
    return

ui.displayInfo("Finished", str(counter) + " files out of " + str(total) + " converted")

The script processes all files with given extension in a directory.
Title: Re: How_To_Batch_File_Proccessing?
Post by: pulsarstar on April 18, 2021, 03:13:17 PM
Thank you for the advise eumagga0x2a.
I appreciate that.
I will give that a try when I get chance.
Title: Re: How_To_Batch_File_Proccessing?
Post by: pulsarstar on April 19, 2021, 07:39:01 AM
Hi, eumagga0x2a
The script works perfectly, it does exactly what I wanted it to do.
I pasted the script into Tools> Script shell> in the Evaluate box.
I Evaluated it. Beautiful.
Could you tell me how to change the Gain mode: Manual (dB)
In the script to lower or raise the manual (dB)?
As I have never written any script in my entire life, I am guessing
If I change the values in
adm.audioSetNormalize2(0, 2, 120, -30)    ?
Or am I barking up the wrong tree ?
Thanks again for the script,
I would have never done it on my own.
Title: Re: How_To_Batch_File_Proccessing?
Post by: eumagga0x2a on April 19, 2021, 08:50:18 AM
Quote from: pulsarstar on April 19, 2021, 07:39:01 AMThe script works perfectly, it does exactly what I wanted it to do.
I pasted the script into Tools> Script shell> in the Evaluate box.
I Evaluated it. Beautiful.

Glad that it worked, you can save the script as a .py file and put it into the folder %appdata%\avidemux\custom for easy access. After restarting Avidemux, it should be available via the "Custom" menu.

Quote from: pulsarstar on April 19, 2021, 07:39:01 AMCould you tell me how to change the Gain mode: Manual (dB)
In the script to lower or raise the manual (dB)?
As I have never written any script in my entire life, I am guessing
If I change the values in
adm.audioSetNormalize2(0, 2, 120, -30)    ?

Absolutely correct. The first argument is the track index (counted from zero – "0" means the first audio track), the second one represents the gain mode (https://github.com/mean00/avidemux2/blob/master/avidemux_core/ADM_coreAudioFilter/include/audiofilter_normalize_param.h) (valid values are ADM_NO_GAIN = 0, ADM_GAIN_AUTOMATIC = 1, ADM_GAIN_MANUAL = 2 so that "2" means manual), the third is the gain value in 10*dB (e.g. "120" = +12 dB, "18" would be +1.8 dB), the last one is the maximum level in 10*dB ("-30" = -3 dB), evaluated only in automatic mode. All parameters must be integers (no fractions, no decimal point).
Title: Re: How_To_Batch_File_Proccessing?
Post by: pulsarstar on April 19, 2021, 09:59:13 AM
Thank You eumagga0x2a for such a clear and precise answer.
I shall enjoy working with this script.
I would like to teach myself this programming language.
The Script language used in Avidemux, is Python I believe?
Is there any good web pages that show all commands and examples of how to use the Script in Avidemux?
I found this web page (http://avidemux.sourceforge.net/doc/en/script.xml.html)
I was looking for a lot more info. Especially for beginners/Newbies.
I was looking for something like the old DOS manual,
With command and example of use underneath.
Title: Re: How_To_Batch_File_Proccessing?
Post by: butterw on April 19, 2021, 11:43:02 AM
Current Avidemux uses TinyPy (.py) for scripting, which is a very limited subset of Python.
There is no complete updated documentation, but a number of example scripts are available.
The page you linked to is likely out of date.

A feature to generate a batch script from the current configuration would be useful for casual users and could be added (in c++) to the GUI in the project script submenu. Manually modifying an existing .py script isn't difficult but there is a bit of a learning curve.
Title: Re: How_To_Batch_File_Proccessing?
Post by: pulsarstar on April 19, 2021, 02:37:39 PM
Thanks for your thoughts Butterw.
Can you point me to useful links,
where I can find these existing scripts.py
that I can as you say modify ?
Cheers!
Title: Re: How_To_Batch_File_Proccessing?
Post by: butterw on April 19, 2021, 02:57:42 PM
Search for: Tinypy Avidemux
or Tinypy on this forum
The most up to date info is in the thread I already linked to: https://avidemux.org/smif/index.php/topic,19390.0.html 

there are a also number of scripts in the source code repo:
https://github.com/mean00/avidemux2/search?p=2&q=extension%3Apy

my own scripts are listed in this thread: https://avidemux.org/smif/index.php/topic,19404.0.html
Title: Re: How_To_Batch_File_Proccessing?
Post by: pulsarstar on April 19, 2021, 03:58:09 PM
Thanks You, butterw for the info:
I will take a look at your links tomorrow.
Title: Re: How_To_Batch_File_Proccessing?
Post by: eumagga0x2a on April 19, 2021, 07:40:44 PM
I'd like to add that internal Python-like scripting in Avidemux should not be mixed up with external batch / shell scripting. They serve different purposes (e.g. you cannot create directories or arbitrary files or call other executables when using the internal scripting while the external scripting won't give you detailed access to the configuration of Avidemux), but very often you would need (or want) to use both.
Title: Re: How_To_Batch_File_Proccessing?
Post by: pulsarstar on April 20, 2021, 12:02:52 PM
Thank you eumagga0x2a.
That info was helpful.
As this will be a regular program I shall use,
I see I have a learning curve in front of me. ;D
 
Title: Re: How_To_Batch_File_Proccessing?
Post by: butterw on April 20, 2021, 02:51:08 PM
When you load a new file (with default preference setting, "reset_encoder_on_video_load" : false):
- encoder and output container options are not reset.
- markers and filters are reset.

1) setup the output settings in the gui then save the .py project.
2) Modify the script to process all files in a folder:
- get a list of input filepaths.
for each filepath_in:
- adm.load(filepath_in)
- apply filters to the file
- adm.save(filepath_out) #overwrites existing files
Title: Re: How_To_Batch_File_Proccessing?
Post by: pulsarstar on April 21, 2021, 07:54:10 AM
Thank You, butterw for the advice.
Title: Re: How_To_Batch_File_Proccessing?
Post by: chucknolan on April 25, 2021, 08:19:40 PM
Quote from: eumagga0x2a on April 17, 2021, 01:11:59 PM
Quote from: pulsarstar on April 14, 2021, 03:24:13 PMI hope in future update versions of Avidemux the R & D Department include batch file processing in the GUI options.

You can queue tasks for later batch processing using Avidemux Jobs GUI, but the R & D Department doesn't think that inflating GUI is the way to go.

For your task, you could use the following untested script (copy and paste it into the Avidemux script console or save as a .py file and pass to the executable on the command line as the argument of the --run option:

#PY  <- Needed to identify #
#
ui = Gui()
adm = Avidemux()
ext = "mp4"
sep = "\\"
#
# Function to convert an individual video
#
def convert(filein,out):
    if not adm.loadVideo(filein):
        ui.displayError("oops","cannot load "+filein)
        return 0

    adm.videoCodec("Copy")
    if adm.audioTracksCount() > 0:
        adm.audioClearTracks()
        adm.audioAddTrack(0)
        adm.audioCodec(0, "FDK_AAC", "bitrate=192", "afterburner=True", "profile=2", "sbr=False")
        adm.audioSetDrc(0, 0)
        adm.audioSetShift(0, 0, 0)
        adm.audioSetNormalize2(0, 2, 120, -30)
    adm.setContainer("MKV", "forceAspectRatio=False", "displayWidth=1280", "displayAspectRatio=2", "addColourInfo=False", "colMatrixCoeff=2", "colRange=0", "colTransfer=2", "colPrimaries=2")

    filename = (splitext(filein))[0]
    filename += ".mkv"
    filename = basename(filename)
    return adm.save(out + sep + filename)
#
# Main
#
# -------- select extension --------
extensions = ["avi","m2ts","mkv","mov","mp4","mpg","ts","vob","webm","wmv"]
mx = len(extensions)

menuExt = DFMenu("Select extension:")
for entry in range(0, mx):
    menuExt.addItem(extensions[entry])
dia = DialogFactory("Filter directory content")
dia.addControl(menuExt)
if not dia.show():
    return

idx = menuExt.index

if idx < 0 or idx >= mx:
    ui.displayError("Oops", "Internal error: invalid menu index")
    return

ext = extensions[idx]

# -------- select input directory --------
inputFolder = ui.dirSelect("Select source folder")
if inputFolder is None:
    ui.displayError("Oops", "No source folder selected")
    return

# -------- read content --------
list = get_folder_content(inputFolder, ext)
if list is None:
    ui.displayError("Oops", "No " + ext + " files found in \"" + inputFolder + "\"")
    return

# -------- select output directory --------
outputFolder = ui.dirSelect("Select output folder")
if outputFolder is None:
    ui.displayError("Oops", "No output folder selected")
    return

if(inputFolder == outputFolder):
    ui.displayError("Error","Output folder cannot be the same as the input one")
    return

# -------- process --------
total = 0
counter = 0

for i in list:
    total += 1
    counter += convert(i, outputFolder)

if not counter:
    ui.displayInfo("Warning", "No files converted")
    return

if counter == 1:
    ui.displayInfo("Finished", "One file out of " + str(total) + " converted")
    return

ui.displayInfo("Finished", str(counter) + " files out of " + str(total) + " converted")

The script processes all files with given extension in a directory.

I will like to say that your python batch script is THE BEST THAT I HAVE EVER USED compared to the DasTactic method located on the avidemux website. Moreover, I have created some of my own python scripts using DasTactic as a template, but with yours, I managed to cut back A LOT of filler concerning the creation of multiple/individual batch scripts for various extension inputs such as a script for mkv to mp4, mkv to mkv, ts to mp4, etc.  However, with yours, in one SINGLE script file, I have the ability of choosing from multiple inputs (mkv, ts, mp4, avi, etc) to output (mkv).  Therefore, I wanted to ask you a question in regards to creating a script for me, if you don't mind?

I have no intensions of converting the video. Only audio conversion. Therefore, the video will be just "Copy."

On the same script, is it possible, just like you had with the script you wrote for pulsarstar, to have multiple INPUT extensions, and as well as multiple OUTPUT extension options?  For example, let's say that my file input choice from the list/menu is ".ts," and I wanted the output extension options to be available for "mkv," "mp4," "mov" with the "mkv" audio being 56 kbps FDK-AAC (HE-AAC); "mp4" audio 128 kbps FDK-AAC (LC-AAC); "mov" audio 192 kbps FDK-AAC (LC-AAC).

The script that I hope that you can create for me, assuming it's possible, is the ability of having the option to choose from a list/menu of INPUTS (mkv, mp4, ts, avi, etc) to a list/menu of OUTPUTS (mkv, mp4, mov), in which I am aware that each output extension has to have their own individual profiles.  Apologies, if my wording is confusing.
Title: Re: How_To_Batch_File_Proccessing?
Post by: eumagga0x2a on April 25, 2021, 11:55:33 PM
Quote from: chucknolan on April 25, 2021, 08:19:40 PMI wanted the output extension options to be available for "mkv," "mp4," "mov" with the "mkv" audio being 56 kbps FDK-AAC (HE-AAC); "mp4" audio 128 kbps FDK-AAC (LC-AAC); "mov" audio 192 kbps FDK-AAC (LC-AAC).

Assuming that you don't need to filter audio, the script below should do it:

#PY  <- Needed to identify #
#
ui = Gui()
adm = Avidemux()
ext = "mp4"
outputs = ["MKV, HE-AAC @ 56 kbps (FDK-AAC)","MP4, AAC LC @ 128 kbps (FDK-AAC)","MOV, AAC LC @ 192 kbps (FDK-AAC)"]
sep = "\\"
#
# Function to convert an individual video
#
def convert(filein,outdir,outidx):
    if not adm.loadVideo(filein):
        ui.displayError("oops","cannot load "+filein)
        return 0

    adm.videoCodec("Copy")
    if adm.audioTracksCount() > 0:
        adm.audioClearTracks()
        adm.audioAddTrack(0)
        if outidx == 0:
            adm.audioCodec(0, "FDK_AAC", "bitrate=56", "afterburner=True", "profile=5", "sbr=False")
        elif outidx == 1:
            adm.audioCodec(0, "FDK_AAC", "bitrate=128", "afterburner=True", "profile=2", "sbr=False")
        elif outidx == 2:
            adm.audioCodec(0, "FDK_AAC", "bitrate=192", "afterburner=True", "profile=2", "sbr=False")
        else:
            ui.displayError("Error", "Invalid output preset index \"" + str(outidx) + "\"")
            return 0
    filename = (splitext(filein))[0]
    if outidx == 0:
        adm.setContainer("MKV", "forceAspectRatio=False", "displayWidth=1280", "displayAspectRatio=2", "addColourInfo=False", "colMatrixCoeff=2", "colRange=0", "colTransfer=2", "colPrimaries=2")
        filename += ".mkv"
    elif outidx == 1:
        adm.setContainer("MP4", "muxerType=0", "optimize=1", "forceAspectRatio=False", "aspectRatio=1", "displayWidth=1280", "rotation=0", "clockfreq=0")
        filename += ".mp4"
    elif outidx == 2:
        adm.setContainer("MOV", "muxerType=0", "optimize=1", "forceAspectRatio=False", "aspectRatio=1", "displayWidth=1280", "rotation=0", "clockfreq=0")
        filename += ".mov"
    else:
        ui.displayError("Error", "Invalid output preset index \"" + str(outidx) + "\"")
        return 0
    filename = basename(filename)
    return adm.save(outdir + sep + filename)
#
# Main
#
# -------- select extension and output preset --------
extensions = ["avi","m2ts","mkv","mov","mp4","mpg","ts","vob","webm","wmv"]
mxExt = len(extensions)

menuExt = DFMenu("Select extension:")
for entry in range(0, mxExt):
    menuExt.addItem(extensions[entry])

mxOut = len(outputs)

menuOut = DFMenu("Select output preset:")
for entry in range(0, mxOut):
    menuOut.addItem(outputs[entry])

dia = DialogFactory("Configuration")
dia.addControl(menuExt)
dia.addControl(menuOut)
if not dia.show():
    return

idxExt = menuExt.index

if idxExt < 0 or idxExt >= mxExt:
    ui.displayError("Oops", "Internal error: invalid menu index")
    return

ext = extensions[idxExt]

idxOut = menuOut.index

if idxOut < 0 or idxOut >= mxOut:
    ui.displayError("Oops", "Internal error: invalid menu index")
    return

# -------- select input directory --------
inputFolder = ui.dirSelect("Select source folder")
if inputFolder is None:
    ui.displayError("Error", "No source folder selected")
    return

# -------- read content --------
list = get_folder_content(inputFolder, ext)
if list is None:
    ui.displayError("Oops", "No " + ext + " files found in \"" + inputFolder + "\"")
    return

# -------- select output directory --------
outputFolder = ui.dirSelect("Select output folder")
if outputFolder is None:
    ui.displayError("Error", "No output folder selected")
    return

if(inputFolder == outputFolder):
    ui.displayError("Error","Output folder cannot be the same as the input one")
    return

# -------- process --------
total = 0
counter = 0

for i in list:
    total += 1
    counter += convert(i, outputFolder, idxOut)

if not counter:
    ui.displayInfo("Warning", "No files converted")
    return

if counter == 1:
    ui.displayInfo("Finished", "One file out of " + str(total) + " converted")
    return

ui.displayInfo("Finished", str(counter) + " files out of " + str(total) + " converted")
Title: Re: How_To_Batch_File_Proccessing?
Post by: pulsarstar on April 26, 2021, 07:20:16 AM
Thanks for your input chucknolan.
I have saved your script to my script folder.
I found your question to eumagga0x2a a good read,
and also the script he gave you in response was very good.
I saved that for later use.
Thanks go to eumagga0x2a for the script!
Title: Re: How_To_Batch_File_Proccessing?
Post by: chucknolan on April 26, 2021, 08:46:13 PM
Quote from: eumagga0x2a on April 25, 2021, 11:55:33 PM
Quote from: chucknolan on April 25, 2021, 08:19:40 PMI wanted the output extension options to be available for "mkv," "mp4," "mov" with the "mkv" audio being 56 kbps FDK-AAC (HE-AAC); "mp4" audio 128 kbps FDK-AAC (LC-AAC); "mov" audio 192 kbps FDK-AAC (LC-AAC).

Assuming that you don't need to filter audio, the script below should do it:

#PY  <- Needed to identify #
#
ui = Gui()
adm = Avidemux()
ext = "mp4"
outputs = ["MKV, HE-AAC @ 56 kbps (FDK-AAC)","MP4, AAC LC @ 128 kbps (FDK-AAC)","MOV, AAC LC @ 192 kbps (FDK-AAC)"]
sep = "\\"
#
# Function to convert an individual video
#
def convert(filein,outdir,outidx):
    if not adm.loadVideo(filein):
        ui.displayError("oops","cannot load "+filein)
        return 0

    adm.videoCodec("Copy")
    if adm.audioTracksCount() > 0:
        adm.audioClearTracks()
        adm.audioAddTrack(0)
        if outidx == 0:
            adm.audioCodec(0, "FDK_AAC", "bitrate=56", "afterburner=True", "profile=5", "sbr=False")
        elif outidx == 1:
            adm.audioCodec(0, "FDK_AAC", "bitrate=128", "afterburner=True", "profile=2", "sbr=False")
        elif outidx == 2:
            adm.audioCodec(0, "FDK_AAC", "bitrate=192", "afterburner=True", "profile=2", "sbr=False")
        else:
            ui.displayError("Error", "Invalid output preset index \"" + str(outidx) + "\"")
            return 0
    filename = (splitext(filein))[0]
    if outidx == 0:
        adm.setContainer("MKV", "forceAspectRatio=False", "displayWidth=1280", "displayAspectRatio=2", "addColourInfo=False", "colMatrixCoeff=2", "colRange=0", "colTransfer=2", "colPrimaries=2")
        filename += ".mkv"
    elif outidx == 1:
        adm.setContainer("MP4", "muxerType=0", "optimize=1", "forceAspectRatio=False", "aspectRatio=1", "displayWidth=1280", "rotation=0", "clockfreq=0")
        filename += ".mp4"
    elif outidx == 2:
        adm.setContainer("MOV", "muxerType=0", "optimize=1", "forceAspectRatio=False", "aspectRatio=1", "displayWidth=1280", "rotation=0", "clockfreq=0")
        filename += ".mov"
    else:
        ui.displayError("Error", "Invalid output preset index \"" + str(outidx) + "\"")
        return 0
    filename = basename(filename)
    return adm.save(outdir + sep + filename)
#
# Main
#
# -------- select extension and output preset --------
extensions = ["avi","m2ts","mkv","mov","mp4","mpg","ts","vob","webm","wmv"]
mxExt = len(extensions)

menuExt = DFMenu("Select extension:")
for entry in range(0, mxExt):
    menuExt.addItem(extensions[entry])

mxOut = len(outputs)

menuOut = DFMenu("Select output preset:")
for entry in range(0, mxOut):
    menuOut.addItem(outputs[entry])

dia = DialogFactory("Configuration")
dia.addControl(menuExt)
dia.addControl(menuOut)
if not dia.show():
    return

idxExt = menuExt.index

if idxExt < 0 or idxExt >= mxExt:
    ui.displayError("Oops", "Internal error: invalid menu index")
    return

ext = extensions[idxExt]

idxOut = menuOut.index

if idxOut < 0 or idxOut >= mxOut:
    ui.displayError("Oops", "Internal error: invalid menu index")
    return

# -------- select input directory --------
inputFolder = ui.dirSelect("Select source folder")
if inputFolder is None:
    ui.displayError("Error", "No source folder selected")
    return

# -------- read content --------
list = get_folder_content(inputFolder, ext)
if list is None:
    ui.displayError("Oops", "No " + ext + " files found in \"" + inputFolder + "\"")
    return

# -------- select output directory --------
outputFolder = ui.dirSelect("Select output folder")
if outputFolder is None:
    ui.displayError("Error", "No output folder selected")
    return

if(inputFolder == outputFolder):
    ui.displayError("Error","Output folder cannot be the same as the input one")
    return

# -------- process --------
total = 0
counter = 0

for i in list:
    total += 1
    counter += convert(i, outputFolder, idxOut)

if not counter:
    ui.displayInfo("Warning", "No files converted")
    return

if counter == 1:
    ui.displayInfo("Finished", "One file out of " + str(total) + " converted")
    return

ui.displayInfo("Finished", str(counter) + " files out of " + str(total) + " converted")

First off, sir, you're amazing.  THANK YOU.  Unfortunately, the mkv output preset didn't work, but I addressed it by removing the option for the output folder.  Nonetheless, what tutorial or manual did you use to write these scripts because they are incredible, and, by using your template as a backbone, I set the audio filters to my liking and altered the renaming output files according to output preset?

I do, however, have 2 more questions, if you don't mind:

1) For COPY of audio and video, how may I create a python script that will accommodate files with multiple audio tracks because I have to keep creating different profiles for 1 track, 2 tracks, 3 tracks, & 4 tracks for my DBZ anime collection?  I mean is there a variable that I can utilize to do so. Example below:

    adm.videoCodec("Copy")
    if adm.audioTracksCount() > 0:
        adm.audioClearTracks()
        if outidx == 0:
            adm.setSourceTrackLanguage(0,"eng")
            adm.audioAddTrack(0)
            adm.audioCodec(0, "copy")
        elif outidx == 1:
            adm.setSourceTrackLanguage(0,"eng")
            adm.setSourceTrackLanguage(1,"jpn")
            adm.audioAddTrack(0)
            adm.audioAddTrack(1)
            adm.audioCodec(0, "copy")
            adm.audioCodec(1, "copy")
        elif outidx == 2:
            adm.setSourceTrackLanguage(0,"eng")
            adm.setSourceTrackLanguage(1,"jpn")
            adm.setSourceTrackLanguage(2,"spa")
            adm.audioAddTrack(0)
            adm.audioAddTrack(1)
            adm.audioAddTrack(2)
            adm.audioCodec(0, "copy")
            adm.audioCodec(1, "copy")
            adm.audioCodec(2, "copy")


2) Not sure if it's possible, but is there a way for me to choose a specific file apply an "output preset?" Not sure if I'm framing the question correctly.  Therefore, I will try a scenario approach.  For example, if I was batching 8 mkv files to output mkv, but forgot one file, how can I select that SPECIFIC file and apply the preset without having to create a random folder, place that one file, and apply the python script?  Is there something that I have to do BELOW that will allow access to view BOTH FILES and FOLDERS, instead of just the folders?

# -------- select input directory --------
inputFolder = ui.dirSelect("Select source folder")
if inputFolder is None:
    ui.displayError("Error", "No source folder selected")
    return

# -------- read content --------
list = get_folder_content(inputFolder, ext)
if list is None:
    ui.displayError("Oops", "No " + ext + " files found in \"" + inputFolder + "\"")
    return

NONETHELESS, THANK YOU AGAIN. YOU ARE TRULY A Lifesaver
 
Title: Re: How_To_Batch_File_Proccessing?
Post by: chucknolan on April 26, 2021, 08:49:14 PM
Quote from: pulsarstar on April 26, 2021, 07:20:16 AMThanks for your input chucknolan.
I have saved your script to my script folder.
I found your question to eumagga0x2a a good read,
and also the script he gave you in response was very good.
I saved that for later use.
Thanks go to eumagga0x2a for the script!

No, I should be thanking you because I wasn't aware that this forum would be this helpful.  I performed the batching from DasTactic youtube video, but it pales in comparison to eumagga0x2a's.  Therefore, thank you for posing the question. Whomever eumagga0x2a is, thank you.
Title: Re: How_To_Batch_File_Proccessing?
Post by: eumagga0x2a on April 26, 2021, 09:33:50 PM
Quote from: chucknolan on April 26, 2021, 08:46:13 PMUnfortunately, the mkv output preset didn't work

Could you please elaborate? It worked for me after I recompiled Avidemux against the proper fdk-aac library (should not be a concern on platforms other than Linux). Regarding MKV muxer configuration, everything I suggest is based on the latest git master, please make sure you use the latest nightly available.

I'll try to address other questions tomorrow.
Title: Re: How_To_Batch_File_Proccessing?
Post by: chucknolan on April 26, 2021, 10:23:15 PM
Quote from: eumagga0x2a on April 26, 2021, 09:33:50 PM
Quote from: chucknolan on April 26, 2021, 08:46:13 PMUnfortunately, the mkv output preset didn't work

Could you please elaborate? It worked for me after I recompiled Avidemux against the proper fdk-aac library (should not be a concern on platforms other than Linux). Regarding MKV muxer configuration, everything I suggest is based on the latest git master, please make sure you use the latest nightly available.

I'll try to address other questions tomorrow.

My apologies.  I just tried it again, and it works. I received an error yesterday for some reason.  Moreover, thank you for taking the time to address my other questions.
Title: Re: How_To_Batch_File_Proccessing?
Post by: eumagga0x2a on April 27, 2021, 10:56:02 PM
I'm sorry, everything slips by a day or two.

It turned out to be that Avidemux...

a) doesn't evaluate language metadata in MP4 files at all and...

b) fails to set language metadata in MOV files for many languages (more precisely for all languages with ISO-639-2/B codes different from their ISO-639-2 codes like "ger" vs "deu" for German).

I've fixed (well, copypasted the code from libavcodec) the first issue in my local code, not yet committed. Will try to fix the second one tomorrow.
Title: Re: How_To_Batch_File_Proccessing?
Post by: eumagga0x2a on April 28, 2021, 08:54:41 PM
The bugs in MP4 demuxer and MOV muxer affecting language metadata are fixed now, the fixes will be in the next round of official nightly builds unless you build Avidemux from source yourself to get them instantly.

Regarding source files with multiple audio tracks, you can use

#PY  <- Needed to identify #
#
ui = Gui()
adm = Avidemux()
ext = "mp4"
outputs = ["MKV, HE-AAC @ 56 kbps (FDK-AAC)","MP4, AAC LC @ 128 kbps (FDK-AAC)","MOV, AAC LC @ 192 kbps (FDK-AAC)"]
sep = "\\"
#
# Function to convert an individual video
#
def convert(filein,outdir,outidx):
    if not adm.loadVideo(filein):
        ui.displayError("oops","cannot load "+filein)
        return 0

    adm.videoCodec("Copy")
    nbTracks = adm.audioTracksCount()
    if nbTracks > 0:
        adm.audioClearTracks()
        for track in range(nbTracks):
            adm.audioAddTrack(track)
            if outidx == 0:
                adm.audioCodec(track, "FDK_AAC", "bitrate=56", "afterburner=True", "profile=5", "sbr=False")
            elif outidx == 1:
                adm.audioCodec(track, "FDK_AAC", "bitrate=128", "afterburner=True", "profile=2", "sbr=False")
            elif outidx == 2:
                adm.audioCodec(track, "FDK_AAC", "bitrate=192", "afterburner=True", "profile=2", "sbr=False")
            else:
                ui.displayError("Error", "Invalid output preset index \"" + str(outidx) + "\"")
                return 0
    filename = (splitext(filein))[0]
    if outidx == 0:
        adm.setContainer("MKV", "forceAspectRatio=False", "displayWidth=1280", "displayAspectRatio=2", "addColourInfo=False", "colMatrixCoeff=2", "colRange=0", "colTransfer=2", "colPrimaries=2")
        filename += ".mkv"
    elif outidx == 1:
        adm.setContainer("MP4", "muxerType=0", "optimize=1", "forceAspectRatio=False", "aspectRatio=1", "displayWidth=1280", "rotation=0", "clockfreq=0")
        filename += ".mp4"
    elif outidx == 2:
        adm.setContainer("MOV", "muxerType=0", "optimize=1", "forceAspectRatio=False", "aspectRatio=1", "displayWidth=1280", "rotation=0", "clockfreq=0")
        filename += ".mov"
    else:
        ui.displayError("Error", "Invalid output preset index \"" + str(outidx) + "\"")
        return 0
    filename = basename(filename)
    return adm.save(outdir + sep + filename)
#
# Main
#
# -------- select extension and output preset --------
extensions = ["avi","m2ts","mkv","mov","mp4","mpg","ts","vob","webm","wmv"]
mxExt = len(extensions)

menuExt = DFMenu("Select extension:")
for entry in range(0, mxExt):
    menuExt.addItem(extensions[entry])

mxOut = len(outputs)

menuOut = DFMenu("Select output preset:")
for entry in range(0, mxOut):
    menuOut.addItem(outputs[entry])

dia = DialogFactory("Configuration")
dia.addControl(menuExt)
dia.addControl(menuOut)
if not dia.show():
    return

idxExt = menuExt.index

if idxExt < 0 or idxExt >= mxExt:
    ui.displayError("Oops", "Internal error: invalid menu index")
    return

ext = extensions[idxExt]

idxOut = menuOut.index

if idxOut < 0 or idxOut >= mxOut:
    ui.displayError("Oops", "Internal error: invalid menu index")
    return

# -------- select input directory --------
inputFolder = ui.dirSelect("Select source folder")
if inputFolder is None:
    ui.displayError("Error", "No source folder selected")
    return

# -------- read content --------
list = get_folder_content(inputFolder, ext)
if list is None:
    ui.displayError("Oops", "No " + ext + " files found in \"" + inputFolder + "\"")
    return

# -------- select output directory --------
outputFolder = ui.dirSelect("Select output folder")
if outputFolder is None:
    ui.displayError("Error", "No output folder selected")
    return

if(inputFolder == outputFolder):
    ui.displayError("Error","Output folder cannot be the same as the input one")
    return

# -------- process --------
total = 0
counter = 0

for i in list:
    total += 1
    counter += convert(i, outputFolder, idxOut)

if not counter:
    ui.displayInfo("Warning", "No files converted")
    return

if counter == 1:
    ui.displayInfo("Finished", "One file out of " + str(total) + " converted")
    return

ui.displayInfo("Finished", str(counter) + " files out of " + str(total) + " converted")

to loop over the available audio tracks.
Title: Re: How_To_Batch_File_Proccessing?
Post by: chucknolan on April 29, 2021, 06:53:09 PM
Quote from: eumagga0x2a on April 28, 2021, 08:54:41 PMThe bugs in MP4 demuxer and MOV muxer affecting language metadata are fixed now, the fixes will be in the next round of official nightly builds unless you build Avidemux from source yourself to get them instantly.

Regarding source files with multiple audio tracks, you can use

#PY  <- Needed to identify #
#
ui = Gui()
adm = Avidemux()
ext = "mp4"
outputs = ["MKV, HE-AAC @ 56 kbps (FDK-AAC)","MP4, AAC LC @ 128 kbps (FDK-AAC)","MOV, AAC LC @ 192 kbps (FDK-AAC)"]
sep = "\\"
#
# Function to convert an individual video
#
def convert(filein,outdir,outidx):
    if not adm.loadVideo(filein):
        ui.displayError("oops","cannot load "+filein)
        return 0

    adm.videoCodec("Copy")
    nbTracks = adm.audioTracksCount()
    if nbTracks > 0:
        adm.audioClearTracks()
        for track in range(nbTracks):
            adm.audioAddTrack(track)
            if outidx == 0:
                adm.audioCodec(track, "FDK_AAC", "bitrate=56", "afterburner=True", "profile=5", "sbr=False")
            elif outidx == 1:
                adm.audioCodec(track, "FDK_AAC", "bitrate=128", "afterburner=True", "profile=2", "sbr=False")
            elif outidx == 2:
                adm.audioCodec(track, "FDK_AAC", "bitrate=192", "afterburner=True", "profile=2", "sbr=False")
            else:
                ui.displayError("Error", "Invalid output preset index \"" + str(outidx) + "\"")
                return 0
    filename = (splitext(filein))[0]
    if outidx == 0:
        adm.setContainer("MKV", "forceAspectRatio=False", "displayWidth=1280", "displayAspectRatio=2", "addColourInfo=False", "colMatrixCoeff=2", "colRange=0", "colTransfer=2", "colPrimaries=2")
        filename += ".mkv"
    elif outidx == 1:
        adm.setContainer("MP4", "muxerType=0", "optimize=1", "forceAspectRatio=False", "aspectRatio=1", "displayWidth=1280", "rotation=0", "clockfreq=0")
        filename += ".mp4"
    elif outidx == 2:
        adm.setContainer("MOV", "muxerType=0", "optimize=1", "forceAspectRatio=False", "aspectRatio=1", "displayWidth=1280", "rotation=0", "clockfreq=0")
        filename += ".mov"
    else:
        ui.displayError("Error", "Invalid output preset index \"" + str(outidx) + "\"")
        return 0
    filename = basename(filename)
    return adm.save(outdir + sep + filename)
#
# Main
#
# -------- select extension and output preset --------
extensions = ["avi","m2ts","mkv","mov","mp4","mpg","ts","vob","webm","wmv"]
mxExt = len(extensions)

menuExt = DFMenu("Select extension:")
for entry in range(0, mxExt):
    menuExt.addItem(extensions[entry])

mxOut = len(outputs)

menuOut = DFMenu("Select output preset:")
for entry in range(0, mxOut):
    menuOut.addItem(outputs[entry])

dia = DialogFactory("Configuration")
dia.addControl(menuExt)
dia.addControl(menuOut)
if not dia.show():
    return

idxExt = menuExt.index

if idxExt < 0 or idxExt >= mxExt:
    ui.displayError("Oops", "Internal error: invalid menu index")
    return

ext = extensions[idxExt]

idxOut = menuOut.index

if idxOut < 0 or idxOut >= mxOut:
    ui.displayError("Oops", "Internal error: invalid menu index")
    return

# -------- select input directory --------
inputFolder = ui.dirSelect("Select source folder")
if inputFolder is None:
    ui.displayError("Error", "No source folder selected")
    return

# -------- read content --------
list = get_folder_content(inputFolder, ext)
if list is None:
    ui.displayError("Oops", "No " + ext + " files found in \"" + inputFolder + "\"")
    return

# -------- select output directory --------
outputFolder = ui.dirSelect("Select output folder")
if outputFolder is None:
    ui.displayError("Error", "No output folder selected")
    return

if(inputFolder == outputFolder):
    ui.displayError("Error","Output folder cannot be the same as the input one")
    return

# -------- process --------
total = 0
counter = 0

for i in list:
    total += 1
    counter += convert(i, outputFolder, idxOut)

if not counter:
    ui.displayInfo("Warning", "No files converted")
    return

if counter == 1:
    ui.displayInfo("Finished", "One file out of " + str(total) + " converted")
    return

ui.displayInfo("Finished", str(counter) + " files out of " + str(total) + " converted")

to loop over the available audio tracks.

THANK YOU. I actually figured out the audio loop by playing around with the previous template when I changed "if adm.audioTracksCount() > 0" to "if adm.audioTracksCount() < 0".  However, the downside of doing so prevented the ability to assign language sets.  This latest one is amazing.

Can you create one more for me to complete my set of AviDemux conversions presets? I was wondering if you can use the previous template or the current template that you just uploaded yesterday and assign video conversions on them.  I just need 2 to 3 presets, and then I can work from there as I did for your past templates. Please see example below:

Video & Audio Preset/Profile #1:

adm.videoCodec("xvid4", "params=CQ=2", "profile=244", "rdMode=3", "motionEstimation=3", "cqmMode=0", "arMode=1", "maxBFrame=2", "maxKeyFrameInterval=200", "nbThreads=99", "qMin=2", "qMax=25", "rdOnBFrame=True", "hqAcPred=True"
, "optimizeChrome=True", "trellis=True", "useXvidFCC=True", "enableFrameDrop=False", "frameDropRatio=50")
adm.audioClearTracks()
adm.setSourceTrackLanguage(0,"und")
if adm.audioTotalTracksCount() <= 0:
    raise("Cannot add audio track 0, total tracks: " + str(adm.audioTotalTracksCount()))
adm.audioAddTrack(0)
adm.audioCodec(0, "FDK_AAC", "bitrate=160", "afterburner=False", "profile=2", "sbr=False")
adm.audioSetDrc(0, 0)
adm.audioSetShift(0, 0, 0)
adm.setContainer("MKV", "forceAspectRatio=False", "displayWidth=1280", "displayAspectRatio=2", "addColourInfo=False", "colMatrixCoeff=2", "colRange=0", "colTransfer=2", "colPrimaries=2")


Video & Audio Preset/Profile #2:
adm.videoCodec("x265", "useAdvancedConfiguration=True", "general.params=AQ=20", "general.poolThreads=99", "general.frameThreads=99", "general.output_bit_depth=0", "general.preset=", "general.tuning=", "general.profile=", "level=-1"
, "vui.sar_idc=0", "vui.sar_height=1", "vui.sar_width=1", "vui.color_primaries=2", "vui.transfer_characteristics=2", "vui.matrix_coeffs=2", "MaxRefFrames=3", "MinIdr=25", "MaxIdr=250", "i_scenecut_threshold=40"
, "MaxBFrame=3", "i_bframe_adaptive=2", "i_bframe_bias=0", "i_bframe_pyramid=1", "b_deblocking_filter=True", "b_open_gop=False", "interlaced_mode=0", "constrained_intra=False", "b_intra=True", "lookahead=40"
, "weighted_pred=2", "weighted_bipred=True", "rect_inter=False", "amp_inter=False", "limit_modes=False", "cb_chroma_offset=0", "cr_chroma_offset=0", "me_method=3", "me_range=16", "subpel_refine=5", "limit_refs=3"
, "rd_level=3", "psy_rd=1.000000", "rdoq_level=0", "psy_rdoq=0.000000", "fast_pskip=True", "dct_decimate=True", "noise_reduction_intra=0", "noise_reduction_inter=0", "strong_intra_smoothing=True", "ratecontrol.rc_method=0"
, "ratecontrol.qp_constant=0", "ratecontrol.qp_step=4", "ratecontrol.bitrate=0", "ratecontrol.vbv_max_bitrate=0", "ratecontrol.vbv_buffer_size=0", "ratecontrol.vbv_buffer_init=1", "ratecontrol.ip_factor=1.400000"
, "ratecontrol.pb_factor=1.300000", "ratecontrol.aq_mode=2", "ratecontrol.aq_strength=1.000000", "ratecontrol.cu_tree=True", "ratecontrol.strict_cbr=False")
adm.audioClearTracks()
adm.setSourceTrackLanguage(0,"und")
if adm.audioTotalTracksCount() <= 0:
    raise("Cannot add audio track 0, total tracks: " + str(adm.audioTotalTracksCount()))
adm.audioAddTrack(0)
adm.audioCodec(0, "FDK_AAC", "bitrate=56", "afterburner=False", "profile=5", "sbr=False")
adm.audioSetDrc(0, 0)
adm.audioSetShift(0, 0, 0)
adm.setContainer("MP4", "muxerType=0", "optimize=1", "forceAspectRatio=False", "aspectRatio=1", "displayWidth=1280", "rotation=0", "clockfreq=0")


Thank you!
Title: Re: How_To_Batch_File_Proccessing?
Post by: eumagga0x2a on April 29, 2021, 08:46:07 PM
Quote from: chucknolan on April 29, 2021, 06:53:09 PMI actually figured out the audio loop by playing around with the previous template when I changed "if adm.audioTracksCount() > 0" to "if adm.audioTracksCount() < 0".

This makes the test to always evaluate to false, so the whole block configuring audio encoders gets simply skipped.

Quote from: chucknolan on April 29, 2021, 06:53:09 PMCan you create one more for me to complete my set of AviDemux conversions presets? I was wondering if you can use the previous template or the current template that you just uploaded yesterday and assign video conversions on them.

I don't get, do you want the choice of video encoder to be independent or linked to specific audio encoder and muxer configurations?
Title: Re: How_To_Batch_File_Proccessing?
Post by: chucknolan on April 29, 2021, 09:15:04 PM
Quote from: eumagga0x2a on April 29, 2021, 08:46:07 PM
Quote from: chucknolan on April 29, 2021, 06:53:09 PMI actually figured out the audio loop by playing around with the previous template when I changed "if adm.audioTracksCount() > 0" to "if adm.audioTracksCount() < 0".

This makes the test to always evaluate to false, so the whole block configuring audio encoders gets simply skipped.

Quote from: chucknolan on April 29, 2021, 06:53:09 PMCan you create one more for me to complete my set of AviDemux conversions presets? I was wondering if you can use the previous template or the current template that you just uploaded yesterday and assign video conversions on them.

I don't get, do you want the choice of video encoder to be independent or linked to specific audio encoder and muxer configurations?

I want the video encoder to be independent and linked to a specific audio encoder and muxer configuration for each output preset.  This way, I can add more presets in the future.  Example below using the output preset from your template

outputs = ["x265 (MKV) High@4.1, 1080p, HE-AAC @ 56 kbps (FDK-AAC)","x264 (MP4) High@3.1, 720p, AAC LC @ 128 kbps (FDK-AAC)","x264 (MKV) High@5.1, 720p, AAC LC @ 192 kbps (FDK-AAC)"]

3 individual video with audio conversions profiles linked into the output preset menu.  If it's possible to do so, I will really appreciate it.  If not, thank you for everything because you saved me a ton of time and organizing.

Title: Re: How_To_Batch_File_Proccessing?
Post by: eumagga0x2a on April 29, 2021, 09:31:18 PM
Quote from: chucknolan on April 29, 2021, 09:15:04 PMI want the video encoder to be independent and linked to a specific audio encoder and muxer configuration for each output preset.

They can be either independent or linked. Not both at the same time.
Title: Re: How_To_Batch_File_Proccessing?
Post by: eumagga0x2a on April 29, 2021, 09:38:06 PM
Just to be clear: in your example they are linked.
Title: Re: How_To_Batch_File_Proccessing?
Post by: chucknolan on April 29, 2021, 09:46:44 PM
Quote from: eumagga0x2a on April 29, 2021, 09:38:06 PMJust to be clear: in your example they are linked.

Yes sir. I guess that I want them linked, according to my example.  Thank you.  Now you have me curious on what an independent video encoder will look like.  I guess I will investigate that on my own. Thanks, again.
Title: Re: How_To_Batch_File_Proccessing?
Post by: eumagga0x2a on April 29, 2021, 09:52:36 PM
Quote from: chucknolan on April 29, 2021, 09:46:44 PMNow you have me curious on what an independent video encoder will look like.

You would add one more array (e.g. "videncs") as well as a menu similar to what I did with outputs. However, I don't think this is much more comfortable than just setting up the encoder in the main window.

As there is no "High" profile for HEVC, I would really prefer to let you figure out which configuration you actually want.
Title: Re: How_To_Batch_File_Proccessing?
Post by: chucknolan on April 29, 2021, 10:07:55 PM
Quote from: eumagga0x2a on April 29, 2021, 09:52:36 PM
Quote from: chucknolan on April 29, 2021, 09:46:44 PMNow you have me curious on what an independent video encoder will look like.

You would add one more array (e.g. "videncs") as well as a menu similar to what I did with outputs. However, I don't think this is much more comfortable than just setting up the encoder in the main window.

As there is no "High" profile for HEVC, I would really prefer to let you figure out which configuration you actually want.

Oh ok. Yeah the independent method seems far more complex.  The linked method would be my preference, and no worries regarding the HEVC because I just added various video codecs as a placeholder to present the individuality of what I was hoping you could code for me.  I tried to place as much detail as possible on the request.  Thanks again.
Title: Re: How_To_Batch_File_Proccessing?
Post by: eumagga0x2a on April 30, 2021, 11:54:56 AM
Using your examples, I can suggest the following example script:

#PY  <- Needed to identify #
#
ui = Gui()
adm = Avidemux()
ext = "mp4"
outputs = ["MKV, xvid4, HE-AAC @ 56 kbps (FDK-AAC)","MP4, x265, AAC LC @ 128 kbps (FDK-AAC)","MOV, x264, AAC LC @ 192 kbps (FDK-AAC)"]
sep = "\\"
#
# Function to convert an individual video
#
def convert(filein,outdir,outidx):
    if not adm.loadVideo(filein):
        ui.displayError("oops","cannot load "+filein)
        return 0

    if outidx == 0:
        adm.videoCodec("xvid4", "params=CQ=2", "profile=244", "rdMode=3", "motionEstimation=3", "cqmMode=0", "arMode=1", "maxBFrame=2", "maxKeyFrameInterval=200", "nbThreads=99", "qMin=2", "qMax=25", "rdOnBFrame=True", "hqAcPred=True"
, "optimizeChrome=True", "trellis=True", "useXvidFCC=True", "enableFrameDrop=False", "frameDropRatio=50")
    elif outidx == 1:
        adm.videoCodec("x265", "useAdvancedConfiguration=True", "general.params=AQ=20", "general.poolThreads=99", "general.frameThreads=99", "general.output_bit_depth=0", "general.preset=", "general.tuning=", "general.profile=", "level=-1"
, "vui.sar_idc=0", "vui.sar_height=1", "vui.sar_width=1", "vui.color_primaries=2", "vui.transfer_characteristics=2", "vui.matrix_coeffs=2", "MaxRefFrames=3", "MinIdr=25", "MaxIdr=250", "i_scenecut_threshold=40"
, "MaxBFrame=3", "i_bframe_adaptive=2", "i_bframe_bias=0", "i_bframe_pyramid=1", "b_deblocking_filter=True", "b_open_gop=False", "interlaced_mode=0", "constrained_intra=False", "b_intra=True", "lookahead=40"
, "weighted_pred=2", "weighted_bipred=True", "rect_inter=False", "amp_inter=False", "limit_modes=False", "cb_chroma_offset=0", "cr_chroma_offset=0", "me_method=3", "me_range=16", "subpel_refine=5", "limit_refs=3"
, "rd_level=3", "psy_rd=1.000000", "rdoq_level=0", "psy_rdoq=0.000000", "fast_pskip=True", "dct_decimate=True", "noise_reduction_intra=0", "noise_reduction_inter=0", "strong_intra_smoothing=True", "ratecontrol.rc_method=0"
, "ratecontrol.qp_constant=0", "ratecontrol.qp_step=4", "ratecontrol.bitrate=0", "ratecontrol.vbv_max_bitrate=0", "ratecontrol.vbv_buffer_size=0", "ratecontrol.vbv_buffer_init=1", "ratecontrol.ip_factor=1.400000"
, "ratecontrol.pb_factor=1.300000", "ratecontrol.aq_mode=2", "ratecontrol.aq_strength=1.000000", "ratecontrol.cu_tree=True", "ratecontrol.strict_cbr=False")
    elif outidx == 2:
        adm.videoCodec("x264", "useAdvancedConfiguration=False", "general.params=AQ=20", "general.threads=0", "general.preset=veryfast", "general.tuning=none", "general.profile=high", "general.fast_decode=False", "general.zero_latency=False"
, "general.fast_first_pass=True", "general.blueray_compatibility=False", "general.fake_interlaced=False", "level=-1", "vui.sar_height=1", "vui.sar_width=1", "MaxRefFrames=3", "MinIdr=25", "MaxIdr=250"
, "i_scenecut_threshold=40", "intra_refresh=False", "MaxBFrame=3", "i_bframe_adaptive=1", "i_bframe_bias=0", "i_bframe_pyramid=1", "b_deblocking_filter=True", "i_deblocking_filter_alphac0=0", "i_deblocking_filter_beta=0"
, "cabac=True", "interlaced=False", "constrained_intra=False", "tff=True", "fake_interlaced=False", "analyze.b_8x8=True", "analyze.b_i4x4=True", "analyze.b_i8x8=True", "analyze.b_p8x8=True", "analyze.b_p16x16=False"
, "analyze.b_b16x16=False", "analyze.weighted_pred=2", "analyze.weighted_bipred=True", "analyze.direct_mv_pred=1", "analyze.chroma_offset=0", "analyze.me_method=1", "analyze.me_range=16", "analyze.mv_range=-1"
, "analyze.mv_range_thread=-1", "analyze.subpel_refine=7", "analyze.chroma_me=True", "analyze.mixed_references=True", "analyze.trellis=1", "analyze.psy_rd=1.000000", "analyze.psy_trellis=0.000000", "analyze.fast_pskip=True"
, "analyze.dct_decimate=True", "analyze.noise_reduction=0", "analyze.psy=True", "analyze.intra_luma=11", "analyze.inter_luma=21", "ratecontrol.rc_method=0", "ratecontrol.qp_constant=0", "ratecontrol.qp_min=10"
, "ratecontrol.qp_max=51", "ratecontrol.qp_step=4", "ratecontrol.bitrate=0", "ratecontrol.rate_tolerance=1.000000", "ratecontrol.vbv_max_bitrate=0", "ratecontrol.vbv_buffer_size=0", "ratecontrol.vbv_buffer_init=1"
, "ratecontrol.ip_factor=1.400000", "ratecontrol.pb_factor=1.300000", "ratecontrol.aq_mode=1", "ratecontrol.aq_strength=1.000000", "ratecontrol.mb_tree=True", "ratecontrol.lookahead=40")
    else:
        ui.displayError("Error", "Invalid output preset index \"" + str(outidx) + "\"")
        return 0
    nbTracks = adm.audioTracksCount()
    if nbTracks > 0:
        adm.audioClearTracks()
        for track in range(nbTracks):
            adm.audioAddTrack(track)
            if outidx == 0:
                adm.audioCodec(track, "FDK_AAC", "bitrate=56", "afterburner=True", "profile=5", "sbr=False")
            elif outidx == 1:
                adm.audioCodec(track, "FDK_AAC", "bitrate=128", "afterburner=True", "profile=2", "sbr=False")
            elif outidx == 2:
                adm.audioCodec(track, "FDK_AAC", "bitrate=192", "afterburner=True", "profile=2", "sbr=False")
            else:
                ui.displayError("Error", "Invalid output preset index \"" + str(outidx) + "\"")
                return 0
    filename = (splitext(filein))[0]
    if outidx == 0:
        adm.setContainer("MKV", "forceAspectRatio=False", "displayWidth=1280", "displayAspectRatio=2", "addColourInfo=False", "colMatrixCoeff=2", "colRange=0", "colTransfer=2", "colPrimaries=2")
        filename += ".mkv"
    elif outidx == 1:
        adm.setContainer("MP4", "muxerType=0", "optimize=1", "forceAspectRatio=False", "aspectRatio=1", "displayWidth=1280", "rotation=0", "clockfreq=0")
        filename += ".mp4"
    elif outidx == 2:
        adm.setContainer("MOV", "muxerType=0", "optimize=1", "forceAspectRatio=False", "aspectRatio=1", "displayWidth=1280", "rotation=0", "clockfreq=0")
        filename += ".mov"
    else:
        ui.displayError("Error", "Invalid output preset index \"" + str(outidx) + "\"")
        return 0
    filename = basename(filename)
    return adm.save(outdir + sep + filename)
#
# Main
#
# -------- select extension and output preset --------
extensions = ["avi","m2ts","mkv","mov","mp4","mpg","ts","vob","webm","wmv"]
mxExt = len(extensions)

menuExt = DFMenu("Select extension:")
for entry in range(0, mxExt):
    menuExt.addItem(extensions[entry])

mxOut = len(outputs)

menuOut = DFMenu("Select output preset:")
for entry in range(0, mxOut):
    menuOut.addItem(outputs[entry])

dia = DialogFactory("Configuration")
dia.addControl(menuExt)
dia.addControl(menuOut)
if not dia.show():
    return

idxExt = menuExt.index

if idxExt < 0 or idxExt >= mxExt:
    ui.displayError("Oops", "Internal error: invalid menu index")
    return

ext = extensions[idxExt]

idxOut = menuOut.index

if idxOut < 0 or idxOut >= mxOut:
    ui.displayError("Oops", "Internal error: invalid menu index")
    return

# -------- select input directory --------
inputFolder = ui.dirSelect("Select source folder")
if inputFolder is None:
    ui.displayError("Error", "No source folder selected")
    return

# -------- read content --------
list = get_folder_content(inputFolder, ext)
if list is None:
    ui.displayError("Oops", "No " + ext + " files found in \"" + inputFolder + "\"")
    return

# -------- select output directory --------
outputFolder = ui.dirSelect("Select output folder")
if outputFolder is None:
    ui.displayError("Error", "No output folder selected")
    return

if(inputFolder == outputFolder):
    ui.displayError("Error","Output folder cannot be the same as the input one")
    return

# -------- process --------
total = 0
counter = 0

for i in list:
    total += 1
    counter += convert(i, outputFolder, idxOut)

if not counter:
    ui.displayInfo("Warning", "No files converted")
    return

if counter == 1:
    ui.displayInfo("Finished", "One file out of " + str(total) + " converted")
    return

ui.displayInfo("Finished", str(counter) + " files out of " + str(total) + " converted")

I didn't verify that video encoder configuration makes sense, please replace it with whatever suits your needs. I think that special cases like interlaced source videos should be handled manually anyway.
Title: Re: How_To_Batch_File_Proccessing?
Post by: chucknolan on April 30, 2021, 10:06:37 PM
Quote from: eumagga0x2a on April 30, 2021, 11:54:56 AMUsing your examples, I can suggest the following example script:

#PY  <- Needed to identify #
#
ui = Gui()
adm = Avidemux()
ext = "mp4"
outputs = ["MKV, xvid4, HE-AAC @ 56 kbps (FDK-AAC)","MP4, x265, AAC LC @ 128 kbps (FDK-AAC)","MOV, x264, AAC LC @ 192 kbps (FDK-AAC)"]
sep = "\\"
#
# Function to convert an individual video
#
def convert(filein,outdir,outidx):
    if not adm.loadVideo(filein):
        ui.displayError("oops","cannot load "+filein)
        return 0

    if outidx == 0:
        adm.videoCodec("xvid4", "params=CQ=2", "profile=244", "rdMode=3", "motionEstimation=3", "cqmMode=0", "arMode=1", "maxBFrame=2", "maxKeyFrameInterval=200", "nbThreads=99", "qMin=2", "qMax=25", "rdOnBFrame=True", "hqAcPred=True"
, "optimizeChrome=True", "trellis=True", "useXvidFCC=True", "enableFrameDrop=False", "frameDropRatio=50")
    elif outidx == 1:
        adm.videoCodec("x265", "useAdvancedConfiguration=True", "general.params=AQ=20", "general.poolThreads=99", "general.frameThreads=99", "general.output_bit_depth=0", "general.preset=", "general.tuning=", "general.profile=", "level=-1"
, "vui.sar_idc=0", "vui.sar_height=1", "vui.sar_width=1", "vui.color_primaries=2", "vui.transfer_characteristics=2", "vui.matrix_coeffs=2", "MaxRefFrames=3", "MinIdr=25", "MaxIdr=250", "i_scenecut_threshold=40"
, "MaxBFrame=3", "i_bframe_adaptive=2", "i_bframe_bias=0", "i_bframe_pyramid=1", "b_deblocking_filter=True", "b_open_gop=False", "interlaced_mode=0", "constrained_intra=False", "b_intra=True", "lookahead=40"
, "weighted_pred=2", "weighted_bipred=True", "rect_inter=False", "amp_inter=False", "limit_modes=False", "cb_chroma_offset=0", "cr_chroma_offset=0", "me_method=3", "me_range=16", "subpel_refine=5", "limit_refs=3"
, "rd_level=3", "psy_rd=1.000000", "rdoq_level=0", "psy_rdoq=0.000000", "fast_pskip=True", "dct_decimate=True", "noise_reduction_intra=0", "noise_reduction_inter=0", "strong_intra_smoothing=True", "ratecontrol.rc_method=0"
, "ratecontrol.qp_constant=0", "ratecontrol.qp_step=4", "ratecontrol.bitrate=0", "ratecontrol.vbv_max_bitrate=0", "ratecontrol.vbv_buffer_size=0", "ratecontrol.vbv_buffer_init=1", "ratecontrol.ip_factor=1.400000"
, "ratecontrol.pb_factor=1.300000", "ratecontrol.aq_mode=2", "ratecontrol.aq_strength=1.000000", "ratecontrol.cu_tree=True", "ratecontrol.strict_cbr=False")
    elif outidx == 2:
        adm.videoCodec("x264", "useAdvancedConfiguration=False", "general.params=AQ=20", "general.threads=0", "general.preset=veryfast", "general.tuning=none", "general.profile=high", "general.fast_decode=False", "general.zero_latency=False"
, "general.fast_first_pass=True", "general.blueray_compatibility=False", "general.fake_interlaced=False", "level=-1", "vui.sar_height=1", "vui.sar_width=1", "MaxRefFrames=3", "MinIdr=25", "MaxIdr=250"
, "i_scenecut_threshold=40", "intra_refresh=False", "MaxBFrame=3", "i_bframe_adaptive=1", "i_bframe_bias=0", "i_bframe_pyramid=1", "b_deblocking_filter=True", "i_deblocking_filter_alphac0=0", "i_deblocking_filter_beta=0"
, "cabac=True", "interlaced=False", "constrained_intra=False", "tff=True", "fake_interlaced=False", "analyze.b_8x8=True", "analyze.b_i4x4=True", "analyze.b_i8x8=True", "analyze.b_p8x8=True", "analyze.b_p16x16=False"
, "analyze.b_b16x16=False", "analyze.weighted_pred=2", "analyze.weighted_bipred=True", "analyze.direct_mv_pred=1", "analyze.chroma_offset=0", "analyze.me_method=1", "analyze.me_range=16", "analyze.mv_range=-1"
, "analyze.mv_range_thread=-1", "analyze.subpel_refine=7", "analyze.chroma_me=True", "analyze.mixed_references=True", "analyze.trellis=1", "analyze.psy_rd=1.000000", "analyze.psy_trellis=0.000000", "analyze.fast_pskip=True"
, "analyze.dct_decimate=True", "analyze.noise_reduction=0", "analyze.psy=True", "analyze.intra_luma=11", "analyze.inter_luma=21", "ratecontrol.rc_method=0", "ratecontrol.qp_constant=0", "ratecontrol.qp_min=10"
, "ratecontrol.qp_max=51", "ratecontrol.qp_step=4", "ratecontrol.bitrate=0", "ratecontrol.rate_tolerance=1.000000", "ratecontrol.vbv_max_bitrate=0", "ratecontrol.vbv_buffer_size=0", "ratecontrol.vbv_buffer_init=1"
, "ratecontrol.ip_factor=1.400000", "ratecontrol.pb_factor=1.300000", "ratecontrol.aq_mode=1", "ratecontrol.aq_strength=1.000000", "ratecontrol.mb_tree=True", "ratecontrol.lookahead=40")
    else:
        ui.displayError("Error", "Invalid output preset index \"" + str(outidx) + "\"")
        return 0
    nbTracks = adm.audioTracksCount()
    if nbTracks > 0:
        adm.audioClearTracks()
        for track in range(nbTracks):
            adm.audioAddTrack(track)
            if outidx == 0:
                adm.audioCodec(track, "FDK_AAC", "bitrate=56", "afterburner=True", "profile=5", "sbr=False")
            elif outidx == 1:
                adm.audioCodec(track, "FDK_AAC", "bitrate=128", "afterburner=True", "profile=2", "sbr=False")
            elif outidx == 2:
                adm.audioCodec(track, "FDK_AAC", "bitrate=192", "afterburner=True", "profile=2", "sbr=False")
            else:
                ui.displayError("Error", "Invalid output preset index \"" + str(outidx) + "\"")
                return 0
    filename = (splitext(filein))[0]
    if outidx == 0:
        adm.setContainer("MKV", "forceAspectRatio=False", "displayWidth=1280", "displayAspectRatio=2", "addColourInfo=False", "colMatrixCoeff=2", "colRange=0", "colTransfer=2", "colPrimaries=2")
        filename += ".mkv"
    elif outidx == 1:
        adm.setContainer("MP4", "muxerType=0", "optimize=1", "forceAspectRatio=False", "aspectRatio=1", "displayWidth=1280", "rotation=0", "clockfreq=0")
        filename += ".mp4"
    elif outidx == 2:
        adm.setContainer("MOV", "muxerType=0", "optimize=1", "forceAspectRatio=False", "aspectRatio=1", "displayWidth=1280", "rotation=0", "clockfreq=0")
        filename += ".mov"
    else:
        ui.displayError("Error", "Invalid output preset index \"" + str(outidx) + "\"")
        return 0
    filename = basename(filename)
    return adm.save(outdir + sep + filename)
#
# Main
#
# -------- select extension and output preset --------
extensions = ["avi","m2ts","mkv","mov","mp4","mpg","ts","vob","webm","wmv"]
mxExt = len(extensions)

menuExt = DFMenu("Select extension:")
for entry in range(0, mxExt):
    menuExt.addItem(extensions[entry])

mxOut = len(outputs)

menuOut = DFMenu("Select output preset:")
for entry in range(0, mxOut):
    menuOut.addItem(outputs[entry])

dia = DialogFactory("Configuration")
dia.addControl(menuExt)
dia.addControl(menuOut)
if not dia.show():
    return

idxExt = menuExt.index

if idxExt < 0 or idxExt >= mxExt:
    ui.displayError("Oops", "Internal error: invalid menu index")
    return

ext = extensions[idxExt]

idxOut = menuOut.index

if idxOut < 0 or idxOut >= mxOut:
    ui.displayError("Oops", "Internal error: invalid menu index")
    return

# -------- select input directory --------
inputFolder = ui.dirSelect("Select source folder")
if inputFolder is None:
    ui.displayError("Error", "No source folder selected")
    return

# -------- read content --------
list = get_folder_content(inputFolder, ext)
if list is None:
    ui.displayError("Oops", "No " + ext + " files found in \"" + inputFolder + "\"")
    return

# -------- select output directory --------
outputFolder = ui.dirSelect("Select output folder")
if outputFolder is None:
    ui.displayError("Error", "No output folder selected")
    return

if(inputFolder == outputFolder):
    ui.displayError("Error","Output folder cannot be the same as the input one")
    return

# -------- process --------
total = 0
counter = 0

for i in list:
    total += 1
    counter += convert(i, outputFolder, idxOut)

if not counter:
    ui.displayInfo("Warning", "No files converted")
    return

if counter == 1:
    ui.displayInfo("Finished", "One file out of " + str(total) + " converted")
    return

ui.displayInfo("Finished", str(counter) + " files out of " + str(total) + " converted")

I didn't verify that video encoder configuration makes sense, please replace it with whatever suits your needs. I think that special cases like interlaced source videos should be handled manually anyway.

THANK YOU. I really appreciate it.  Managed to attach over 40 output presets within 4 individual scripts, and it's all thanks to you.  Thanks again.
Title: Re: How_To_Batch_File_Proccessing?
Post by: chucknolan on May 03, 2021, 08:28:23 PM
Apologies for bothering you, but I am not sure if you answered this previous question regarding how to apply the preset to a specific file via selection.  I was wondering, below, if you can help me with the script because it gives me a loading error each time I want to select a specific file instead of the folder:

# -------- select input directory --------
inputFolder = ui.dirSelect("Select source folder")
if inputFolder is None:
    ui.displayError("Error", "No source folder selected")
    return
   
# -------- read content --------
list = get_folder_content(inputFolder, ext)
if list is None:
    ui.displayError("Oops", "No " + ext + " files found in \"" + inputFolder + "\"")
    return

# -------- read content commanding --------
list = ui.fileReadSelect(inputFolder, ext)
if list is None:
    ui.displayError("Oops", "No " + ext + " files found in \"" + inputFolder + "\"")
    return

# -------- write content commanding --------
list = ui.fileWriteSelect(inputFolder, ext)
if list is None:
    ui.displayError("Oops", "No " + ext + " files found in \"" + inputFolder + "\"")
    return
Title: Re: How_To_Batch_File_Proccessing?
Post by: eumagga0x2a on May 03, 2021, 11:11:42 PM
You cannot use dirSelect() for single file selection, it also doesn't make sense to use a list to hold a single string. You could use the following not exactly pretty script which adds an additional dialog to switch between directory and single file modes:

#PY  <- Needed to identify #
#
ui = Gui()
adm = Avidemux()
ext = "mp4"
outputs = ["MKV, xvid4, HE-AAC @ 56 kbps (FDK-AAC)","MP4, x265, AAC LC @ 128 kbps (FDK-AAC)","MOV, x264, AAC LC @ 192 kbps (FDK-AAC)"]
mxOut = len(outputs)
sep = "\\"
#
# Function to convert an individual video
#
def convert(filein,outdir,outidx):
    if not adm.loadVideo(filein):
        ui.displayError("oops","cannot load "+filein)
        return 0

    if outidx == 0:
        adm.videoCodec("xvid4", "params=CQ=2", "profile=244", "rdMode=3", "motionEstimation=3", "cqmMode=0", "arMode=1", "maxBFrame=2", "maxKeyFrameInterval=200", "nbThreads=99", "qMin=2", "qMax=25", "rdOnBFrame=True", "hqAcPred=True"
, "optimizeChrome=True", "trellis=True", "useXvidFCC=True", "enableFrameDrop=False", "frameDropRatio=50")
    elif outidx == 1:
        adm.videoCodec("x265", "useAdvancedConfiguration=True", "general.params=AQ=20", "general.poolThreads=99", "general.frameThreads=99", "general.output_bit_depth=0", "general.preset=", "general.tuning=", "general.profile=", "level=-1"
, "vui.sar_idc=0", "vui.sar_height=1", "vui.sar_width=1", "vui.color_primaries=2", "vui.transfer_characteristics=2", "vui.matrix_coeffs=2", "MaxRefFrames=3", "MinIdr=25", "MaxIdr=250", "i_scenecut_threshold=40"
, "MaxBFrame=3", "i_bframe_adaptive=2", "i_bframe_bias=0", "i_bframe_pyramid=1", "b_deblocking_filter=True", "b_open_gop=False", "interlaced_mode=0", "constrained_intra=False", "b_intra=True", "lookahead=40"
, "weighted_pred=2", "weighted_bipred=True", "rect_inter=False", "amp_inter=False", "limit_modes=False", "cb_chroma_offset=0", "cr_chroma_offset=0", "me_method=3", "me_range=16", "subpel_refine=5", "limit_refs=3"
, "rd_level=3", "psy_rd=1.000000", "rdoq_level=0", "psy_rdoq=0.000000", "fast_pskip=True", "dct_decimate=True", "noise_reduction_intra=0", "noise_reduction_inter=0", "strong_intra_smoothing=True", "ratecontrol.rc_method=0"
, "ratecontrol.qp_constant=0", "ratecontrol.qp_step=4", "ratecontrol.bitrate=0", "ratecontrol.vbv_max_bitrate=0", "ratecontrol.vbv_buffer_size=0", "ratecontrol.vbv_buffer_init=1", "ratecontrol.ip_factor=1.400000"
, "ratecontrol.pb_factor=1.300000", "ratecontrol.aq_mode=2", "ratecontrol.aq_strength=1.000000", "ratecontrol.cu_tree=True", "ratecontrol.strict_cbr=False")
    elif outidx == 2:
        adm.videoCodec("x264", "useAdvancedConfiguration=False", "general.params=AQ=20", "general.threads=0", "general.preset=veryfast", "general.tuning=none", "general.profile=high", "general.fast_decode=False", "general.zero_latency=False"
, "general.fast_first_pass=True", "general.blueray_compatibility=False", "general.fake_interlaced=False", "level=-1", "vui.sar_height=1", "vui.sar_width=1", "MaxRefFrames=3", "MinIdr=25", "MaxIdr=250"
, "i_scenecut_threshold=40", "intra_refresh=False", "MaxBFrame=3", "i_bframe_adaptive=1", "i_bframe_bias=0", "i_bframe_pyramid=1", "b_deblocking_filter=True", "i_deblocking_filter_alphac0=0", "i_deblocking_filter_beta=0"
, "cabac=True", "interlaced=False", "constrained_intra=False", "tff=True", "fake_interlaced=False", "analyze.b_8x8=True", "analyze.b_i4x4=True", "analyze.b_i8x8=True", "analyze.b_p8x8=True", "analyze.b_p16x16=False"
, "analyze.b_b16x16=False", "analyze.weighted_pred=2", "analyze.weighted_bipred=True", "analyze.direct_mv_pred=1", "analyze.chroma_offset=0", "analyze.me_method=1", "analyze.me_range=16", "analyze.mv_range=-1"
, "analyze.mv_range_thread=-1", "analyze.subpel_refine=7", "analyze.chroma_me=True", "analyze.mixed_references=True", "analyze.trellis=1", "analyze.psy_rd=1.000000", "analyze.psy_trellis=0.000000", "analyze.fast_pskip=True"
, "analyze.dct_decimate=True", "analyze.noise_reduction=0", "analyze.psy=True", "analyze.intra_luma=11", "analyze.inter_luma=21", "ratecontrol.rc_method=0", "ratecontrol.qp_constant=0", "ratecontrol.qp_min=10"
, "ratecontrol.qp_max=51", "ratecontrol.qp_step=4", "ratecontrol.bitrate=0", "ratecontrol.rate_tolerance=1.000000", "ratecontrol.vbv_max_bitrate=0", "ratecontrol.vbv_buffer_size=0", "ratecontrol.vbv_buffer_init=1"
, "ratecontrol.ip_factor=1.400000", "ratecontrol.pb_factor=1.300000", "ratecontrol.aq_mode=1", "ratecontrol.aq_strength=1.000000", "ratecontrol.mb_tree=True", "ratecontrol.lookahead=40")
    else:
        ui.displayError("Error", "Invalid output preset index \"" + str(outidx) + "\"")
        return 0
    nbTracks = adm.audioTracksCount()
    if nbTracks > 0:
        adm.audioClearTracks()
        for track in range(nbTracks):
            adm.audioAddTrack(track)
            if outidx == 0:
                adm.audioCodec(track, "FDK_AAC", "bitrate=56", "afterburner=True", "profile=5", "sbr=False")
            elif outidx == 1:
                adm.audioCodec(track, "FDK_AAC", "bitrate=128", "afterburner=True", "profile=2", "sbr=False")
            elif outidx == 2:
                adm.audioCodec(track, "FDK_AAC", "bitrate=192", "afterburner=True", "profile=2", "sbr=False")
            else:
                ui.displayError("Error", "Invalid output preset index \"" + str(outidx) + "\"")
                return 0
    filename = (splitext(filein))[0]
    if outidx == 0:
        adm.setContainer("MKV", "forceAspectRatio=False", "displayWidth=1280", "displayAspectRatio=2", "addColourInfo=False", "colMatrixCoeff=2", "colRange=0", "colTransfer=2", "colPrimaries=2")
        filename += ".mkv"
    elif outidx == 1:
        adm.setContainer("MP4", "muxerType=0", "optimize=1", "forceAspectRatio=False", "aspectRatio=1", "displayWidth=1280", "rotation=0", "clockfreq=0")
        filename += ".mp4"
    elif outidx == 2:
        adm.setContainer("MOV", "muxerType=0", "optimize=1", "forceAspectRatio=False", "aspectRatio=1", "displayWidth=1280", "rotation=0", "clockfreq=0")
        filename += ".mov"
    else:
        ui.displayError("Error", "Invalid output preset index \"" + str(outidx) + "\"")
        return 0
    filename = basename(filename)
    return adm.save(outdir + sep + filename)
#
# Main
#
# -------- select mode --------
menuMode = DFMenu("Select mode:")
menuMode.addItem("Process directory")
menuMode.addItem("Process single file")

diaMode = DialogFactory("Type of operation")
diaMode.addControl(menuMode)
if not diaMode.show():
    return

idxMode = menuMode.index

if idxMode < 0 or idxMode > 1:
    ui.displayError("Oops", "Internal error: invalid menu index")
    return

if idxMode == 1:
    # select output preset for single-file operation
    mxOut = len(outputs)
    menuOut = DFMenu("Select output preset:")
    for entry in range(mxOut):
        menuOut.addItem(outputs[entry])
    diaSingle = DialogFactory("Configuration")
    diaSingle.addControl(menuOut)
    if not diaSingle.show():
        return
    idxOut = menuOut.index
    if idxOut < 0 or idxOut >= mxOut:
        ui.displayError("Oops", "Internal error: invalid menu index")
        return
    # select input file
    fileToProcess = ui.fileReadSelect("Select file to process")
    if fileToProcess is None:
        return
    # select output directory
    outputFolder = ui.dirSelect("Select output folder")
    if outputFolder is None:
        ui.displayError("Error", "No output folder selected")
        return
    if outputFolder == dirname(fileToProcess):
        ui.displayError("Error","Output folder and the directory of the input file must be different")
        return
    # process!
    if not convert(fileToProcess, outputFolder, idxOut):
        ui.displayError("Error","Error processing \"" + fileToProcess + "\"")
        return
    ui.displayInfo("Finished","File \"" + fileToProcess + "\" processed successfully")
    return

# -------- select extension and output preset --------
extensions = ["avi","m2ts","mkv","mov","mp4","mpg","ts","vob","webm","wmv"]
mxExt = len(extensions)

menuExt = DFMenu("Select extension:")
for entry in range(0, mxExt):
    menuExt.addItem(extensions[entry])

menuOut = DFMenu("Select output preset:")
for entry in range(0, mxOut):
    menuOut.addItem(outputs[entry])

diaMulti = DialogFactory("Configuration")
diaMulti.addControl(menuExt)
diaMulti.addControl(menuOut)
if not diaMulti.show():
    return

idxExt = menuExt.index

if idxExt < 0 or idxExt >= mxExt:
    ui.displayError("Oops", "Internal error: invalid menu index")
    return

ext = extensions[idxExt]

idxOut = menuOut.index

if idxOut < 0 or idxOut >= mxOut:
    ui.displayError("Oops", "Internal error: invalid menu index")
    return

# -------- select input directory --------
inputFolder = ui.dirSelect("Select source folder")
if inputFolder is None:
    ui.displayError("Error", "No source folder selected")
    return

# -------- read content --------
list = get_folder_content(inputFolder, ext)
if list is None:
    ui.displayError("Oops", "No " + ext + " files found in \"" + inputFolder + "\"")
    return

# -------- select output directory --------
outputFolder = ui.dirSelect("Select output folder")
if outputFolder is None:
    ui.displayError("Error", "No output folder selected")
    return

if(inputFolder == outputFolder):
    ui.displayError("Error","Output folder cannot be the same as the input one")
    return

# -------- process --------
total = 0
counter = 0

for i in list:
    total += 1
    counter += convert(i, outputFolder, idxOut)

if not counter:
    ui.displayInfo("Warning", "No files converted")
    return

if counter == 1:
    ui.displayInfo("Finished", "One file out of " + str(total) + " converted")
    return

ui.displayInfo("Finished", str(counter) + " files out of " + str(total) + " converted")

Honestly, I would rather move single-file processing to a completely different script.
Title: Re: How_To_Batch_File_Proccessing?
Post by: butterw on May 03, 2021, 11:51:11 PM
Tinypy is quite limited. This is how you can create a list from a single filepath variable:

f_list = []
if list is None:
    ui.displayError("Oops", "No " + ext + " files found in \"" + inputFolder + "\""); return
f_ path = ui.fileReadSelect(inputFolder, ext)
f_list.append[f_path]
or
f_list = [ui.fileReadSelect(inputFolder, ext)]
if f_list[0] is None:
    ui.displayError("Oops", "No " + ext + " files found in \"" + inputFolder + "\""); return

list is a built-in function name in python, even though it's not available in TinyPy, I don't think it is a good idea to use it as a variable name.

Title: Re: How_To_Batch_File_Proccessing?
Post by: chucknolan on May 06, 2021, 07:48:00 PM
Quote from: eumagga0x2a on May 03, 2021, 11:11:42 PMYou cannot use dirSelect() for single file selection, it also doesn't make sense to use a list to hold a single string. You could use the following not exactly pretty script which adds an additional dialog to switch between directory and single file modes:

#PY  <- Needed to identify #
#
ui = Gui()
adm = Avidemux()
ext = "mp4"
outputs = ["MKV, xvid4, HE-AAC @ 56 kbps (FDK-AAC)","MP4, x265, AAC LC @ 128 kbps (FDK-AAC)","MOV, x264, AAC LC @ 192 kbps (FDK-AAC)"]
mxOut = len(outputs)
sep = "\\"
#
# Function to convert an individual video
#
def convert(filein,outdir,outidx):
    if not adm.loadVideo(filein):
        ui.displayError("oops","cannot load "+filein)
        return 0

    if outidx == 0:
        adm.videoCodec("xvid4", "params=CQ=2", "profile=244", "rdMode=3", "motionEstimation=3", "cqmMode=0", "arMode=1", "maxBFrame=2", "maxKeyFrameInterval=200", "nbThreads=99", "qMin=2", "qMax=25", "rdOnBFrame=True", "hqAcPred=True"
, "optimizeChrome=True", "trellis=True", "useXvidFCC=True", "enableFrameDrop=False", "frameDropRatio=50")
    elif outidx == 1:
        adm.videoCodec("x265", "useAdvancedConfiguration=True", "general.params=AQ=20", "general.poolThreads=99", "general.frameThreads=99", "general.output_bit_depth=0", "general.preset=", "general.tuning=", "general.profile=", "level=-1"
, "vui.sar_idc=0", "vui.sar_height=1", "vui.sar_width=1", "vui.color_primaries=2", "vui.transfer_characteristics=2", "vui.matrix_coeffs=2", "MaxRefFrames=3", "MinIdr=25", "MaxIdr=250", "i_scenecut_threshold=40"
, "MaxBFrame=3", "i_bframe_adaptive=2", "i_bframe_bias=0", "i_bframe_pyramid=1", "b_deblocking_filter=True", "b_open_gop=False", "interlaced_mode=0", "constrained_intra=False", "b_intra=True", "lookahead=40"
, "weighted_pred=2", "weighted_bipred=True", "rect_inter=False", "amp_inter=False", "limit_modes=False", "cb_chroma_offset=0", "cr_chroma_offset=0", "me_method=3", "me_range=16", "subpel_refine=5", "limit_refs=3"
, "rd_level=3", "psy_rd=1.000000", "rdoq_level=0", "psy_rdoq=0.000000", "fast_pskip=True", "dct_decimate=True", "noise_reduction_intra=0", "noise_reduction_inter=0", "strong_intra_smoothing=True", "ratecontrol.rc_method=0"
, "ratecontrol.qp_constant=0", "ratecontrol.qp_step=4", "ratecontrol.bitrate=0", "ratecontrol.vbv_max_bitrate=0", "ratecontrol.vbv_buffer_size=0", "ratecontrol.vbv_buffer_init=1", "ratecontrol.ip_factor=1.400000"
, "ratecontrol.pb_factor=1.300000", "ratecontrol.aq_mode=2", "ratecontrol.aq_strength=1.000000", "ratecontrol.cu_tree=True", "ratecontrol.strict_cbr=False")
    elif outidx == 2:
        adm.videoCodec("x264", "useAdvancedConfiguration=False", "general.params=AQ=20", "general.threads=0", "general.preset=veryfast", "general.tuning=none", "general.profile=high", "general.fast_decode=False", "general.zero_latency=False"
, "general.fast_first_pass=True", "general.blueray_compatibility=False", "general.fake_interlaced=False", "level=-1", "vui.sar_height=1", "vui.sar_width=1", "MaxRefFrames=3", "MinIdr=25", "MaxIdr=250"
, "i_scenecut_threshold=40", "intra_refresh=False", "MaxBFrame=3", "i_bframe_adaptive=1", "i_bframe_bias=0", "i_bframe_pyramid=1", "b_deblocking_filter=True", "i_deblocking_filter_alphac0=0", "i_deblocking_filter_beta=0"
, "cabac=True", "interlaced=False", "constrained_intra=False", "tff=True", "fake_interlaced=False", "analyze.b_8x8=True", "analyze.b_i4x4=True", "analyze.b_i8x8=True", "analyze.b_p8x8=True", "analyze.b_p16x16=False"
, "analyze.b_b16x16=False", "analyze.weighted_pred=2", "analyze.weighted_bipred=True", "analyze.direct_mv_pred=1", "analyze.chroma_offset=0", "analyze.me_method=1", "analyze.me_range=16", "analyze.mv_range=-1"
, "analyze.mv_range_thread=-1", "analyze.subpel_refine=7", "analyze.chroma_me=True", "analyze.mixed_references=True", "analyze.trellis=1", "analyze.psy_rd=1.000000", "analyze.psy_trellis=0.000000", "analyze.fast_pskip=True"
, "analyze.dct_decimate=True", "analyze.noise_reduction=0", "analyze.psy=True", "analyze.intra_luma=11", "analyze.inter_luma=21", "ratecontrol.rc_method=0", "ratecontrol.qp_constant=0", "ratecontrol.qp_min=10"
, "ratecontrol.qp_max=51", "ratecontrol.qp_step=4", "ratecontrol.bitrate=0", "ratecontrol.rate_tolerance=1.000000", "ratecontrol.vbv_max_bitrate=0", "ratecontrol.vbv_buffer_size=0", "ratecontrol.vbv_buffer_init=1"
, "ratecontrol.ip_factor=1.400000", "ratecontrol.pb_factor=1.300000", "ratecontrol.aq_mode=1", "ratecontrol.aq_strength=1.000000", "ratecontrol.mb_tree=True", "ratecontrol.lookahead=40")
    else:
        ui.displayError("Error", "Invalid output preset index \"" + str(outidx) + "\"")
        return 0
    nbTracks = adm.audioTracksCount()
    if nbTracks > 0:
        adm.audioClearTracks()
        for track in range(nbTracks):
            adm.audioAddTrack(track)
            if outidx == 0:
                adm.audioCodec(track, "FDK_AAC", "bitrate=56", "afterburner=True", "profile=5", "sbr=False")
            elif outidx == 1:
                adm.audioCodec(track, "FDK_AAC", "bitrate=128", "afterburner=True", "profile=2", "sbr=False")
            elif outidx == 2:
                adm.audioCodec(track, "FDK_AAC", "bitrate=192", "afterburner=True", "profile=2", "sbr=False")
            else:
                ui.displayError("Error", "Invalid output preset index \"" + str(outidx) + "\"")
                return 0
    filename = (splitext(filein))[0]
    if outidx == 0:
        adm.setContainer("MKV", "forceAspectRatio=False", "displayWidth=1280", "displayAspectRatio=2", "addColourInfo=False", "colMatrixCoeff=2", "colRange=0", "colTransfer=2", "colPrimaries=2")
        filename += ".mkv"
    elif outidx == 1:
        adm.setContainer("MP4", "muxerType=0", "optimize=1", "forceAspectRatio=False", "aspectRatio=1", "displayWidth=1280", "rotation=0", "clockfreq=0")
        filename += ".mp4"
    elif outidx == 2:
        adm.setContainer("MOV", "muxerType=0", "optimize=1", "forceAspectRatio=False", "aspectRatio=1", "displayWidth=1280", "rotation=0", "clockfreq=0")
        filename += ".mov"
    else:
        ui.displayError("Error", "Invalid output preset index \"" + str(outidx) + "\"")
        return 0
    filename = basename(filename)
    return adm.save(outdir + sep + filename)
#
# Main
#
# -------- select mode --------
menuMode = DFMenu("Select mode:")
menuMode.addItem("Process directory")
menuMode.addItem("Process single file")

diaMode = DialogFactory("Type of operation")
diaMode.addControl(menuMode)
if not diaMode.show():
    return

idxMode = menuMode.index

if idxMode < 0 or idxMode > 1:
    ui.displayError("Oops", "Internal error: invalid menu index")
    return

if idxMode == 1:
    # select output preset for single-file operation
    mxOut = len(outputs)
    menuOut = DFMenu("Select output preset:")
    for entry in range(mxOut):
        menuOut.addItem(outputs[entry])
    diaSingle = DialogFactory("Configuration")
    diaSingle.addControl(menuOut)
    if not diaSingle.show():
        return
    idxOut = menuOut.index
    if idxOut < 0 or idxOut >= mxOut:
        ui.displayError("Oops", "Internal error: invalid menu index")
        return
    # select input file
    fileToProcess = ui.fileReadSelect("Select file to process")
    if fileToProcess is None:
        return
    # select output directory
    outputFolder = ui.dirSelect("Select output folder")
    if outputFolder is None:
        ui.displayError("Error", "No output folder selected")
        return
    if outputFolder == dirname(fileToProcess):
        ui.displayError("Error","Output folder and the directory of the input file must be different")
        return
    # process!
    if not convert(fileToProcess, outputFolder, idxOut):
        ui.displayError("Error","Error processing \"" + fileToProcess + "\"")
        return
    ui.displayInfo("Finished","File \"" + fileToProcess + "\" processed successfully")
    return

# -------- select extension and output preset --------
extensions = ["avi","m2ts","mkv","mov","mp4","mpg","ts","vob","webm","wmv"]
mxExt = len(extensions)

menuExt = DFMenu("Select extension:")
for entry in range(0, mxExt):
    menuExt.addItem(extensions[entry])

menuOut = DFMenu("Select output preset:")
for entry in range(0, mxOut):
    menuOut.addItem(outputs[entry])

diaMulti = DialogFactory("Configuration")
diaMulti.addControl(menuExt)
diaMulti.addControl(menuOut)
if not diaMulti.show():
    return

idxExt = menuExt.index

if idxExt < 0 or idxExt >= mxExt:
    ui.displayError("Oops", "Internal error: invalid menu index")
    return

ext = extensions[idxExt]

idxOut = menuOut.index

if idxOut < 0 or idxOut >= mxOut:
    ui.displayError("Oops", "Internal error: invalid menu index")
    return

# -------- select input directory --------
inputFolder = ui.dirSelect("Select source folder")
if inputFolder is None:
    ui.displayError("Error", "No source folder selected")
    return

# -------- read content --------
list = get_folder_content(inputFolder, ext)
if list is None:
    ui.displayError("Oops", "No " + ext + " files found in \"" + inputFolder + "\"")
    return

# -------- select output directory --------
outputFolder = ui.dirSelect("Select output folder")
if outputFolder is None:
    ui.displayError("Error", "No output folder selected")
    return

if(inputFolder == outputFolder):
    ui.displayError("Error","Output folder cannot be the same as the input one")
    return

# -------- process --------
total = 0
counter = 0

for i in list:
    total += 1
    counter += convert(i, outputFolder, idxOut)

if not counter:
    ui.displayInfo("Warning", "No files converted")
    return

if counter == 1:
    ui.displayInfo("Finished", "One file out of " + str(total) + " converted")
    return

ui.displayInfo("Finished", str(counter) + " files out of " + str(total) + " converted")

Honestly, I would rather move single-file processing to a completely different script.

Thank you, sir.  Last question, regarding INDEPENDENT presets.  Would the script, below, be classified as INDEPENDENT because I utilized a cumulative of all the templates that you provided for me?  Nonetheless, the three output presets worked on the script below.


#PY  <- Needed to identify #
#
ui = Gui()
adm = Avidemux()
ext = "mp4"
outputs = ["MKV, xvid4, HE-AAC @ 56 kbps (FDK-AAC)","MP4, AAC LC @ 128 kbps (FDK-AAC)","MOV, HE-AACv2 @ 56 kbps (FDK-AAC)"]
mxOut = len(outputs)
sep = "\\"
#
# Function to convert an individual video
#
def convert(filein,outdir,outidx):
    if not adm.loadVideo(filein):
        ui.displayError("oops","cannot load "+filein)
        return 0

    if outidx == 0:
        adm.videoCodec("xvid4", "params=CQ=2", "profile=244", "rdMode=3", "motionEstimation=3", "cqmMode=0", "arMode=1", "maxBFrame=2", "maxKeyFrameInterval=200", "nbThreads=99", "qMin=2", "qMax=25", "rdOnBFrame=True", "hqAcPred=True"
, "optimizeChrome=True", "trellis=True", "useXvidFCC=True", "enableFrameDrop=False", "frameDropRatio=50")
        if adm.audioTracksCount() > 0:
            adm.audioClearTracks()
            adm.audioAddTrack(0)
            adm.audioCodec(0, "FDK_AAC", "bitrate=56", "afterburner=True", "profile=5", "sbr=False")
            adm.audioSetDrc(0, 0)
            adm.audioSetShift(0, 0, 0)
            adm.audioSetNormalize2(0, 2, 120, -30)
        adm.setContainer("MKV", "forceAspectRatio=False", "displayWidth=1280", "displayAspectRatio=2", "addColourInfo=False", "colMatrixCoeff=2", "colRange=0", "colTransfer=2", "colPrimaries=2")

        filename = (splitext(filein))[0]
        filename += ".mkv"
        filename = basename(filename)
        return adm.save(outdir + sep + filename)
    elif outidx == 1:
        adm.videoCodec("copy")
        if adm.audioTracksCount() > 0:
            adm.audioClearTracks()
            adm.audioAddTrack(0)
            adm.audioCodec(0, "FDK_AAC", "bitrate=128", "afterburner=True", "profile=2", "sbr=False")
        adm.setContainer("MP4", "muxerType=0", "optimize=1", "forceAspectRatio=False", "aspectRatio=1", "displayWidth=1280", "rotation=0", "clockfreq=0")

        filename = (splitext(filein))[0]
        filename += ".mp4"
        filename = basename(filename)
        return adm.save(outdir + sep + filename)
    elif outidx == 2:
        adm.videoCodec("copy")
        nbTracks = adm.audioTracksCount()
        if nbTracks > 0:
            adm.audioClearTracks()
            for track in range(nbTracks):
                adm.audioAddTrack(track)
                adm.audioCodec(track, "FDK_AAC", "bitrate=56", "afterburner=True", "profile=29", "sbr=False")
        adm.setContainer("MOV", "muxerType=0", "optimize=1", "forceAspectRatio=False", "aspectRatio=1", "displayWidth=1280", "rotation=0", "clockfreq=0")

        filename = (splitext(filein))[0]
        filename += ".mov"
        filename = basename(filename)
        return adm.save(outdir + sep + filename)
    else:
        ui.displayError("Error", "Invalid output preset index \"" + str(outidx) + "\"")
        return 0
#
# Main
#
# -------- select mode --------
menuMode = DFMenu("Select mode:")
menuMode.addItem("Process directory")
menuMode.addItem("Process single file")

diaMode = DialogFactory("Type of operation")
diaMode.addControl(menuMode)
if not diaMode.show():
    return

idxMode = menuMode.index

if idxMode < 0 or idxMode > 1:
    ui.displayError("Oops", "Internal error: invalid menu index")
    return

if idxMode == 1:
    # select output preset for single-file operation
    mxOut = len(outputs)
    menuOut = DFMenu("Select output preset:")
    for entry in range(mxOut):
        menuOut.addItem(outputs[entry])
    diaSingle = DialogFactory("Configuration")
    diaSingle.addControl(menuOut)
    if not diaSingle.show():
        return
    idxOut = menuOut.index
    if idxOut < 0 or idxOut >= mxOut:
        ui.displayError("Oops", "Internal error: invalid menu index")
        return
    # select input file
    fileToProcess = ui.fileReadSelect("Select file to process")
    if fileToProcess is None:
        return
    # select output directory
    outputFolder = ui.dirSelect("Select output folder")
    if outputFolder is None:
        ui.displayError("Error", "No output folder selected")
        return
    if outputFolder == dirname(fileToProcess):
        ui.displayError("Error","Output folder and the directory of the input file must be different")
        return
    # process!
    if not convert(fileToProcess, outputFolder, idxOut):
        ui.displayError("Error","Error processing \"" + fileToProcess + "\"")
        return
    ui.displayInfo("Finished","File \"" + fileToProcess + "\" processed successfully")
    return

# -------- select extension and output preset --------
extensions = ["avi","m2ts","mkv","mov","mp4","mpg","ts","vob","webm","wmv"]
mxExt = len(extensions)

menuExt = DFMenu("Select extension:")
for entry in range(0, mxExt):
    menuExt.addItem(extensions[entry])

menuOut = DFMenu("Select output preset:")
for entry in range(0, mxOut):
    menuOut.addItem(outputs[entry])

diaMulti = DialogFactory("Configuration")
diaMulti.addControl(menuExt)
diaMulti.addControl(menuOut)
if not diaMulti.show():
    return

idxExt = menuExt.index

if idxExt < 0 or idxExt >= mxExt:
    ui.displayError("Oops", "Internal error: invalid menu index")
    return

ext = extensions[idxExt]

idxOut = menuOut.index

if idxOut < 0 or idxOut >= mxOut:
    ui.displayError("Oops", "Internal error: invalid menu index")
    return

# -------- select input directory --------
inputFolder = ui.dirSelect("Select source folder")
if inputFolder is None:
    ui.displayError("Error", "No source folder selected")
    return

# -------- read content --------
list = get_folder_content(inputFolder, ext)
if list is None:
    ui.displayError("Oops", "No " + ext + " files found in \"" + inputFolder + "\"")
    return

# -------- select output directory --------
outputFolder = ui.dirSelect("Select output folder")
if outputFolder is None:
    ui.displayError("Error", "No output folder selected")
    return

if(inputFolder == outputFolder):
    ui.displayError("Error","Output folder cannot be the same as the input one")
    return

# -------- process --------
total = 0
counter = 0

for i in list:
    total += 1
    counter += convert(i, outputFolder, idxOut)

if not counter:
    ui.displayInfo("Warning", "No files converted")
    return

if counter == 1:
    ui.displayInfo("Finished", "One file out of " + str(total) + " converted")
    return

ui.displayInfo("Finished", str(counter) + " files out of " + str(total) + " converted")
Title: Re: How_To_Batch_File_Proccessing?
Post by: eumagga0x2a on May 06, 2021, 09:33:58 PM
Quote from: chucknolan on May 06, 2021, 07:48:00 PMWould the script, below, be classified as INDEPENDENT because I utilized a cumulative of all the templates that you provided for me?

"Independent" vs "linked" meant the ability to specify video encoder independently from muxer. Obviously, both are linked in your script.
Title: Re: How_To_Batch_File_Proccessing?
Post by: chucknolan on May 06, 2021, 10:23:30 PM
Quote from: eumagga0x2a on May 06, 2021, 09:33:58 PM"Independent" vs "linked" meant the ability to specify video encoder independently from muxer. Obviously, both are linked in your script.


They were linked to only reassure the drop-down menu output preset selection.  Nonetheless, I'm still confused about how an independent script would look like, and was hoping, at your leisure, if you can write one for me?