Closed matthijsvrenswoude closed 4 months ago
Hi thanks for posting.
The whole idea behind the flow system is not have super large plugins that do a lot of things but instead to have small configurable blocks where people can pick and choose what they want to happen.
Tdarr comes with several binaries (FFmpeg, FFprobe, HandBrake, mkvpropedit) and a few others which it needs for normal operation. If your plugin requires a specific external binary that the user must install manually then the paths for those can be set as a plugin input, likewise any presets can be set in plugin inputs and logic handled in the plugin. This can be combined with the global variable functionality on the Tools tab so that you can set the path in one place and re-use it in flow plugin inputs. Node path translation also applies to plugin inputs so any paths in input are automatically translated. There does not need to be new logic to do this.
So overall I think this suggestion is not adding anything new, in fact it's making it confusing as it seems to be misunderstanding how the classic plugins work. The preset
string is just arguments for either handbrake or ffmpeg (handBrakeMode
or FFmpegMode
need to be set to true
). Passing e.g. "mkvextract", ", extracting embedded subtitle"
isn't a valid preset.
Also would recommend creating a flow plugin instead of a classic plugin. Classic plugins aren't being further developed and flow plugins are much more powerful and customisable (you can run any CLI on a file which is what you're trying to do, classic plugins are only for running handbrake or ffmpeg on a file).
Please post any plugin related bugs/requests at here: https://github.com/HaveAGitGat/Tdarr_Plugins
I respectfully disagree on the added value.
While I agree with your statement there shouldn't be a super plugin, I think this one is an exception. And that reason is standardization of media. Codecs and playback support on devices is a giant cluster f*ck. Especially when having media from different sources. This Plugin tends to fix all that issues by creating 1 media file with almost identical quality to the original with maximum device playback support in new codecs.
Some examples are issues with media could be:
These are only a few issues, and I could get on and on with more issues that I have encountered. The plugin I have created is customizable for everyday normal users for the things that matter, without the need to have engineer level knowledge of codecs and playback support. In separate flow plugins that concept would be huge, incredibility complicated and also a pain to code. For the advanced users, there are even extra settings at the beginning of the code If they really want to play with the output / decision-making process.
For the current profile the plugin is using to intelligently determine the fate of individual streams, I spend days going through codec documentations and video files to determine the best course of action.
And undoubtedly the best setup for maximum support currently is HEVC, AC3 surround, AAC Stereo. (And User optional Dolby Truehd, DTS-HD Master Audio and Dolby vision in MP4)
The thing is, most people don't want to go in depth of the inner working of video playback, and to be honest I don't blame them, since it's complicated and often limited documented. Wouldn't it be nice if they can add one plugin, Setup that plugin with their Hardware Acceleration platform of choice, with the preferred languages of choice and some other preferences and the plugin takes care of fixing all codec issues, compact the file size by upgrading all the codecs and only keep the streams that they really want? They don't have to even leave it like that, and they could still be manipulate the file further by including it in flows, but at least it gives a good solid base to build on top off with current day codec support. I think on a platform like Tdarr that provides a good interface to track all progress and distribute tasks, such a plugin provides huge value.
I'll advise you to look through the code that I have already written, and see what you think.
Now to the topic of "mkvextract", ", extracting embedded subtitle" I know that the above-mentioned preset is not a valid preset it was only as example of the action I would like to, if you want an actual example, here is one without even something advanced like Dolby Vision or MKV to MP4 Conversion (I'm still improving the profiles on these):
But then why not just put it in a single flow plugin if you're really wanting to do that? Or create a flow template that has all those plugins in ready to go so the user just has to configure/disable certain ones? That's sort of the whole purpose of templates:
Would just export the flow and then add the file here in the same formatting as the others there: https://github.com/HaveAGitGat/Tdarr_Plugins/tree/master/FlowPluginsTs/CommunityFlowTemplates/video
The flows system has sub-flows with the Go To Flow
plugin. So they could do their own stuff in a flow, then go to your flow, then go back to their original flow to continue other stuff?
Have a look at these 2 flow plugins: https://github.com/HaveAGitGat/Tdarr_Plugins/blob/master/FlowPluginsTs/CommunityFlowPlugins/classic/runClassicTranscodePlugin/2.0.0/index.ts https://github.com/HaveAGitGat/Tdarr_Plugins/blob/master/FlowPluginsTs/CommunityFlowPlugins/handbrake/handbrakeCustomArguments/2.0.0/index.ts
Those contain info on everything needed. runClassicTranscodePlugin
shows how to run a classic plugin in a flow and handbrakeCustomArguments
shows how to run a CLI in a flow. A lot of extra stuff in those plugins but this is the most important part:
const cli = new CLI({
cli: args.handbrakePath,
spawnArgs: cliArgs,
spawnOpts: {},
jobLog: args.jobLog,
outputFilePath,
inputFileObj: args.inputFileObj,
logFullCliOutput: args.logFullCliOutput,
updateWorker: args.updateWorker,
args,
});
const res = await cli.runCli();
if (res.cliExitCode !== 0) {
args.jobLog('Running HandBrake failed');
throw new Error('Running HandBrake failed');
}
So in the flow plugin inputs could have a switch or dropdown etc to enable disable different presets and then can act on those in the code.
So that's 2 ways to do what you're trying to do, or am I missing something there?
I already started migrating to a flow plugin based on your reasoning in a previous post of using global vars for additional program paths. Which is a good middle ground. I however was still was under the impression flow plugins also only could execute one CLI action, which apparently is not the case. Your last post clears it up fully, and indeed lines up with my needs.
Yeah that's right you can pretty much do anything in a flow plugin as long as you return file and output number at the end for Tdarr to continue with.
So can so can use this code to generate a new temp output folder file each time if you've got multiple things going on:
const outputFilePath1 = `${getPluginWorkDir(args)}/${getFileName(args.inputFileObj._id)}.${container}`;
const outputFilePath2 = `${getPluginWorkDir(args)}/${getFileName(args.inputFileObj._id)}.${container}`;
Where getPluginWorkDir
creates a new folder for the temp file to be in.
Then can have multiple bits of processing:
...
if(args.inputs.thing1){
const cli = new CLI({
cli: args.ffmpegPath,
spawnArgs: cliArgs,
spawnOpts: {},
jobLog: args.jobLog,
outputFilePath: outputFilePath1,
inputFileObj: args.inputFileObj,
logFullCliOutput: args.logFullCliOutput,
updateWorker: args.updateWorker,
args,
});
const res = await cli.runCli();
if (res.cliExitCode !== 0) {
args.jobLog('Running FFmpeg failed');
throw new Error('Running FFmpeg failed');
}
}
...
if(args.inputs.thing2){
const cli = new CLI({
cli: args.ffmpegPath,
spawnArgs: cliArgs,
spawnOpts: {},
jobLog: args.jobLog,
outputFilePath: outputFilePath2,
inputFileObj: args.inputFileObj,
logFullCliOutput: args.logFullCliOutput,
updateWorker: args.updateWorker,
args,
});
const res = await cli.runCli();
if (res.cliExitCode !== 0) {
args.jobLog('Running FFmpeg failed');
throw new Error('Running FFmpeg failed');
}
}
...
If you have VSCode (other IDEs should support this too), you can right click on the type/interface to see the definition so you can see what info is passed to the plugin.
Hope that helps
And if you produce a new file that you want Tdarr to give you info for, you can do it 2 ways.
First way is to use this (can see example in here: https://github.com/HaveAGitGat/Tdarr_Plugins/blob/71f468fab7ca51613dfee13c42e09435cbef7b8a/FlowPluginsTs/FlowHelpers/1.0.0/classicPlugins.ts#L114) :
const fileInfo = await args.scanIndividualFile(inputFileScanArgs, scanTypes);
Second way is each time you produce a new file, you return that and use the same process as what the Run Classic Transcode Plugin
does where output 1 is if processing was done and output 2 is if no processing was done. So can keep looping through output 1 and then when all stuff is finished go to ouput 2. Each time it's looped Tdarr will scan the new file info and that will be passed to args
at the start of the plugin.
Okay, hear me out.
I have been using Tdarr on my media library for some time now. For that, I have written all the plugins myself. Currently, I am currently doing a full rework of my original plugins and trying to combine them all, including some mayor improvements including efficiency and a more streamlined design so it could be made into a community plugin.
For that I would like to request some changes though. The current version of the plugin, you could follow for updates here. It is still very much in WIP, but I am currently in the state where I can comfortably request some changes, since I have mostly figured out the complete software design.
So, a summary of what it does:
What additions I would like to see:
let pathVars = [ ["node", "C:/Tdarr/Tdarr_Node/runtime/Tdarr_Node_Runtime.exe"], ["ffmpeg", otherArguments.ffmpegPath], ["mkvextract", otherArguments.mkvpropeditPath?.replace("mkvpropedit","mkvextract")], ["dovi_tool", "C:/Tdarr/DoviTool/dovi_tool.exe"], ["mp4box", "C:/Program Files/GPAC/mp4box.exe"], ];
This is how I would code it for Tdarr:
So now finally, with all the presets loaded, I would like Tdarr to show in the backend each individual preset with the following UI, With it own openable and readable logs, as if it were separate plugins, including where if one preset fails the whole pipeline does too.
This way we can have one plugin have mayor performance improvements (CPU execution time, read/write operations you name it) and resource sharing capabilities, compared to separate flow plugins and all perfectly monitorable.
I hope I have explained my request well, If you have any questions, let me know.