Post-Processing
The post-processing gives you the possibility to execute different actions after a recording has finished. You can use that to convert
the files to another format, create preview images, rename / move the file etc.
Available Steps
- create a copy - Creates a copy of the original recording. All following post-processing steps are executed on the copy, not on the
original recording. This means, that the post-processing can be rerun in case a step failed, because the original recording is still
available.
- rename - Renames the recording with the help of variables. See Variables
- move - Moves the recording with the help of variables. See Variables
- remux / transcode - Executes FFmpeg with the given arguments on the recording. This step can be used to convert a recording to
MP4 or re-encode it to a different format / resolution. The input and output file don't have to be defined. If the step was successful
the input file gets deleted.
- execute script - Executes a script or program with the given arguments. You can use the variables to define what
to pass over to the script.
- delete too short - Delete a recording, if it is shorter than the given duration. This post-processing step has replaced the
setting, which was available in the post-processing category before
- delete original - This is a companion step for "create a copy". If you use the copy step and all other steps are successful,
you probably want to get rid of the original file and just keep the result of the post-processing. That's what this step does.
- remove recording, but keep the files - Removes the recording from the recordings list, but keeps the files untouched.
- create contactsheet - create a contact sheet with preview images of the recording
- webhook - send a message via a webhook, e.g. Telegram
Planned for future releases
- create timeline thumbnails - create a small thumbnail for every second or every few seconds, which can be used to very fast
scan through a recording
How to configure the server to do post-processing
There is currently no user interface to configure the post-processing for the server. It has to be added manually to the server config.
I suggest to start the app and configure the post-processing steps in the settings. Afterwards you close the app and copy the
post-processing section from the settings.json to your server.json file. To find out, where these files are on your system, read
Configuration File.
The part you have to copy is
postProcessors: [
...
],
Variables
Available variables:
- ${modelName} - the name of the recorded model
- ${modelDisplayName} - the name of the recorded model, which is shown on the webpage. Might be the same as
${modelName}
- ${modelGroupName} - name of the model group, if the model is part of a group
- ${modelGroupId} - the unique ID of the model group, if the model is part of a group
- ${siteName} - the name of the cam site, the model streams on
- ${contactSheet} - the full path to the contactsheet if one exists
- ${fileSuffix} - the file extension of the recording. E.g. ts or mp4. In case of a standard server recording,
this will be empty
- ${epochSecond} - timestamp of the recording in seconds since 1970-01-01 (unixtime)
- ${modelNotes} - sanitized model notes. The following characters are replaced by an underscore:
\, /, ', " and space
- ${recordingNotes} - sanitized recording notes. The following characters are replaced by an underscore:
\, /, ', " and space. Useful for the download of recordings from the server.
- ${recordingsDir} - the base directory of all recordings. Same as Recordings Directory in the Recorder settings
section.
- ${absolutePath} - the absolute path in the filesystem to the recording file (or the recording directory in case of
a server recording)
- ${absoluteParentPath} - the absolute path to the parent directory of the recording in the filesystem (or the
recording dir in case of a server recording)
- ${utcDateTime} and ${localDateTime} - the timestamp of the recording in the UTC or your local timezone
Functions
- $base64 - base64 encode a string/file -
$base64( "Hello World" ) becomes SGVsbG8gV29ybGQ=
- $trim - removes all leading and trailing space -
$trim( hello world ) becomes hello world
- $upper - converts all of the characters to upper case -
$upper(hello world) becomes HELLO WORLD
- $lower - converts all of the characters to lower case -
$lower(hElLo WORLD) becomes hello world
- $capitalize - capitalizes words changing the first character to upper case -
$capitalize(hElLo WorLD) becomes HElLo WorLD
- $sanitize - removes problematic characters -
$sanitize(hEl'Lo / WO"RLD) becomes hEl_Lo___WO_RLD. The following characters are replaced by an
underscore:
\, /, ', " and space
- $orElse - provide an alternative in case a variable is not set -
$orElse(${variable},someValue) - becomes ${variable}, if it is set or someValue, if
${variable} is not set
- $format - formats a date, can be used with a pattern or without.
Examples:
$format(${localDateTime}) - becomes something like 2023-02-26_12-23-15
$format(${localDateTime},yyyyMMdd-HHmmss) would lead to 20200928-173605
| Symbol | Meaning | Presentation | Examples |
| G | era | text | AD; Anno Domini; A |
|---|
| u | year | year | 2004; 04 |
|---|
| y | year-of-era | year | 2004; 04 |
|---|
| D | day-of-year | number | 189 |
|---|
| M/L | month-of-year | number/text | 7; 07; Jul; July; J |
|---|
| d | day-of-month | number | 10 |
|---|
| g | modified-julian-day | number | 2451334 |
|---|
| Q/q | quarter-of-year | number/text | 3; 03; Q3; 3rd quarter |
|---|
| Y | week-based-year | year | 1996; 96 |
|---|
| w | week-of-week-based-year | number | 27 |
|---|
| W | week-of-month | number | 4 |
|---|
| E | day-of-week | text | Tue; Tuesday; T |
|---|
| e/c | localized day-of-week | number/text | 2; 02; Tue; Tuesday; T |
|---|
| F | day-of-week-in-month | number | 3 |
|---|
| a | am-pm-of-day | text | PM |
|---|
| h | clock-hour-of-am-pm (1-12) | number | 12 |
|---|
| K | hour-of-am-pm (0-11) | number | 0 |
|---|
| k | clock-hour-of-day (1-24) | number | 24 |
|---|
| H | hour-of-day (0-23) | number | 0 |
|---|
| m | minute-of-hour | number | 30 |
|---|
| s | second-of-minute | number | 55 |
|---|
| S | fraction-of-second | fraction | 978 |
|---|
| A | milli-of-day | number | 1234 |
|---|
| n | nano-of-second | number | 987654321 |
|---|
| N | nano-of-day | number | 1234000000 |
|---|
| V | time-zone ID | zone-id | America/Los_Angeles; Z; -08:30 |
|---|
| v | generic time-zone name | zone-name | Pacific Time; PT |
|---|
| z | time-zone name | zone-name | Pacific Standard Time; PST |
|---|
| O | localized zone-offset | offset-O | GMT+8; GMT+08:00; UTC-08:00 |
|---|
| X | zone-offset 'Z' for zero | offset-X | Z; -08; -0830; -08:30; -083015; -08:30:15 |
|---|
| x | zone-offset | offset-x | +0000; -08; -0830; -08:30; -083015; -08:30:15 |
|---|
| Z | zone-offset | offset-Z | +0000; -0800; -08:00 |
|---|
| p | pad next | pad modifier | 1 |
|---|
| ' | escape for text | delimiter | |
|---|
| '' | single quote | literal | ' |
For more information see: DateTimeFormatter
Full Example:
$orElse(${modelGroupName},$sanitize(${modelName}))_$format(${localDateTime})_${recordingNotes}
Webhook examples:
Telegram:
URL: https://api.telegram.org/bot$TO:KEN/sendMessage
Headers:
Method: POST
Data: {"chat_id": <CHAT_ID>, "text": "${modelName} - finished"}
Signal:
URL: http://<IP>:<port>/v2/send
Headers: "Content-Type: application/json"
Method: POST
Data: {"message": "${modelName} - finished", "number": "+<PHONE_NUMBER>", "recipients": [ "+<PHONE_NUMBER>" ]}