From a8b1af848a08724753576d161cb8573aa9ebdb4d Mon Sep 17 00:00:00 2001 From: 0xb00bface <0xboobface@gmail.com> Date: Mon, 28 Sep 2020 17:46:11 +0200 Subject: [PATCH] Add documentation for the post-processing steps --- .../java/ctbrec/ui/settings/SettingsTab.java | 15 +- .../resources/html/docs/PostProcessing.md | 157 ++++++++++-------- 2 files changed, 106 insertions(+), 66 deletions(-) diff --git a/client/src/main/java/ctbrec/ui/settings/SettingsTab.java b/client/src/main/java/ctbrec/ui/settings/SettingsTab.java index 02cb7e2e..a7672c4f 100644 --- a/client/src/main/java/ctbrec/ui/settings/SettingsTab.java +++ b/client/src/main/java/ctbrec/ui/settings/SettingsTab.java @@ -20,6 +20,7 @@ import ctbrec.Settings.DirectoryStructure; import ctbrec.Settings.ProxyType; import ctbrec.recorder.Recorder; import ctbrec.sites.Site; +import ctbrec.ui.DesktopIntegration; import ctbrec.ui.SiteUI; import ctbrec.ui.SiteUiFactory; import ctbrec.ui.controls.range.DiscreteRange; @@ -44,6 +45,7 @@ import javafx.beans.property.SimpleStringProperty; import javafx.beans.value.ObservableValue; import javafx.collections.FXCollections; import javafx.geometry.Insets; +import javafx.scene.control.Button; import javafx.scene.control.Tab; import javafx.scene.control.TextInputDialog; import javafx.scene.layout.GridPane; @@ -100,6 +102,7 @@ public class SettingsTab extends Tab implements TabSelectionListener { private SimpleIntegerProperty postProcessingThreads; private IgnoreList ignoreList; private PostProcessingStepPanel postProcessingStepPanel; + private Button variablesHelpButton; public SettingsTab(List sites, Recorder recorder) { this.sites = sites; @@ -152,6 +155,7 @@ public class SettingsTab extends Tab implements TabSelectionListener { private void createGui() { postProcessingStepPanel = new PostProcessingStepPanel(config); + variablesHelpButton = createHelpButton("Variables", "http://localhost:5689/docs/PostProcessing.md#variables"); ignoreList = new IgnoreList(sites); List siteCategories = new ArrayList<>(); for (Site site : sites) { @@ -199,6 +203,7 @@ public class SettingsTab extends Tab implements TabSelectionListener { Setting.of("Port", port), Setting.of("Path", path, "Leave empty, if you didn't change the servletContext in the server config"), Setting.of("Download Filename", downloadFilename, "File name pattern for downloads"), + Setting.of("", variablesHelpButton), Setting.of("Require authentication", requireAuthentication), Setting.of("Use Secure Communication (TLS)", transportLayerSecurity) ) @@ -206,7 +211,8 @@ public class SettingsTab extends Tab implements TabSelectionListener { Category.of("Post-Processing", Group.of("Post-Processing", Setting.of("Threads", postProcessingThreads), - Setting.of("Steps", postProcessingStepPanel) + Setting.of("Steps", postProcessingStepPanel), + Setting.of("", createHelpButton("Post-Processing Help", "http://localhost:5689/docs/PostProcessing.md")) ) ), Category.of("Events & Actions", new ActionSettingsPanel(recorder)), @@ -246,6 +252,13 @@ public class SettingsTab extends Tab implements TabSelectionListener { prefs.getSetting("concurrentRecordings").ifPresent(s -> bindEnabledProperty(s, recordLocal.not())); prefs.getSetting("downloadFilename").ifPresent(s -> bindEnabledProperty(s, recordLocal)); postProcessingStepPanel.disableProperty().bind(recordLocal.not()); + variablesHelpButton.disableProperty().bind(recordLocal); + } + + private Button createHelpButton(String text, String url) { + Button postProcessingHelpButton = new Button(text); + postProcessingHelpButton.setOnAction(e -> DesktopIntegration.open(url)); + return postProcessingHelpButton; } private void bindEnabledProperty(Setting s, BooleanExpression bindTo) { diff --git a/client/src/main/resources/html/docs/PostProcessing.md b/client/src/main/resources/html/docs/PostProcessing.md index 976c754a..5d13fecd 100644 --- a/client/src/main/resources/html/docs/PostProcessing.md +++ b/client/src/main/resources/html/docs/PostProcessing.md @@ -1,79 +1,106 @@ #### Post-Processing -The post-processing gives you the possibility to run any script / program after a recording has finished. You can use that to convert +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. -There are example scripts included in the distribution zip (`pp.bat`, `pp.ps1`, `pp.sh`). See also the comments in those files. -##### Local Recording -If you are using the local recording mode, you can set the post-processing script / program on the settings tab under *Recorder* -> *Post-Processing*. -ctbrec will call the selected script after the recording has finished with the following parameters: +##### 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](#variables) +- **move** - Moves the recording with the help of variables. See [Variables](#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](#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. -1. directory (absolute path) -2. file (absolute path) -3. model name -4. site name -5. unixtime (seconds since 1/1/1970 00:00) +#### Planned for future releases +- **call a webhook** - call a URL once a recording is finished +- **create contactsheet** - create a contact sheet with preview images of the recording +- **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 -##### Remote Recording (server) -If you are running the server and want to run a post-processing script, you have to edit the [configuration file](/docs/ConfigurationFile.md). Just set the absolute path to an executable script / program for the setting **postProcessing**. Since the recordings look a bit different for the server, the parameters, which are passed to the script are a bit different, too: +#### Variables -1. parent directory (absolute path) -2. directory of the recording (absolute path) - this directory contains the segments and the playlist -3. model name -4. site name -5. unixtime (seconds since 1/1/1970 00:00) + -##### Example Scripts +- **${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} +- **${modelSanitizedName}** - sanitized name of the model. The following characters are replaced by an underscore: + \\, /, ', " and space +- **${siteName}** - the name of the cam site, the model streams on +- **${siteSanitizedName}** - sanitized name of the site. The following characters are replaced by an underscore: + \\, /, ', " and space +- **${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. If no + pattern is given, the default ```yyyy-MM-dd_HH-mm-ss``` is used. You can also define your own pattern using the following + symbols. For example ```${localDateTime(yyyyMMdd-HHmmss)}``` would lead to 20200928-173605. + + + + + + + + + + + + -Server script by @uo0Evx99@mastodon.cloud used on a Raspberry Pi 3 B+ to convert recordigns to mp4 files: -``` -#!/bin/bash + + + + + + + -# -#Explanation of the code: It first takes all the .ts files (because sadly the server -#doesnt save the video in 1 big file instead) and creates one big .ts file in the same -#folder called "all". -# -#Then it uses ffmpeg to re-encode the .ts file to .mp4 while just copying the audio -#and video codec to reduce the encoding time. It also uses the -movflags faststart so -#the video can be played back instantly when viewing online (e.g. with Plex) -#That re-encoded file is being stored in the folder /home/pi/hdd/plex/"MODEL NAME"/ -#with the name "CURRENT TIME"-"MODEL NAME".mp4 -# -#Then it deletes the folder in which all the .ts files were, because we dont need -#those anymore as we have our .mp4 file re-encoded already and ready to use/stream. -# -#This script has been used on a Raspberry Pi 3 B+ -# + + + + -# $1 directory (absolute path) -# $2 file (absolute path) -# $3 model name -# $4 site name -# $5 unixtime + + + + + + + -# format unixtime to human readable -TIME=$(date --date="@$5" +%H:%M_%d.%m.%Y) + + + + + + + -cat $2/*.ts > "$2/all.ts" && ffmpeg -i "$2/all.ts" -acodec copy -vcodec copy -movflags faststart "/home/pi/hdd/plex/$3/$TIME-$3.mp4" && rm -r "$2" -``` + + + + +
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 '
-Windows script by @electrotek@mastodon.cloud. -Automatically converts .ts files into mkv after recording ended, factors in multiple/split files. Assumes mkvtoolnix installed in path stated -``` -@echo off - -set directory=%1 -set file=%2 -set model=%3 -set site=%4 -set unixtime=%5 - -FOR %%f in (%directory%\*.ts) do ( - "C:\Program Files\MKVToolNix\mkvmerge.exe" -o "%directory%\%%~nf.mkv" --title "%model%" "%directory%\%%~nf.ts" - del "%directory%\%%~nf.ts" -) -``` - -##### Video Tutorials - \ No newline at end of file + + For more information see: [DateTimeFormatter](https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/time/format/DateTimeFormatter.html) \ No newline at end of file