A starting point for an ArgonFetch plugin. Use this repository as a template, rename three things, and you have a plugin someone can install.
yt-dlp already fetches an enormous number of sources the ordinary way, and ArgonFetch uses it for all of them. Check whether yours is one of them first - if it is, there is nothing to write.
A plugin is for a link that needs something else:
| You want to | Answer with |
|---|---|
| Fetch a different link, keeping your own title and credit | ProviderOutcome.Rewrite |
| List an album or a playlist | ProviderOutcome.Listing |
| Fetch it yourself, skipping yt-dlp | ProviderOutcome.Complete |
| Nothing - let yt-dlp have it | ProviderOutcome.PassThrough |
Only need to change how yt-dlp is called - a cookies file, a format? That is an
IFetchOptionsHook, not a provider.
src/ArgonFetch.Plugin.Example/→ your source's nameAssemblyNamein the csproj, and the folder, to matchId, the assembly attribute, andUrlPatternsinExampleProvider.cs
<PackageReference Include="ArgonFetch.Abstractions" Version="..." ExcludeAssets="runtime" />ExcludeAssets="runtime" is already in the csproj. Leave it there. The host loads the contract
itself and hands your plugin types from its own copy; ship a second copy and your assembly ends
up implementing a different ISourceProvider from the one the host is looking for. It fails
with a message claiming ISourceProvider cannot be cast to ISourceProvider.
UrlPatternsare matched by the host on every request. Anchor them:example\.comalso matcheshttps://example.com.somebody-elses-site.test/.- Return raw addresses in
MediaStream. Caching and URL building are the host's business. - Cache through
IProviderContext.CacheKey, never a bare string - the cache is shared. - Prefer
Declinedto throwing. The ordinary path may well handle what you could not.
Push to main. CI builds the plugin, checks it does not ship the contract, zips it, hashes it and
pushes the archives with an index.json to an orphan repo branch. Point ArgonFetch at it: