Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add RFC: Plugin Manager #4

Open
wants to merge 2 commits into
base: master
Choose a base branch
from

Conversation

Programatic
Copy link
Contributor

@Programatic Programatic commented Dec 31, 2019

Description

Implement a plugin manager that allows importing and disabling of plugins.

Motivation and Context

Having a plugin manager that is capable of disabling and importing plugins drastically decreases the complexity of using the plugins and opens more opportunities. More in the RFC.

View RFC

@VodBox
Copy link
Member

VodBox commented Jan 1, 2020

The file should be named with 0003, not 0004.

A big problem with the way plugins are loaded now, is that if a plugin causes OBS to crash or fail to launch for whatever reason, there's no easy way to disable the plugin besides out right uninstalling it. The plugin manager should have some mechanism for disabling plugin launches if they're causing issues, and informing the user of these issues.

A big reason for having a plugin manager is not just to simply install them, but to aid in discoverability. I see future considerations mentions making it so plugins can be installed from a server, but that feels like a big part of making sure the feature is in OBS to begin with. Additionally, plugins should possibly be something front and center, rather than something in settings. File > Plugins or a button in Controls may be better at telling a user that plugins are a thing.

How would the manager organize plugins visually so it's easy to find one you've just installed? Will part of the manifest include categories/tags? Will it include some kind of search of installed plugins?

What information or structure should the manifest contain and follow? And how will things like plugin descriptions be localized when displayed to the user (such as letting the description field be able to refer to a key to load in the locale files)? Should a plugin be able to specify minimum and maximum versions of OBS it supports? Should it be able to specify a path which it can use to check for updates to the plugin, and automatically update it?

Rather than just a zip for the plugin, and needing to navigate to it with the plugin manager, maybe it could use a different file extension that OBS registers, and can install just by double clicking the plugin file? It can still be a zip file, just allowing for fewer steps to install.

@Programatic
Copy link
Contributor Author

The file should be named with 0003, not 0004.

Sorry, why? This is the 4th PR so I was just following in line with the others.

A big problem with the way plugins are loaded now, is that if a plugin causes OBS to crash or fail to launch for whatever reason, there's no easy way to disable the plugin besides out right uninstalling it. The plugin manager should have some mechanism for disabling plugin launches if they're causing issues, and informing the user of these issues.

This is a fantastic idea. I am thinking that as the plugins are being initialized, safely try to launch the plugin. For the plugins that fail, disable them and have a popup on startup outlining which plugins have failed.

Additionally, plugins should possibly be something front and center, rather than something in settings. File > Plugins or a button in Controls may be better at telling a user that plugins are a thing.

I previously was thinking having a tab on the menu bar but thought it would be too crowded. Figured the settings would be a good compromise between ease of access and not having too much on the user too quickly.

How would the manager organize plugins visually so it's easy to find one you've just installed? Will part of the manifest include categories/tags? Will it include some kind of search of installed plugins?

I was thinking by default having the plugins sorted alphabetically. And yes, the purpose of the manifest file would to provide metadata that could be searched. This would include categories. I will update it to make it more clear.

What information or structure should the manifest contain and follow? And how will things like plugin descriptions be localized when displayed to the user (such as letting the description field be able to refer to a key to load in the locale files)? Should a plugin be able to specify minimum and maximum versions of OBS it supports? Should it be able to specify a path which it can use to check for updates to the plugin, and automatically update it?

Personally, I thought the way NPM does manifest files could work out pretty well. It could be JSON formatted, all included locales could be included in the compressed file which are referenced inside of the manifest "locales" object. An example manifest would be:

{
    "name": "Plugin Name",
    "author": "Author Name",
    "description": "Description that would be displayed to user",
    "locale": {
        "en": "file path"
    },
    "plugin": "file"
}

Rather than just a zip for the plugin, and needing to navigate to it with the plugin manager, maybe it could use a different file extension that OBS registers, and can install just by double clicking the plugin file? It can still be a zip file, just allowing for fewer steps to install.

This is another great idea that should be implemented

@VodBox
Copy link
Member

VodBox commented Jan 1, 2020

The reason for 0003 is PR #1 is 0000-window-capture-rewrite.md

The things I asked should be the kind of things made clear in the RFC itself, since that will be the reference for actually creating the manager. Part of my issue with the RFC now is lacking details, or simply implying things (like the RFC mentions checking if a plugin is disabled, but not how a plugin might be disabled).

@Programatic
Copy link
Contributor Author

Ok. I appreciate the criticism and I have gone back and rewritten the RFC. It is much more specific and outlines most of the core components.

Copy link
Member

@WizardCM WizardCM left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added some basic thoughts on the current spec. I have a few bigger suggestions I'll contribute another time.


# Summary
Create a plugin manager that is capable of configuring the loading of plugins as
well as providing an easier means of installing plugins. Perhaps - later down
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A first version should not just be capable of installing - but also updating. That's one of the biggest things missing.

# Summary
Create a plugin manager that is capable of configuring the loading of plugins as
well as providing an easier means of installing plugins. Perhaps - later down
the line - creating a online database that individuals can search and seamlessly
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As part of this RFC, I'd like us at least determine whether the Resources plugin we're using on the forums fulfils our needs, or whether we will need to migrate to something with a better API, or whether we need to look into writing our own.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have absolutely no doubt that we will need to move to a different API, likely a custom web application. I envision something similar to the Kodi add-on system: https://kodi.tv/addons

install plugins.

# Motivation
Varying from plugin to plugin, there are a variety of different intallation
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

While these are valid motivations, there are actually two more important motivatations:

  • Discoverability
  • Compatibility (OBS updates vs plugin updates)

Many users don't know plugins exist. If they do manage to find them, they may struggle to install them. Once installed, users are never notified of updates. These often cause compatibility issues down the line.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Architecturally a plugin manager is necessary to finally differentiate between our runtime modules and actual plugins. Right now the program architecture doesn't differentiate between them and loads any 3rd party plugin as if it were a 1st party runtime dependency.

Finally making a distinction between them (which would be necessary to make a plugin manager work) would decouple both types of runtime libraries and increase software stability:

  • OBS Studio could be made to skip loading 3rd party libraries entirely (safe mode)
  • OBS Studio could be made to migrate 3rd party libraries to a different API that exposes much less internal data, enabling more safety and stability

So on top of the obvious wins for end users (discoverability, manageability) there are maintenance and architecture wins for the program itself.

### Loading
Currently, when plugins cause issues, the only way to disable them is by
outright uninstalling them. However, this could be mitigated at startup by
having an internal record of which plugins are installed. By keeping a list -
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A plugin blacklist (rather than whitelist) is a good idea. On top of this, having a way to disable all third party plugins (ala Safe Mode) to easily confirm whether an issue is caused by a plugin would also be useful.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just saw this comment and thought I should mention, the open source software community is moving away from using the terms "blacklist/whitelist" and adopting "blocklist/allowlist" or other representation to avoid certain connotations. Probably a good idea to follow suit.

To further ease the user with their plugin (once downloaded), installation could be handled in 3
different ways.
- A file explorer in the manager to install a compressed package that contains:
a manifest, locales, the actual plugin, and other needed components.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note that OBS already has some level of split for these:

  • Locales and resources are stored in data\obs-plugins\<plugin name>
  • Dlls, PDBs, and core files are stored in obs-plugins\<bitness>\

The biggest concern I have is that while they're split nicely in data, obs-plugins is not given the same level of care. This makes uninstalling plugins basically an unknown. I would say plugins should be given two path variables, config/resources and core, and then can define subdirectories within them. When we install, we generate a subdirectory for the plugin, and never let them work outside of it.

Additionally, I really really don't like that third party plugins are installed in the application's directory, or at least that they're mixed with included plugins. I would vote we do a similar thing to themes. Themes can read from a themes subdirectory within the config directory, which has the added benefit of a full uninstall/reinstall retaining all installed themes/plugins.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since that comment we have obviously merged lots of changes on obs-studio, including the bundle-based plugin format on macOS, which bundles (hence the name) everything a plugin consists of into a single package (albeit it just being a directory on macOS, it is treated as a self-contained package by the OS), which holds all binaries, support files, and resources that make up a plugin.

Removing a plugin just requires removing the package (whether manually or by a plugin manager). A similar pattern would probably benefit Windows and Linux users as well.

"32": "file path"
},
"categories": ["PRODUCTIVITY", "CLASSIC", "THEMES"], //etc
"version": "^24.0.0"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This would allow the UI to show a warning if a version doesn't match, or in case it's an outdated download, very useful. More discussion on the formatting of the version would be good, as I'd like devs to be able to specify a range. I think npm's semver matching works really well for this.

have random options that can be searched as outlined in UX.

### UX
To access the plugin manager, it would be under Settings -> Plugins or File ->
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I fear this wouldn't be discoverable enough. Maybe a quick-link from the main window's toolbar, too?

which would display a button next to the disable button that opens its settings menu.

When a user disables a plugin, it will add the plugin to a list to prevent
loading during initilization. It will also attempt to unlink the plugin, but a
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Currently the plugins backend is not designed for dynamic unloading, and it may be dangerous to assume plugins will always fully clean up after themselves. It is most likely that the first version will require a restart to unload.

@jp9000
Copy link
Member

jp9000 commented Apr 14, 2020

Things that would be needed for a plugin manager:

  • It should pull approved plugins from the OBS server that we can check and compile ourselves
  • It should support auto-updating plugins from the server
  • Plugins should be digitally signed by us
  • Plugins should probably have stability ratings, like stable/unstable/etc so the user knows what they're getting themselves in to
  • Plugins should have the ability to specify global settings or something, optionally. Probably just easier to make it Qt-based to be honest. Could do something like add settings panes to the settings dialog like we used to do with classic. Or settings in the plugin dialog or something maybe. Not sure.

@dodgepong
Copy link
Member

Plugins should probably have stability ratings, like stable/unstable/etc so the user knows what they're getting themselves in to

Can you go more into detail about this? Are you referring to update channels, like "beta"/"edge"/"stable"? If a plugin has known compatibility issues or serious problems with crashing, we as the curators of the plugin list should probably just take it down rather than flag it with some sort of "problematic" tag.

@Programatic
Copy link
Contributor Author

I don't know. I think it would be better left to the user to decide how stable they would like their plugins. Perhaps the plugin is important enough that a crash every once in a while is worth the risk. I think having tags for the channel such as stable, beta, edge is good. Perhaps put a warning when the user adds a plugin in beta/edge about the potential stability issues

@jp9000
Copy link
Member

jp9000 commented Apr 15, 2020

Can you go more into detail about this? Are you referring to update channels, like "beta"/"edge"/"stable"? If a plugin has known compatibility issues or serious problems with crashing, we as the curators of the plugin list should probably just take it down rather than flag it with some sort of "problematic" tag.

I suppose you've got a point. Problem is it would come down to us to test every plugin. If certain plugins we've had in the past are any indicator, sometimes we can't reasonably convince authors to provie workarounds in a timely manner. And some people will probably get upset if we outright remove their plugin, so it's probably something we have to think about. I.E. Plugin behaving badly, but if we take it away all of a sudden, users complaining.

@dodgepong
Copy link
Member

Problem is it would come down to us to test every plugin

If we're signing every plugin, surely that implies we are testing them too? Maybe I don't quite understand what signing is supposed to buy us.

And some people will probably get upset if we outright remove their plugin

If the policy is that the plugin has to actually work to be listed in the plugin library, then they are free to feel angry as much as they are free to fix their plugin. Really, the question here is now much quality control are we going to do here as we curate the plugin list.

At the same time, though, I question how much of this is more of a policy discussion rather than a technical discussion about implementing the plugin manager to begin with. Presumably the implementation details of the plugin manager would remain the same regardless of how we choose to populate the plugin library.

@Programatic
Copy link
Contributor Author

What it if we create an official stable curation of plugins, and then we can allow plugin creators to either a) host their own plugin servers that users can connect to (maybe even require authentication to) or b) submit their plugins to a more community based server. I am kind of think like arch linux aur. When a plugin becomes popular enough, we add it to the main "repo" where we can more easily verify its stability and compatibility. Otherwise, there is more discretion for the user and plugin developers.

@jp9000
Copy link
Member

jp9000 commented Apr 15, 2020

If we're signing every plugin, surely that implies we are testing them too? Maybe I don't quite understand what signing is supposed to buy us.
If the policy is that the plugin has to actually work to be listed in the plugin library, then they are free to feel angry as much as they are free to fix their plugin. Really, the question here is now much quality control are we going to do here as we curate the plugin list.

Signing is just meant as a verification measure, so we can check that the download is valid. I am not sure if we can reasonably be expected to test and find every plugin's bugs, but yea, I suppose that's what I'm really implying more than anything, how do we curate and ensure that they're working properly or as expected, especially with things like race conditions which can pop up randomly.

At the same time, though, I question how much of this is more of a policy discussion rather than a technical discussion about implementing the plugin manager to begin with. Presumably the implementation details of the plugin manager would remain the same regardless of how we choose to populate the plugin library.

Well, we can't release it without a policy on that. I suppose we could implement it and merge it and then just not expose it until we had a policy though, so if you feel we should put the policy discussion aside then I don't mind that.

@dodgepong
Copy link
Member

dodgepong commented Apr 15, 2020

so we can check that the download is valid

By "valid" do you just mean, like, a checksum? Or to verify that there hasn't been some sort of MITM attack that makes a user think they are getting a legitimate plugin but are actually getting someone else's random DLL?

I suppose we could implement it and merge it and then just not expose it until we had a policy though, so if you feel we should put the policy discussion aside then I don't mind that.

I just want to be sure that the discussion here is meaningful for the RFC, which is largely a technical spec draft. I think policy discussion can inform what features we want to have for a minimum viable product, but I just want to be sure we don't get lost in the weeds.

For example, the suggestion @Programatic made about letting people specify a non-authoritative plugin repository is more complicated than it may seem on the surface, because one issue I've been struggling with is what to do about plugins that offer paid services or integrations.

Suppose a graphic design company wanted to sell OBS overlay packages, and they made a plugin that was basically an embedded browser page to their online storefront. Listing them in the official OBS plugin library is essentially advertising and visibility for that company. Is this "okay"?

It's a complicated issue. On one hand, the prospect of giving free advertising to a paid service seems...unwise? If they are extracting value from the service we are operating (the official plugin listings, and the platform on which they are consumed) then it doesn't seem unreasonable for the project to charge some listing fee, or request revenue share from sales (conventionally, a standard cut for this sort of "in-app purchase" would be 30%). And more practically speaking, it would be unwise of those companies to build a business on a platform with which they have no SLA, or that may disappear at any moment due to insufficient funding. If those companies are getting value from the platform, it's in their best interest to do everything they can to ensure the platform can continue to exist.

On the other hand, there's "the spirit of open source" that demands that people be able to do whatever they want with the software, and if you didn't want people making money with it then you shouldn't have given it away for free. Sure, fair point, and I think the openness of OBS as a platform is one of its greatest assets for the sake of enabling novel use cases and addons to arise from the community. I think the absolute wrong response would be to create a hard plugin whitelist, and block all plugins that aren't on the whitelist from loading. And if we don't have a whitelist, that means that even if we did have a policy in place that limited the presence of plugins for paid services in the plugin library, those companies would still be able to distribute "side-loaded" plugin installers to get the plugin into OBS anyway and skip any revenue sharing requirement Alternatively, if we allowed users to add third-party plugin repositories, or otherwise had an "unfiltered" community repository, it would be easy enough for a company to instruct users how to install their plugins from a non-standard repository. The value proposition of the main plugin library, then, is limited to simple exposure, and if it's easy enough to get around that hurdle, then there may be no sufficient motivation for companies to want to pay to be listed in the plugin library in the first place.

Right now, my least-bad solution to this problem would be to incentivize corporate sponsorships by associating plugin publisher profiles with Open Collective accounts. This would allow us to show a little badge or something next to the publisher's name on each of their plugin listings to indicate to users that the publisher supports OBS development, and the absence of such a badge would tell users that the company is freeloading. It's not a great solution, because a) I think user convenience will outweigh a mild amount of social shaming, depending on the size of the company, and b) a $250/mo bronze sponsorship is a drop in the bucket compared to the sales numbers that many of these companies put up (which may necessitate showing different badge degrees/sizes based on sponsorship level).

And on top of all this, how would the implementer of this feature feel if they put a bunch of unpaid labor into a feature that ended up making a bunch of money for other companies and possibly also the OBS Project? (To that effect, I think it's entirely reasonable to put a sizable bounty on this feature when the spec is completed.)

I don't know what the right solution to this problem is yet. But all that is to say that yes, policy discussion can inform feature sets, so I suppose you're right that it's fair to discuss them now.

@Programatic
Copy link
Contributor Author

By "valid" do you just mean, like, a checksum? Or to verify that there hasn't been some sort of MITM attack that makes a user think they are getting a legitimate plugin but are actually getting someone else's random DLL?

I would imagine the digital signature would use something like asymmetric key signing in order to verify that there was no corruption as well as preventing of any MITM attacks.

Also, I would imagine that allowing 3rd plugin servers, once implemented, would decrease the complexity for paid plugins and services. By allowing 3rd party authenticated servers, it allows individuals to create their own payed plugins, without having to show any sponsorship whatsoever.

Whether or not there should be monetized plugins, is a different story. I have personally never been a fan of paid content. However, if the plugin significantly increases quality of life for users, I think there could definitely be a case for it. An example could be a plugin that integrates a lot of their services with OBS automatically and seamlessly which should be kept off of official listings.

Suppose a graphic design company wanted to sell OBS overlay packages, and they made a plugin that was basically an embedded browser page to their online storefront. Listing them in the official OBS plugin library is essentially advertising and visibility for that company. Is this "okay"?

Perhaps if they are an official sponsor of OBS, there could be a dedicated section of plugins that they can reserve a spot to. This way, OBS can control the quality of content officially while also providing more value for the users.

I understand the issue with monetization, but it seems like OBS has already been caught inside of the crossfire since many people rely on these streaming tools in order to support themselves. As a result, companies are going to inherently want to pour money into it because there is a big opportunity to make money.

perhaps in the configuration file - of the disabled plugins, they could be
ignored during initilizaiton.

Furthermore, if a plugin causes a major failure while loading or doing use, it
Copy link

@billyjbryant billyjbryant Jan 22, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Adding in addition to this, a performance measurement of which plugins cause the highest hits to system performance would be beneficial. This would help with diagnosing issues that are being caused by bad plugins not properly managing their resource utilization. Also knowing which plugins take the longest to load on OBS launch may become handy as well.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OBS module load time is already logged in the OBS logs at the end of each OBS session under "obs_load_all_modules" in the profiler.

@pedjas
Copy link

pedjas commented Feb 14, 2022

I did not notice it mentioned so here are few suggestions:

Plugin manifest should contain info with what version of OBS Studio plugin works. I guess that should be two information> minimum and maximum version. That would assure that plugin is not loaded into OBS version it cannot work with. Mostly targeted on old and obsolete plugins. This may especially be helpful when user updates OBS and if he has some plugin that is not compatible with the newest OBS that plugin would not be loaded.

There should be indication if plugin is free, or semi free (limited, asking of purchasing more features, relaying on some external commercial online service or software, or fully commercial (must be purchased). This all should be informative and mandatory for user to see before downloading, so he can decide if he wants to install plugin or not.

There may be several Repositories of OBS plugins - one official and others set as per wish or need. Official repository should be mandatory but user could be able to add more repositories in configuration. That may solve dilemma about listing commercial plugins. It could be simple: official OBS repository would show only open source plugins. For other kind of plugins, manufacturer may set his own repository and instruct his clients to set it in OBS to be able to get plugins.

I am not sure if there is actual case but maybe it would be good to allow for plugin dependency - that one plugin requires some other plugin to be already installed. That should be set on plugin version level.

It should be possible to have multiple versions of a plugin. For example: old version of plugin that works with old version of OBS Studio and new version that works with latest OBS, or stable version, then alpha, beta.. so that user is able to choose which one to install. this is a must if automatic updating is implemented.

"name": "Plugin Name",
"author": "Author Name",
"description": "Description that would be displayed to user",
"locale": {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As outlined above, plugins would preferably have a "self-contained" bundle structure, and the same should apply for the downloaded package, which in a best case scenario would contain:

  • Windows x64
  • Windows ARM64
  • macOS Universal
  • Linux x86_64
  • Linux aarch64

(I included arm64-based architectures on purpose because those are becoming more popular thanks to Apple Silicon and it would be beneficial if we mind such future support.)

Usually the plugin package should have a fixed expected directory structure, so the manifest just states which platforms are supported and the plugin manager checks for the specified directories (i.e., if "Windows x64" is supported, a directory "windows-x64" needs to exist in the package).

Each subdirectory then contains the expected bundle with an expected filename (this could be the value of a filename field in the manifest) - on macOS we already have the .plugin bundles, a directory that would need to be copied verbatim, I leave it to Windows and Linux maintainers to decide on their preferred bundle naming scheme.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

10 participants