php-vfxapply/src/Application.php

170 lines
5.0 KiB
PHP

<?php
namespace VfxApply;
class Application
{
protected $plugins = [];
protected $presets = [];
public function readPlugins()
{
$iter = new \DirectoryIterator(
APP_ROOT."/plugins"
);
foreach ($iter as $dir) {
if (!$dir->isDir())
continue;
if (!file_exists($dir->getPathname()."/plugin.php"))
continue;
$this->loadPlugin($dir->getPathname());
}
}
public function readPresets()
{
$iter = new \RecursiveIteratorIterator(
new \RecursiveDirectoryIterator(
APP_ROOT."//presets"
));
foreach ($iter as $file) {
if ($file->isDir() || ($file->getExtension()!='yml'))
continue;
$this->loadPreset($file->getPathname());
}
}
private function loadPlugin($path)
{
$plugin = require_once $path."/plugin.php";
$plugin_class = get_class($plugin);
$plugin_ns = substr($plugin_class, 0, strrpos($plugin_class, '\\'));
spl_autoload_register(function ($cn) use ($plugin_ns, $path) {
if (strncmp($cn, $plugin_ns, strlen($plugin_ns))===0) {
$fn = $path . str_replace("\\",DIRECTORY_SEPARATOR,substr($cn,strlen($plugin_ns))) . ".php";
if (file_exists($fn)) {
require_once $fn;
}
}
});
$this->plugins[$plugin->getName()] = $plugin;
}
private function loadPreset($file)
{
try {
$preset = Preset::createFromFile($file);
$id = basename($file,".yml");
$this->presets[$id] = $preset;
} catch (\Exception $e) {
fprintf(STDERR, "Warning: The preset %s could not be loaded. %s\n", $file, $e->getMessage());
}
}
private function selectPreset()
{
$cmdl = "zenity --list --column=Group --column=Preset --column=Description ".
"--title=\"Apply VFX\" ".
"--width=400 --height=400 ".
"--text=\"Select the preset to apply\" ".
"--mid-search --print-column=2 ";
foreach ($this->presets as $id=>$preset) {
$cmdl.=sprintf(
"%s %s %s ",
escapeshellarg($preset->getGroup()),
escapeshellarg($id),
escapeshellarg($preset->getName())
);
}
exec($cmdl." 2>/dev/null", $output, $retval);
if ($retval == 0) {
$name = trim($output[0]);
return $this->presets[$name];
} else {
return false;
}
}
public function run()
{
$this->readPlugins();
$this->readPresets();
$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());
}
return 0;
}
$input = new Input();
if (!empty($opts['i'])) {
$input->setFilename($opts['i']);
} else {
if (!$input->selectFile()) {
return 1;
}
}
$input->analyze();
$output = new Output();
if (empty($opts['o'])) {
$output->setFilenameFromInput($input);
} else {
$output->setFilename($opts['o']);
}
$dur = $input->getVideoDuration();
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())) {
return 1;
}
} else {
if (!array_key_exists($opts['p'], $this->presets)) {
fprintf(STDERR, "Error: No such preset %s\n", $opts['p']);
}
$preset = $this->presets[$opts['p']];
}
$plugin_name = $preset->getPlugin();
$plugin = $this->plugins[$plugin_name];
$plugin->applyPreset($preset, $input, $output);
$msg = "Process completed.\n\nCreated ".$output->getFilename();
exec("notify-send -h int:transient:1 'Completed' ".escapeshellarg($msg));
}
}