forked from mia/Aegisub
vapoursynth: Add configurable default script
This default script will be executed to load any file whose file name extension is not .py or .vpy . The gui code for setting the default script is still a bit wonky as it doesn't fit the rest of the preferences pages nicely, but it works for now.
This commit is contained in:
parent
ff43f3d601
commit
febce3ecdc
10 changed files with 121 additions and 5 deletions
|
@ -28,13 +28,13 @@
|
|||
|
||||
#include <libaegisub/access.h>
|
||||
#include <libaegisub/format.h>
|
||||
#include <libaegisub/fs.h>
|
||||
#include <libaegisub/path.h>
|
||||
#include <libaegisub/make_unique.h>
|
||||
|
||||
#include <mutex>
|
||||
|
||||
#include "vapoursynth_wrap.h"
|
||||
#include "vapoursynth_common.h"
|
||||
#include "VSScript4.h"
|
||||
|
||||
namespace {
|
||||
|
@ -62,7 +62,7 @@ VapoursynthAudioProvider::VapoursynthAudioProvider(agi::fs::path const& filename
|
|||
throw VapoursynthError("Error creating script API");
|
||||
}
|
||||
vs.GetScriptAPI()->evalSetWorkingDir(script, 1);
|
||||
if (vs.GetScriptAPI()->evaluateFile(script, filename.string().c_str())) {
|
||||
if (OpenScriptOrVideo(vs.GetScriptAPI(), script, filename, OPT_GET("Provider/Audio/VapourSynth/Default Script")->GetString())) {
|
||||
std::string msg = agi::format("Error executing VapourSynth script: %s", vs.GetScriptAPI()->getError(script));
|
||||
vs.GetScriptAPI()->freeScript(script);
|
||||
throw VapoursynthError(msg);
|
||||
|
|
|
@ -336,6 +336,9 @@
|
|||
"BestSource": {
|
||||
"Max Cache Size" : 100,
|
||||
"Aegisub Cache" : true
|
||||
},
|
||||
"VapourSynth" : {
|
||||
"Default Script" : "import vapoursynth as vs\nvs.core.bas.Source(source=filename).set_output()"
|
||||
}
|
||||
},
|
||||
"Avisynth" : {
|
||||
|
@ -362,6 +365,9 @@
|
|||
"Max Cache Size" : 1024,
|
||||
"Threads" : 0,
|
||||
"Seek Preroll" : 12
|
||||
},
|
||||
"VapourSynth" : {
|
||||
"Default Script" : "import vapoursynth as vs\nvs.core.lsmas.LWLibavSource(source=filename).set_output()"
|
||||
}
|
||||
}
|
||||
},
|
||||
|
|
|
@ -336,6 +336,9 @@
|
|||
"BestSource": {
|
||||
"Max Cache Size" : 100,
|
||||
"Aegisub Cache" : true
|
||||
},
|
||||
"VapourSynth" : {
|
||||
"Default Script" : "import vapoursynth as vs\nvs.core.bas.Source(source=filename).set_output()"
|
||||
}
|
||||
},
|
||||
"Avisynth" : {
|
||||
|
@ -362,6 +365,9 @@
|
|||
"Max Cache Size" : 1024,
|
||||
"Threads" : 0,
|
||||
"Seek Preroll" : 12
|
||||
},
|
||||
"VapourSynth" : {
|
||||
"Default Script" : "import vapoursynth as vs\nvs.core.lsmas.LWLibavSource(source=filename).set_output()"
|
||||
}
|
||||
}
|
||||
},
|
||||
|
|
|
@ -240,6 +240,7 @@ opt_src = [
|
|||
'video_provider_bestsource.cpp',
|
||||
'bestsource_common.cpp']],
|
||||
['VapourSynth', ['vapoursynth_wrap.cpp',
|
||||
'vapoursynth_common.cpp',
|
||||
'audio_provider_vs.cpp',
|
||||
'video_provider_vs.cpp']],
|
||||
|
||||
|
|
|
@ -469,6 +469,32 @@ void Advanced_Video(wxTreebook *book, Preferences *parent) {
|
|||
p->SetSizerAndFit(p->sizer);
|
||||
}
|
||||
|
||||
void VapourSynth(wxTreebook *book, Preferences *parent) {
|
||||
#ifdef WITH_VAPOURSYNTH
|
||||
auto p = new OptionPage(book, parent, _("VapourSynth"), OptionPage::PAGE_SUB);
|
||||
auto video = p->PageSizer(_("Default Video Script"));
|
||||
|
||||
auto vhint = new wxStaticText(p, wxID_ANY, _("This script will be executed to load video files that aren't\nVapourSynth scripts (i.e. end in .py or .vpy).\nThe filename variable stores the path to the file."));
|
||||
p->sizer->Fit(p);
|
||||
vhint->Wrap(400);
|
||||
video->Add(vhint, 0, wxALL, 5);
|
||||
video->AddSpacer(16);
|
||||
|
||||
p->OptionAddMultiline(video, "Provider/Video/VapourSynth/Default Script");
|
||||
|
||||
auto audio = p->PageSizer(_("Default Audio Script"));
|
||||
auto ahint = new wxStaticText(p, wxID_ANY, _("This script will be executed to load audio files that aren't\nVapourSynth scripts (i.e. end in .py or .vpy).\nThe filename variable stores the path to the file."));
|
||||
p->sizer->Fit(p);
|
||||
ahint->Wrap(400);
|
||||
audio->Add(ahint, 0, wxALL, 5);
|
||||
audio->AddSpacer(16);
|
||||
|
||||
p->OptionAddMultiline(audio, "Provider/Audio/VapourSynth/Default Script");
|
||||
|
||||
p->SetSizerAndFit(p->sizer);
|
||||
#endif
|
||||
}
|
||||
|
||||
/// wxDataViewIconTextRenderer with command name autocompletion
|
||||
class CommandRenderer final : public wxDataViewCustomRenderer {
|
||||
wxArrayString autocomplete;
|
||||
|
@ -724,6 +750,7 @@ Preferences::Preferences(wxWindow *parent): wxDialog(parent, -1, _("Preferences"
|
|||
Advanced(book, this);
|
||||
Advanced_Audio(book, this);
|
||||
Advanced_Video(book, this);
|
||||
VapourSynth(book, this);
|
||||
|
||||
book->Fit();
|
||||
|
||||
|
|
|
@ -156,6 +156,20 @@ wxControl *OptionPage::OptionAdd(wxFlexGridSizer *flex, const wxString &name, co
|
|||
}
|
||||
}
|
||||
|
||||
wxControl *OptionPage::OptionAddMultiline(wxSizer *sizer, const char *opt_name) {
|
||||
parent->AddChangeableOption(opt_name);
|
||||
const auto opt = OPT_GET(opt_name);
|
||||
|
||||
if (opt->GetType() != agi::OptionType::String) {
|
||||
throw agi::InternalError("Unsupported type for multiline option");
|
||||
}
|
||||
|
||||
auto text = new wxTextCtrl(this, -1, to_wx(opt->GetString()), wxDefaultPosition, wxSize(-1, 200), wxTE_MULTILINE);
|
||||
text->Bind(wxEVT_TEXT, StringUpdater(opt_name, parent));
|
||||
sizer->Add(text, wxSizerFlags().Expand());
|
||||
return text;
|
||||
}
|
||||
|
||||
void OptionPage::OptionChoice(wxFlexGridSizer *flex, const wxString &name, const wxArrayString &choices, const char *opt_name) {
|
||||
parent->AddChangeableOption(opt_name);
|
||||
const auto opt = OPT_GET(opt_name);
|
||||
|
|
|
@ -43,6 +43,7 @@ public:
|
|||
|
||||
void CellSkip(wxFlexGridSizer *flex);
|
||||
wxControl *OptionAdd(wxFlexGridSizer *flex, const wxString &name, const char *opt_name, double min=0, double max=INT_MAX, double inc=1);
|
||||
wxControl *OptionAddMultiline(wxSizer *flex, const char *opt_name);
|
||||
void OptionChoice(wxFlexGridSizer *flex, const wxString &name, const wxArrayString &choices, const char *opt_name);
|
||||
void OptionBrowse(wxFlexGridSizer *flex, const wxString &name, const char *opt_name, wxControl *enabler = nullptr, bool do_enable = false);
|
||||
void OptionFont(wxSizer *sizer, std::string opt_prefix);
|
||||
|
|
37
src/vapoursynth_common.cpp
Normal file
37
src/vapoursynth_common.cpp
Normal file
|
@ -0,0 +1,37 @@
|
|||
// Copyright (c) 2022, arch1t3cht <arch1t3cht@gmail.com>
|
||||
//
|
||||
// Permission to use, copy, modify, and distribute this software for any
|
||||
// purpose with or without fee is hereby granted, provided that the above
|
||||
// copyright notice and this permission notice appear in all copies.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
//
|
||||
// Aegisub Project http://www.aegisub.org/
|
||||
|
||||
#ifdef WITH_VAPOURSYNTH
|
||||
#include "vapoursynth_common.h"
|
||||
|
||||
#include "options.h"
|
||||
#include <libaegisub/fs.h>
|
||||
|
||||
#include <boost/algorithm/string/replace.hpp>
|
||||
|
||||
int OpenScriptOrVideo(const VSSCRIPTAPI *api, VSScript *script, agi::fs::path const& filename, std::string default_script) {
|
||||
if (agi::fs::HasExtension(filename, "py") || agi::fs::HasExtension(filename, "vpy")) {
|
||||
return api->evaluateFile(script, filename.string().c_str());
|
||||
} else {
|
||||
std::string fname = filename.string();
|
||||
boost::replace_all(fname, "\\", "\\\\");
|
||||
boost::replace_all(fname, "'", "\\'");
|
||||
std::string vscript = "filename = '" + fname + "'\n" + default_script;
|
||||
return api->evaluateBuffer(script, vscript.c_str(), "aegisub");
|
||||
}
|
||||
}
|
||||
|
||||
#endif // WITH_VAPOURSYNTH
|
24
src/vapoursynth_common.h
Normal file
24
src/vapoursynth_common.h
Normal file
|
@ -0,0 +1,24 @@
|
|||
// Copyright (c) 2022, arch1t3cht <arch1t3cht@gmail.com>
|
||||
//
|
||||
// Permission to use, copy, modify, and distribute this software for any
|
||||
// purpose with or without fee is hereby granted, provided that the above
|
||||
// copyright notice and this permission notice appear in all copies.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
//
|
||||
// Aegisub Project http://www.aegisub.org/
|
||||
|
||||
#ifdef WITH_VAPOURSYNTH
|
||||
#include "VSScript4.h"
|
||||
|
||||
#include <libaegisub/fs_fwd.h>
|
||||
|
||||
int OpenScriptOrVideo(const VSSCRIPTAPI *api, VSScript *script, agi::fs::path const& filename, std::string default_script);
|
||||
|
||||
#endif // WITH_VAPOURSYNTH
|
|
@ -22,13 +22,13 @@
|
|||
|
||||
#include <libaegisub/access.h>
|
||||
#include <libaegisub/format.h>
|
||||
#include <libaegisub/fs.h>
|
||||
#include <libaegisub/path.h>
|
||||
#include <libaegisub/make_unique.h>
|
||||
|
||||
#include <mutex>
|
||||
|
||||
#include "vapoursynth_wrap.h"
|
||||
#include "vapoursynth_common.h"
|
||||
#include "VSScript4.h"
|
||||
#include "VSHelper4.h"
|
||||
#include "VSConstants4.h"
|
||||
|
@ -113,7 +113,7 @@ VapoursynthVideoProvider::VapoursynthVideoProvider(agi::fs::path const& filename
|
|||
throw VapoursynthError("Error creating script API");
|
||||
}
|
||||
vs.GetScriptAPI()->evalSetWorkingDir(script, 1);
|
||||
if (vs.GetScriptAPI()->evaluateFile(script, filename.string().c_str())) {
|
||||
if (OpenScriptOrVideo(vs.GetScriptAPI(), script, filename, OPT_GET("Provider/Video/VapourSynth/Default Script")->GetString())) {
|
||||
std::string msg = agi::format("Error executing VapourSynth script: %s", vs.GetScriptAPI()->getError(script));
|
||||
vs.GetScriptAPI()->freeScript(script);
|
||||
throw VapoursynthError(msg);
|
||||
|
@ -279,4 +279,4 @@ namespace agi { class BackgroundRunner; }
|
|||
std::unique_ptr<VideoProvider> CreateVapoursynthVideoProvider(agi::fs::path const& path, std::string const& colormatrix, agi::BackgroundRunner *) {
|
||||
return agi::make_unique<VapoursynthVideoProvider>(path, colormatrix);
|
||||
}
|
||||
#endif // HAVE_VAPOURSYNTH
|
||||
#endif // WITH_VAPOURSYNTH
|
||||
|
|
Loading…
Reference in a new issue