FDM Plugins
FDM Plugins
1. Purpose
Plugins are intended to extend the ability of FDM to download useful content from a URL provided by
the user.
There are two possible ways to achieve this:
1. By the use of a plugin user will be able to download a resource (e.g. media) which otherwise cannot
be downloaded by the user using the standard means of a web browser.
2. Improve the user experience, i.e. simplify the way of downloading things. This is still under
consideration.
The current API allows to only extend the ability of FDM to download media content.
2. Basic principles
Plugin should be written using JavaScript. Also, FDM does support launching Python scripts, by
passing arbitrary command line arguments to a script and getting console output from it.
Plugin consists of manifest file, icon file and javascript files with the code.
3. Manifest file
Manifest file is a json file. Its file name must be manifest.json. Here is an example:
{
"uuid": "fdm-supremecourt-gov",
"author": "FreeDownloadManager.ORG",
"name": "Supreme Court Argument Audio",
"description": "Provides support for downloading argument audio from supremecourt.gov site.",
"version": "1.0.0",
"icon": "icon.png",
"mediaParser": true,
"mediaListParser": true,
"scripts": [
"msparser.js",
"msbatchparser.js"
],
"updateUrl": "https://files2.freedownloadmanager.org/updates/plugins/fdm-supremecourt-gov-
update.json",
“minApiVersion”: 1
}
{
"versions": [
{
"version": "...",
"distributiveUrl": "…",
“minApiVersion”: 1
},
{
"version": "...",
"distributiveUrl": "…",
“minApiVersion”: 2
},
...
]
}
4. Javascript code
4.1. Single media parser
This corresponds to mediaParser property in manifest json. If mediaParser is set to true, the plugins’s
javascript code must define a global variable named “msParser”. This global variable must be an
object with the following members:
• isSupportedSource: function(url). This function should return true if plugin supports
downloading from the specified URL.
• supportedSourceCheckPriority: function(). It’s possible that several plugins could support
downloading from the same URL. In this case a plugin with the greatest priority value will be
chosen. Returns integer value from 0 to 2³¹-1 (0x7FFFFFFF).
• isPossiblySupportedSource: function(obj). In some cases it can be hard (or even impossible)
to implement isSupportedSource function. This function is designed to be used in such a case
instead. If the user creates an HTTP(S) download, and there were no plugins returned true from
isSupportedSource call, then this function is called for every plugin. In case a plugin returns
true from it, FDM will try to use this plugin to download from this URL. In case the plugin
fails, FDM will try next plugin and so on. The obj variable is an object with the following
members:
◦ url – URL entered by the user.
◦ contentType – content type, as reported by a server.
◦ resourceSize – content length, as reported by a server.
• parse: function (obj). This function is called when a plugin is chosen to download from a URL
provided by the user. The obj variable is an object with the following members:
◦ url – URL entered by the user.
◦ requestId – integer identifying this request. It’s used in some other APIs.
◦ interactive – boolean value indicating if this request is performing in foreground (i.e. the
user is waiting for it to finish).
This function must return a Promise object. On a success, this Promise must be resolved to
an object with the parsed data. Its format will be described below. In case of a failure, this
Promise must be rejected with an object with the following members:
◦ error. String. It will be shown to the user as is.
◦ isParseError. Boolean value, indicated if this error is caused by parsing algorithms of the
plugin (true) or something else (false).
• minIntevalBetweenQueryInfoDownloads: function(). This function is used to define a
minimum required interval (in milliseconds) between parse function calls. Return 0 to specify
no interval. A typical use of this function is to reduce the load of the remote server.
• overrideUrlPolicy: function(url). Downloads from some specific URLs can be prohibited in
FDM due to various reason. Plugin can define this function and return true for such URLs in
order to lift such restriction.
Please take a look at msparser.js file from fdm-supremecourt-gov add-on for an example. You can find
it in examples folder.
4.3.1.1. “Formats”
It’s an array of objects with the following members (all members are optional if not explicitly stated
otherwise):
• url. Mandatory member. URL to video/audio file.
• filesize – size of the file.
• protocol. Mandatory member. Must be “http” or “https”. M3U8 protocol is not supported
currently.
• ext – file extension (e.g. “mp4”, “m4a”, “mp3” and so on).
• video_ext. Mandatory member in case of a video file. File’s extension.
• audio_ext. Mandatory member in case of an audio file. File’s extension.
• vcodec. Name of the codec used to encode video stream. Can be a name, “unknown” or “none”.
• acodec. Name of the codec used to encode audio stream. Can be a name, “unknown” or “none”.
• container. Mandatory member in case of DASH format. Can be something like “mp4_dash”,
“m4a_dash”, “webm_dash” etc.
• fps. In case of a video – its FPS.
• height – video’s height.
• width – video’s width.
• quality – an arbitrary integer value (the higher the better).
• tbr – total bitrate (audio + video).
• abr – audio stream bitrate.
• preference – an arbitrary integer value indicating the preference of this format over others for
the user (the higher the better).
4.3.1.2. “Subtitles”
It’s an object. Its each member must has name equal to a language code (e.g. “en”, “en_US”, …) and
must be an array of objects with the following members (i.e. one array per one language code):
• name. Mandatory member. Language name.
• url. Mandatory member. URL of the file with subtitles.
• ext. Mandatory member. File’s extension.
Example:
{
“en”: [{name: “English”, url: “someurl”, ext: “vtt”}],
“uk”: [{name: “Ukrainian”, url: “someotherurl”, ext: “vtt”}],
“ru”: [{name: “Russian”, url: “someotherurl”, ext: “vtt”}]
}
4.3.1.3. “Thumbnails”
It’s an array of objects with the following members (all members are optional if not explicitly stated
otherwise):
• url. Mandatory member. URL of the thumbnail image.
• height – image’s height.
• width – image’s width.
• preference. An arbitrary integer value indicating the preference of this format over others for
the user (the higher the better).
4.3.2. Playlist
It’s an object. All members are optional if not explicitly stated otherwise.
• _type. Mandatory member. Must be “playlist”.
• id. A string identifying playlist.
• title. Mandatory member. Media’s title. It will be shown to the user.
• webpage_url. URL of the web page the playlist content resides on.
• thumbnails. An array of objects describing playlist’s thumbnails.
• entries. Mandatory member. An array of objects describing each media the playlist consists of.
4.3.2.1. “Entries”
It’s an array of objects with the following members:
• _type. Mandatory member. Must be “url”.
• url. Mandatory member. Media’s URL. This URL will be passed then to a single media’s
parser.
• title. Mandatory member.
• duration. In seconds.
4.4.1. Console
We do have implementation of this object provided by Qt framework.
The list of functions added is as follows:
console.assert()
console.debug()
console.exception()
console.info()
console.log() (equivalent to console.debug())
console.error()
console.time()
console.timeEnd()
console.trace()
console.count()
console.warn()
print() (equivalent to console.debug())
4.4.4. launchPythonScript
Add-on must has “launchPython” permission to use this function. It will get access denied error
otherwise.
This function accepting the following arguments:
• requestId. Value, passed to parse function, or 0. It’s used to automatically terminate Python’s
process when the user stops download.
• interactive. Value, passed to parse function. In case it’s true, this Python process is launched
immediately ignoring all queued processes. This should be “true” only for a download the user
is creating currently, so he will not have to wait.
• script. Path to python’s file to execute. This must be a relative path to plugin’s root directory.
• args. Some arbitrary args (array) to pass.
It’s resolved to an object with the following members:
• exitCode: Python’s process exit code.
• output: Python’s process console output.
In case of a failure it’s rejected with an object with the following members:
• error. Error string.
5. Feedback
This is just an experimental API. We do not know exactly if it can be useful and demanded. Please tell
us what you think. Do not hesitate to report us bugs / suggestions on improvement this.
We prefer you to use our forum for this.