Modding Tools

Vidsquish is a GUI for executing external video conversion programs called profiles. A collection of profiles are provided as part of the main Vidsquish download to get you started and act as templates for creating your own. While writing a new profile from scratch may seem daunting, this guide will cover the fundamental principles of Vidsquish profile development so you'll be modding in no time.

Profile Format
Vidsquish profiles use the extension ".cmd", but actually, they're two different filetypes in one! A profile is comprised of an INI section which defines values for the Vidsquish GUI, and a Batch section which executes Windows console commands to perform conversions.

Every Vidsquish profile must begin with the following code:


@echo off
setlocal EnableDelayedExpansion
goto process_start

<INI section goes here>

[BATCH]
:process_start

<Batch section goes here>


The opening three lines instruct Windows not to write out the contents of every Batch command while processing, to allow defining variables in real-time, and to skip over the INI section down to the Batch section, where commands begin. Similarly, the [BATCH] header helps INI parsers skip over the Batch section--like putting Batch code in a box that INI can understand (and then simply never opening the box).

Virtually any Windows Batch commands can be executed in the Batch section, provided they follow some basic rules (more on that later). But first, we need to retrieve any customizable options from the user, so we know what commands to execute!

INI Menu Definitions
When a profile is selected in the Vidsquish GUI, the INI section will be parsed for menu definitions. These include values describing the profile itself, as well as any options the user may wish to choose to customize the profile's behavior. All options are presented as dropdown lists.

(Tip: INI files can include comments preceded by a semicolon. Comments can help describe your code while being ignored by the parser.)

The [PROFILE] Section
The first definition to create is the [PROFILE] section. Here there are four required values:

[PROFILE]
name="My Profile Name (Video Format)"
format="My Video Format (*.video)|*.video"
example="file.video"
version="1.0"


(Note the quotes around each definition!)

The profile name determines how your profile will appear in the Vidsquish GUI. It is recommended to include the name of the applicable game and video format, since some profiles may apply to multiple games even if they are only written and tested for one.

The format section is more particular: this defines how files will be filtered in the Windows file browser dialog. There are two values here, divided by a pipe ("|") in the middle. The first half provides a description of the format being filtered, while the second half provides the filter itself. This filter should always be written as *.extension, where "*" is a wildcard allowing any filenames with the matching extension to be selected. Although rare, some games may use multiple extensions for the same format, in which case multiple filters can be listed, separated with a semicolon. For example:

format="Multiple Formats|*.one;*.two"

The example definition provides the default filename to be included in the file browser dialog. Since game data often uses obtuse naming schemes, this can help the user identify the correct folder in their game directory. The example is only a suggestion, however, and any filename of the filtered extension can be selected. Remember: Vidsquish will operate on the entire folder, not just the selected file!

Lastly, there is the version definition. This value is for your reference only to track any changes you may have made to your profile over time.

In addition to these required definitions, the Profile section also supports three optional definitions as well:

description="Everything you need to know about this profile"
basedir="some\sub\folder"
maxthreads="1"


The description definition will cause a "?" icon to be displayed in the Vidsquish GUI, which users can click to learn more about your profile as a whole. It is recommended to include any known details about the game format, any limitations the game imposes on its cutscenes, and information on any required mods to remove those limitations.

Note that descriptions must be written on one line. To add line breaks to your description text, write \n (for "newline").

Some games spread video files across multiple directories. However, as explained above, users must select an individual file to choose a directory for Vidsquish to operate on. In this case, the basedir definition provides a filter for Vidsquish to parse contents starting in a certain parent directory instead. Do not try to write the full path here--it may be different on different users' PC's. Instead, include the target directory name and one or two parent directories to make sure the filter is accurate.

Note that this definition will also enable recursive mode in Vidsquish. By default, Vidsquish will not search any child directories for video files.

As of version 2.0.0, Vidsquish supports multi-processing to speed up conversions by executing multiple conversion processes simultaneously. While this is very useful, it also adds complexity to profile design, and some libraries may not support it at all. If your profile does not support multi-processing, or only supports a limited number of simultaneous processes, the maxthreads definition allows you to specify how many processes are allowed for a given profile. This value will override the user's multi-processing setting in the Vidsquish GUI to avoid instability or corrupted data in profiles not designed with multi-processing in mind.

Note that if this definition is set to 0, it will be ignored.

The [MENU#] Sections
After the Profile section come any Menu sections your profile requires to customize its behavior. Each menu represents a single dropdown list of options in the Vidsquish GUI, and are numbered starting from 2. This is because [MENU0] and [MENU1] are for selecting a profile and folder path, respectively.

Each Menu section requires one or more case definitions and a default. A description can also be defined, which follows the same principles as the Profile section.

[MENU2]
case0="Option 1|value1"
case1="Option 2|value2"
default="Choose an option"
description="Everything you need to know about this menu"


(Note that cases are numbered from 0!)

Like file filters, each option (or "case") is comprised of a description and value separated by a pipe ("|"). The description will be shown in the Vidsquish GUI, while the value will be passed into the Batch section as a commandline argument. Values can be either numerical or strings, but they cannot contain spaces or delimiter characters, otherwise they will be parsed as two arguments rather than one.

If no pipe/value is present, the option value will be treated as NULL, and the conversion process will not begin until a valid option is selected. As such, it is recommended not to include a value in the default definition, but rather to use it as a description of the menu itself. This ensures the user doesn't forget to choose any available option for themselves.

Note that there is no limit on the number of cases a menu may have, but there is a practical limit on the number of menus Vidsquish can display. This is determined by the active skin. If your profile requires an exceptional number of menus, you may also need to create a custom skin to display them all.

Batch Commands
Once your Profile and Menu definitions are complete, you're ready to start programming for real!

While they may exist together in Vidsquish, Windows Batch code operates completely differently from INI code. A complete tutorial on Batch programming is beyond the scope of this guide, so instead we'll focus on the flow and principles of writing Vidsquish profiles in Batch.

Starting after the :process_start marker, a Vidsquish profile should achieve six basic tasks:

  • Initialize and setup based on user options
  • Unpack/convert arcane formats to common media formats
  • Generate a preview image
  • Perform filters and modifications
  • Package/convert common formats back to game formats
  • Flag the process as complete

Steps 2 and 5 will generally require different tools for each game--and sometimes, different tools for each step. This is where Vidsquish libraries come in. Vidsquish includes a collection of commandline utilities capable of unpacking and repacking files for each game supported out of the box. But if the included libraries don't support your game's format, you can add your own libraries too! Simply open the Vidsquish GUI and go to Settings > Manage Libraries (Alt + L) to add any extra programs your profile requires. When distributing your profile, be sure to include them for other users to add to their Vidsquish installations as well.

Steps 3 and 4, on the other hand, will generally all use the same tool: FFMPEG. FFMPEG is a commandline utility capable of encoding and decoding an incredible variety of video formats by itself. But also, it provides a powerful suite of filters and modifications that will handle the bulk of your user-selected options. As with Batch programming, a complete tutorial on FFMPEG filters is beyond the scope of this guide, but you'll find a variety of examples in existing Vidsquish profiles to get you started with the most common manipulations.

As previously mentioned, you'll want to handle user-selected options in Step 1 before passing them into FFMPEG and other libraries as Batch variables. Arguments are input in menu order, including the hidden [MENU0] and [MENU1]. As such, the argument %0 refers to the profile itself, and %1 refers to the current input video file being modified. Arguments %2%3, and so on refer to your own Menu definitions.

For example, consider the following menu:

[MENU2] ;Aspect ratio
case0="16:9 (HD)|16_9"
case1="4:3 (Legacy)|4_3"
default="Select aspect ratio"


In this case, if the user chose the first option, the variable %2 would equal 16_9. If they chose the second, %2 would equal 4_3. Batch allows basic 'if/then' logic which can be used to check such user choices and adjust behaviors accordingly. For example:

if %2==4_3 (
set width=1024
set height=768
)


In this way, user choices can be used to create variables which alter the output of each commandline program in the profile. Custom variables as shown above can be referenced elsewhere in code enclosed in exclamation marks, (e.g. !width! and !height!).

In general, Vidsquish places very few limits on what Batch code can be executed. However, keep in mind that all commands will be executed from the "%APPDATA%\Vidsquish\lib" directory. To reference files in the game directory, you can use Batch argument expansion operators. As previously stated, the variable %1 refers to the current input video file itself. To get the game directory, %~dp1 can be used instead. The tilde ("~") begins the expansion, while "d" and "p" refer to "drive" and "path", respectively. This will return the drive and path of argument 1, excluding the filename and extension (which could be retrieved with "n" and "x" instead). In many cases, you may wish to write temporary data to the game directory this way--just don't forget to also delete it later!

Another useful expansion is to retrieve the name of the running batch file itself. To support multi-processing, Vidsquish will randomize the batch process name for each thread. This means that %~n0 can also be used any time a random string is needed--for example, to avoid multiple threads writing data to the same filename at once.

One filename that shouldn't be randomized is the preview image. Though optional, displaying a preview image in the Vidsquish GUI is a good indicator to users that progress is being made and that their chosen options are being applied as expected. This is typically handled through FFMPEG using an expansion operator to write a file named "preview.jpg" to the game directory:

ffmpeg.exe -ss 00:00:01 -i "%1" -y -frames 1 "%~dp1preview.jpg"

This is an abbreviated example that provides no filters or modifications, which you should add yourself. However, note the key parameters used here: -ss to set the start time, -y to allow overwriting previous preview images, and -frames 1 to output only one image. These should always be used. Vidsquish will continuously monitor the path at %~dp1 for a file named "preview.jpg", and if found, automatically import and delete it.

When all processes are complete and temp data is cleaned up, all that remains is to signal Vidsquish that the process is done. This is handled through temporary flag files, but don't sweat the details: you can copy/paste this one!

:process_end
echo %1 >> "%~dpn0.vs2"


Every Vidsquish profile must end with this exact code. Vidsquish will continuously monitor for flag files, and once found, will remove files from the project to mark them as complete. The profile will then be executed again from the beginning for the next remaining file until all files are complete.

Article information

Added on

Edited on

Written by

LukeLC

0 comments