Phar support, more plugins and presets
This commit is contained in:
parent
1938337bb0
commit
0ca1da06e7
1
.gitignore
vendored
1
.gitignore
vendored
@ -1 +1,2 @@
|
||||
/vendor
|
||||
composer.lock
|
||||
|
114
PRESETS.md
Normal file
114
PRESETS.md
Normal file
@ -0,0 +1,114 @@
|
||||
VfxApply Presets Documentation
|
||||
==============================
|
||||
|
||||
|
||||
## Preset keys
|
||||
|
||||
**Common keys**
|
||||
|
||||
| Key | Type | Description
|
||||
|------.------------|----------------|-------------------------------------------
|
||||
| `preset/name` | *String* | A description string for this preset
|
||||
| `preset/group` | *String|Null* | Logical grouping
|
||||
| `preset/plugin` | *String* | The id of the plugin this preset is for
|
||||
| `preset/props` | *Array* | Properties used by the plugin
|
||||
| `preset/params` | *Array|Null* | Parameters for tweaking
|
||||
|
||||
## Properties
|
||||
|
||||
**ffmpeg**
|
||||
|
||||
| Property | Type | Description
|
||||
|-------------------|----------------|-------------------------------------------
|
||||
| `filter` | *String* | The filter string, with optional param placeholders
|
||||
| `extra` | *String|Null* | Extra options to pass on the ffmpeg command line
|
||||
| `type` | *Enum|Null* | ffmpeg filter type; One of `complex` (default), `audio` or `video`
|
||||
|
||||
|
||||
**natron**
|
||||
|
||||
| Property | Type | Description
|
||||
|------.------------|--------------------|-------------------------------------------
|
||||
| `project` | *String* | Natron project file name
|
||||
| `input` | *String|Int|Null* | Extra options to pass on the ffmpeg command line
|
||||
| `output` | *String|Int|Null* | ffmpeg filter type; One of `complex`, `audio` or `video`
|
||||
| `framescale` | *Float* | Ratio of output frames to input files, 2.0=twice as many out as in=half speed
|
||||
|
||||
**executor**
|
||||
|
||||
| Property | Type | Description
|
||||
|------.------------|--------------------|-------------------------------------------
|
||||
| `set` | *Array* | Define variables
|
||||
| `script` | *Array* | Define commands
|
||||
| `set/%/value` | *String* | Set variable % to value.
|
||||
| `set/%/escape` | *Bool* | If true, the resulting vriable will be escaped
|
||||
| `script/%/info` | *String* | Info about what this step is doing
|
||||
| `script/%/exec` | *String* | Command to execute
|
||||
| `script/%/parse` | *Map* | Parse output from command, see docs for plugin
|
||||
|
||||
|
||||
## Parameters
|
||||
|
||||
All parameters must specify `label` and `type`. The remaining keys are depending on the
|
||||
type of parameter.
|
||||
|
||||
**float**
|
||||
|
||||
Float parameters need to specify `min`, `max`, `default` and optionally `step`.
|
||||
|
||||
|
||||
## Examples
|
||||
|
||||
### ffmpeg
|
||||
|
||||
preset:
|
||||
name: Normalize audio level
|
||||
group: ffmpeg/audio
|
||||
plugin: ffmpeg
|
||||
props:
|
||||
filter: "dynaudnorm=m={maxgain}:s={compress}"
|
||||
extra: "-c:v copy"
|
||||
type: complex
|
||||
params:
|
||||
compress: { label:"Compression factor", type:float, min:0.0, max:30.0, default:0.0 }
|
||||
maxgain: { label:"Max gain factor", type:float, min:0.0, max:100.0, default:10.0 }
|
||||
|
||||
### natron
|
||||
|
||||
preset:
|
||||
name: Apply a CCTV look to the video
|
||||
group: natron
|
||||
plugin: natron
|
||||
props:
|
||||
project: natron-cctv.ntp
|
||||
reader: Reader1
|
||||
writer: Writer1
|
||||
|
||||
### executor
|
||||
|
||||
preset:
|
||||
name: Stabilize video clip (two-pass)
|
||||
group: video
|
||||
plugin: executor
|
||||
props:
|
||||
set:
|
||||
inputtrf: { value:"{%uinput}.trf", escape:true }
|
||||
script:
|
||||
analyze:
|
||||
info: Getting stabilization vectors
|
||||
exec: "transcode -i {%input} -J stabilize"
|
||||
parse:
|
||||
from: 'stderr'
|
||||
regex: '/encoding frames \[0-([0-9]+?)\],\s+([0-9\.]+?) fps/'
|
||||
frame:1
|
||||
eta:2
|
||||
stabilize:
|
||||
info: Stabilizing video
|
||||
exec: "transcode -i {%input} -o {%output} -J transform -y xvid"
|
||||
parse:
|
||||
from: 'stderr'
|
||||
regex: '/encoding frames \[0-([0-9]+?)\],\s+([0-9\.]+?) fps/'
|
||||
frame:1
|
||||
eta:2
|
||||
cleanup:
|
||||
exec: "rm {%inputtrf}"
|
26
README.md
26
README.md
@ -9,11 +9,12 @@ Natron pipeline.
|
||||
|
||||
## Usage
|
||||
|
||||
vfxapply [-i <input>] [-o <output>|-O] [-p <preset>] [-c <key>=<value>]
|
||||
vfxapply [-i <input>] [-o <output>|-O] [-l] [-p <preset>] [-c <key>=<value>]
|
||||
|
||||
-i Set the input file (if omitted, a file picker will be displayed)
|
||||
-o Set the output file (if omitted, a file picker will be displayed)
|
||||
-O Automatically assign output filename based on input filename
|
||||
-O Automatically assign output filename
|
||||
-l List presets
|
||||
-p Select the preset to apply
|
||||
-c Specify parameters for the preset
|
||||
-b Batch mode, input parameter is a list of files
|
||||
@ -33,4 +34,25 @@ Examples:
|
||||
|
||||
### ffmpeg
|
||||
|
||||
This plugin allows for both video filters, audio filters and complex filters
|
||||
to f.ex. normalize audio or generate spectrograms of the audio channes
|
||||
|
||||
### natron
|
||||
|
||||
*This plugin is currently broken*
|
||||
|
||||
### executor
|
||||
|
||||
The executor plugin does as the name suggests; it executes one or more custom
|
||||
commands on the input file. The command output can be parsed using regular
|
||||
expressions to present the progress.
|
||||
|
||||
### melt
|
||||
|
||||
The melt plugin uses the MLT library, the same as is used by f.ex. Kdenlive
|
||||
to process the media.
|
||||
|
||||
### transcode
|
||||
|
||||
Transcode uses the transcode tool from transcoder.org. While powerful, it
|
||||
works best with AVI files.
|
||||
|
31
check-requirements
Executable file
31
check-requirements
Executable file
@ -0,0 +1,31 @@
|
||||
#!/bin/bash
|
||||
|
||||
function group {
|
||||
echo -e "\e[1m$1\e[0m"
|
||||
}
|
||||
function good {
|
||||
echo -e "[\e[92m ok \e[0m] \e[32m$1\e[0m"
|
||||
}
|
||||
function bad {
|
||||
echo -e "[\e[91mfail\e[0m] \e[31m$1\e[0m"
|
||||
}
|
||||
|
||||
function check {
|
||||
local NAME
|
||||
test -z "$2" || NAME="$2"
|
||||
test -z "$NAME" && NAME="$1"
|
||||
if [ -z "$(which $1)" ]; then
|
||||
bad "$NAME is missing"
|
||||
else
|
||||
good "Found $NAME at $(which $1)"
|
||||
fi
|
||||
}
|
||||
|
||||
group "Checking for zenity"
|
||||
check "zenity"
|
||||
check "dialog"
|
||||
|
||||
group "Checking tools"
|
||||
check "ffprobe"
|
||||
check "ffmpeg"
|
||||
check "transcode"
|
@ -1,23 +1,5 @@
|
||||
preset:
|
||||
name: Stabilize video clip
|
||||
group: video
|
||||
plugin: transcode
|
||||
props:
|
||||
set:
|
||||
inputtrf: { value:"{%uinput}.trf", escape:true }
|
||||
script:
|
||||
analyze:
|
||||
info: Getting stabilization vectors
|
||||
exec: "transcode -J stabilize -i {%input}"
|
||||
parse: { regex: '/^encoding frames [0-([0-9]+?)], ([0-9\.]+?) fps/', frame:1, eta:2 }
|
||||
stabilize:
|
||||
info Stabilizing video
|
||||
exec: "transcode -J transform -i {%input} -o {%output}"
|
||||
parse: { regex: '/^encoding frames [0-([0-9]+?)], ([0-9\.]+?) fps/', frame:1, eta:2 }
|
||||
cleanup:
|
||||
exec: "rm {%inputtrf}"
|
||||
|
||||
|
||||
Executor Plugin for VfxApply
|
||||
============================
|
||||
|
||||
## Scripts
|
||||
|
||||
@ -25,6 +7,16 @@ Each script command is named, and will be executed in order of appearance. Error
|
||||
will be reported and execution will stop if the exit code is non-zero, using
|
||||
the names as logical pointers.
|
||||
|
||||
props:
|
||||
set:
|
||||
<varname>: { value:<expr>, escape:<bool> }
|
||||
script:
|
||||
<step>:
|
||||
info: <string>
|
||||
exec: <commmand>
|
||||
parse: <parse-expr>
|
||||
|
||||
|
||||
### Command lines
|
||||
|
||||
Command line uses placeholders.
|
||||
@ -40,11 +32,35 @@ Any parameters will also be available:
|
||||
|
||||
And you can use `set` to assign stuff to variables.
|
||||
|
||||
|
||||
### Setting variables
|
||||
|
||||
Setting variables is done using the `set` prop. The core syntax is:
|
||||
|
||||
set:
|
||||
myvarname: { value:"MyValue" }
|
||||
|
||||
Additionally, `escape` can be used to flag that the value need to be
|
||||
escaped for the command line.
|
||||
|
||||
myvarname: { value:"SomeValue", escape:true }
|
||||
|
||||
Variables set this way can be used for the command line, and the same
|
||||
expressions can be used to define vars:
|
||||
|
||||
set:
|
||||
tempfile: { value:"{%uinput}.tmp", escape:true }
|
||||
script:
|
||||
first:
|
||||
exec "first --temp-file {%tempfile}"
|
||||
|
||||
|
||||
### Parsing output
|
||||
|
||||
To parse the output, add a `parse` key to the command block.
|
||||
|
||||
parse:
|
||||
regex: <- expression
|
||||
from: <- stream for comparison (stdout or stderr)
|
||||
frame: <- index of frame number, or leave out
|
||||
fps: <- index of frames per second, or leave out
|
||||
|
24
plugins/melt/plugin.php
Normal file
24
plugins/melt/plugin.php
Normal file
@ -0,0 +1,24 @@
|
||||
<?php
|
||||
|
||||
namespace VfxApply\Plugin\Melt;
|
||||
|
||||
use VfxApply\Plugin;
|
||||
use VfxApply\Input;
|
||||
use VfxApply\Output;
|
||||
use VfxApply\Preset;
|
||||
|
||||
class MeltPlugin extends Plugin
|
||||
{
|
||||
public function getName()
|
||||
{
|
||||
return "melt";
|
||||
}
|
||||
|
||||
public function applyPreset(Preset $preset, Input $input, Output $output)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return new MeltPlugin();
|
24
plugins/transcode/plugin.php
Normal file
24
plugins/transcode/plugin.php
Normal file
@ -0,0 +1,24 @@
|
||||
<?php
|
||||
|
||||
namespace VfxApply\Plugin\Transcode;
|
||||
|
||||
use VfxApply\Plugin;
|
||||
use VfxApply\Input;
|
||||
use VfxApply\Output;
|
||||
use VfxApply\Preset;
|
||||
|
||||
class TranscodePlugin extends Plugin
|
||||
{
|
||||
public function getName()
|
||||
{
|
||||
return "transcode";
|
||||
}
|
||||
|
||||
public function applyPreset(Preset $preset, Input $input, Output $output)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return new TranscodePlugin();
|
18
presets/executor/executor-vidstab-ffmpeg.yml
Normal file
18
presets/executor/executor-vidstab-ffmpeg.yml
Normal file
@ -0,0 +1,18 @@
|
||||
preset:
|
||||
name: Stabilize video clip (two-pass, ffmpeg)
|
||||
group: video
|
||||
plugin: executor
|
||||
props:
|
||||
set:
|
||||
inputtrf: { value:"{%uinput}.trf", escape:true }
|
||||
script:
|
||||
analyze:
|
||||
info: Getting stabilization vectors
|
||||
exec: "ffmpeg -i {%input} -vf vidstabdetect=stepsize=6:shakiness=8:accuracy=9:result={%inputtrf} -f null -"
|
||||
parse: { from: 'stderr', regex: '/^frame=[\s]*([0-9]+)\s/', frame:1 }
|
||||
stabilize:
|
||||
info: Stabilizing video
|
||||
exec: "ffmpeg -i {%input} -vf vidstabtransform=input={%inputtrf}:zoom=1:smoothing=30,unsharp=5:5:0.8:3:3:0.4 -vcodec libx264 -preset slow -tune film -crf 18 -acodec copy {%output}"
|
||||
parse: { from: 'stderr', regex: '/^frame=[\s]*([0-9]+)\s/', frame:1 }
|
||||
cleanup:
|
||||
exec: "rm {%inputtrf}"
|
@ -2,6 +2,10 @@ preset:
|
||||
name: Stabilize video clip (two-pass)
|
||||
group: video
|
||||
plugin: executor
|
||||
info: >
|
||||
This preset uses 'transcode' to stabilize the video clip. As transcode has limited
|
||||
support for other output containers than AVI, the resulting file will be an .AVI
|
||||
file.
|
||||
props:
|
||||
set:
|
||||
inputtrf: { value:"{%uinput}.trf", escape:true }
|
||||
@ -17,18 +21,3 @@ preset:
|
||||
parse: { from: 'stderr', regex: '/encoding frames \[0-([0-9]+?)\],\s+([0-9\.]+?) fps/', frame:1, eta:2 }
|
||||
cleanup:
|
||||
exec: "ls {%inputtrf}"
|
||||
#!/bin/bash
|
||||
|
||||
#INPUT="$1"
|
||||
#OUTPUT="$1.stab.avi"
|
||||
#CODEC="-y xvid"
|
||||
|
||||
#if [ -e "$INPUT.trf" ]; then
|
||||
# echo "Cache found, not re-calling stabilize..."
|
||||
#else
|
||||
# Start the deshake process
|
||||
# transcode -J stabilize -i $INPUT || transcode -J stabilize --mplayer_probe -i $INPUT
|
||||
#fi
|
||||
|
||||
# Now, stabilize the video
|
||||
#transcode -J transform -i $INPUT $CODEC -o $OUTPUT
|
||||
|
9
presets/melt/melt-grayscale.yml
Normal file
9
presets/melt/melt-grayscale.yml
Normal file
@ -0,0 +1,9 @@
|
||||
preset:
|
||||
name: Turn the video into grayscale
|
||||
group: melt
|
||||
plugin: melt
|
||||
props:
|
||||
filters:
|
||||
- { type: greyscale, in: ~, out: ~ }
|
||||
|
||||
# melt test.mp4 -filter greyscale -consumer avformat:output.avi acodec=libmp3lame vcodec=libx264
|
6
presets/transcode/transcode-deshake.yml
Normal file
6
presets/transcode/transcode-deshake.yml
Normal file
@ -0,0 +1,6 @@
|
||||
preset:
|
||||
name: Deshake video clip (single-pass)
|
||||
group: video
|
||||
plugin: transcode
|
||||
props:
|
||||
filter: deshake
|
@ -12,7 +12,7 @@ class Application
|
||||
public function readPlugins()
|
||||
{
|
||||
$iter = new \DirectoryIterator(
|
||||
__DIR__."/../plugins"
|
||||
APP_ROOT."/plugins"
|
||||
);
|
||||
foreach ($iter as $dir) {
|
||||
if (!$dir->isDir())
|
||||
@ -27,7 +27,7 @@ class Application
|
||||
{
|
||||
$iter = new \RecursiveIteratorIterator(
|
||||
new \RecursiveDirectoryIterator(
|
||||
__DIR__."/../presets"
|
||||
APP_ROOT."//presets"
|
||||
));
|
||||
foreach ($iter as $file) {
|
||||
if ($file->isDir() || ($file->getExtension()!='yml'))
|
||||
@ -83,8 +83,30 @@ class Application
|
||||
$this->readPlugins();
|
||||
$this->readPresets();
|
||||
|
||||
$opts = getopt("i:o:p:l");
|
||||
$opts = getopt("hi:o:p:l");
|
||||
|
||||
if (array_key_exists('h',$opts)) {
|
||||
printf("Usage:\n");
|
||||
foreach([
|
||||
"%s -h",
|
||||
"%s -l",
|
||||
"%s [-i FILE] [-o FILE] [-p PRESET]"
|
||||
] as $example)
|
||||
printf(" ".$example."\n", "vfxapply");
|
||||
printf("Options:\n");
|
||||
foreach ([
|
||||
"-h" => "Show this help",
|
||||
"-i FILE" => "Input filename",
|
||||
"-o FILE" => "Output filename",
|
||||
"-p PRESET" => "Select preset",
|
||||
"-l" => "List presets",
|
||||
] as $opt=>$info)
|
||||
printf(" %-10s %s\n", $opt, $info);
|
||||
|
||||
printf("\n");
|
||||
|
||||
return 0;
|
||||
}
|
||||
if (array_key_exists('l',$opts)) {
|
||||
foreach ($this->presets as $name=>$preset) {
|
||||
printf("%s: %s\n", $name, $preset->getName());
|
||||
@ -110,8 +132,8 @@ class Application
|
||||
}
|
||||
|
||||
$dur = $input->getVideoDuration();
|
||||
printf("Input: %s %.2fs (%d frames)\n", $input->getFilename(), $dur->seconds, $dur->frames);
|
||||
printf("Output: %s\n", $output->getFilename());
|
||||
printf("Input: \e[1m%s\e[0m %.2fs (%d frames)\n", $input->getFilename(), $dur->seconds, $dur->frames);
|
||||
printf("Output: \e[1m%s\e[0m\n", $output->getFilename());
|
||||
|
||||
if (empty($opts['p'])) {
|
||||
if (!($preset = $this->selectPreset())) {
|
||||
|
11
src/app.php
11
src/app.php
@ -11,5 +11,14 @@ define("DIALOG_SAVEFILE", "savefile");
|
||||
require_once __DIR__."/../vendor/autoload.php";
|
||||
|
||||
use VfxApply\Application;
|
||||
|
||||
// Find the actual root, follow links, and strip the bin part if local
|
||||
if (!($script = dirname(@readlink($_SERVER['SCRIPT_NAME']))))
|
||||
$script = dirname($_SERVER['SCRIPT_NAME']);
|
||||
if (basename($script)=='bin')
|
||||
$script = dirname($script);
|
||||
|
||||
define("APP_ROOT", $script);
|
||||
|
||||
$app = new Application();
|
||||
$app->run();
|
||||
$app->run();
|
||||
|
Loading…
Reference in New Issue
Block a user