MediaMonkey 5 is a fully HTML-based desktop application which uses Chromium for rendering. This means that the entire UI is driven by an HTML/CSS/JS stack, which is fully accessible to developers and skinners. JS in cooperation with native code drives the non-visual aspects, also fully controllable by developers. This gives unprecedented customization options to create beautiful skins, new or enhanced functionality and great addons in general.
Documentation
- The Getting Started guide provides you with all the information you need to get started.
- This document provides a summary of the MM5 addon framework and its differences from previous versions.
- The API reference will soon be a complete reference to all the functionality provided both by MM native code and JS libraries. Important Methods and Utilities contains a list of the most notable functionality provided.
- Sample scripts and skins are a good source of how-tos. They are placed directly in 'Scripts' and 'Skins' folders (see below for details). Some more scripts are in the SampleScripts folder (can be installed via Tools > Extensions > [Add]).
- The most comprehensive source of information is directly within the MM source code (see the folder structure below), particularly all the JavaScript code that powers the UI framework. From these, you can answer most questions about individual features and study/modify behavior beyond what’s possible with the documented API.
- If you have questions that aren’t answered above, please raise them in the MM5 Developers Forum to be answered by MM devs or other Addon authors.
All the HTML/CSS/JS code that handles MM functionality is stored in a tree structure. As a developer, you can add new files, replace existing, or even extend functionality of the existing files. This is achieved by replication of the folder structure in Addons. For example, if a file controls\checkbox.js is present in the Addon, it completely replaces the default MM functionality of a checkbox. Similarly, an _add suffix in a filename extends functionality of an existing file. For example, dialogs\dlgAbout_add.js can contain code that adds new controls to the layout of the About dialog.
- Root - Contains mainly mminit.js, which has the basic MM JS routines, several other utility .js files, maincontent.html which contains the basic definition of the main window. Also important is viewHandlers.js, which defines the tree structure of MM and behaviour of the views.
- controls - Contains all the controls used in MM UI. This starts with very basic controls, like button.js or dropdown.js, and continues with more complex things like listview.js and goes all the way to the complex UI elements, like equalizer.js, player.js or autoPlaylistEditor.js.
- dialogs - All the dialogs reside here, e.g. dlgConvertFormat.html + dlgConvertFormat.js
- dlgOptions - Panels for the Tools > Options menu reside here.
- layouts - Subfolders contain individual layouts, i.e. something that can replace/modify the files in the default folder structure in order to achieve completely different layout of MM (e.g. "Touch mode" layout). Unlike skins, layouts are supposed to mainly modify dimensions, positions and types of UI elements, not their color, etc.
- scripts - There are some sample scripts included demonstrating various aspects of MM customization. Some more are in the SampleScripts folder.
- skin - Contains basic skin definitions, mostly a set of LESS files (an extension to CSS).
- icon - Contains all the icons used by MM. They are in SVG format in order to scale nicely to any display resolution. As anything else, they can be easily replaced by any Addon (skin or script).
- skins - Subfolders contain individual skins, i.e. something that can replace/modify the files in the default folder structure in order to achieve completely different looks of MM. Unlike layouts, this is supposed to mainly modify colors, fonts, icons, etc.
As in the past, the MMIP file format is just a zip archive with a different extension (.mmip). You can do it manually, or use an automatic tool such as pack-mmip.
If you use GitHub, you can automatically create versioned builds by following this guide from TIV73/mmuffins.
Make sure that the files are in the root of the archive, and not inside a subfolder. (Demonstration)
Scripts
Scripts should be placed following the folder structure described above, in order to modify/replace existing functionality of any part of MediaMonkey. When addons are installed, they are placed inside the Scripts subfolder of the install location. If you add init.js into the root, it will run at startup. Inside your scripts, you can use the method localRequirejs when you need to include other script files that are not part of the existing MM structure.
Skins/Layouts
Skin files should be placed inside the skin folder, and layout files should be placed in the layout folder, inside the mmip archive as described above. The idea of separation of skins and layouts is that layout defines how it works, while skin more or less defines how it looks. Skins consist of a set of LESS (see http://lesscss.org/ for documentation) files that are later automatically compiled into a single CSS that drives the look of the application. The most important files are:
- skin_complete.less - Links all the other skin files - usually not modified by skinners.
- skin_base.less - Basic constants, like colors, margins, etc. - almost always modified by skinners.
- skin_layout.less - The part of CSS that we use for basic layout of our windows, i.e. something that will almost never be modified by skinners.
- skin_{control_name}.less - Specific CSS for given control, e.g. its borders (whether they are rounded, etc.)
- skin_custom.less - Included as the last, so that skinners can re-define anything, add some specific CSS, etc.
The framework is designed to be ready for deployment on any platform, since the HTML/CSS/JS code is platform independent. Some UI details can certainly be tweaked so that it looks native to a particular platform.
Pre-MM5 scripts, skins and plugins
- MM4 scripts are mostly VBS-based and specific to the Windows platform. During the planning phase of MM5, we decided to make a clean break from this so that MM5 scripts could be cross-platform and more powerful. As a consequence, MM5 has a completely different interface from that of MM4, and support for MM4 scripts in MM5 would be very hard to implement. That said, we have a converter that helps perform automatic script conversions, while not perfect, they can help as a starting point.
- MM4 skins are so different from what MM5 offers that we don’t even consider any backward compatibility. Just consider that MM4 uses bitmaps while MM5 uses vector based graphics (SVG icons), as well as using LESS/CSS for the entire styling.
- Winamp visualization plugins is replaced by JS framework, i.e. fully cross-platform now.
- Winamp general plugins won’t be needed anymore, since JS scripting should be able to achieve the same (and more) in a more cross-platform fashion.
- Winamp input / output / DSP plugins are presently supported, though we are evaluating our future options re. how to support such functionality when making MM5 cross-platform.
- We currently use Chromium version 98, but will keep it updated as much as possible. Chromium version can help you to decide which HTML/CSS/JS features can be used (e.g. at http://www.chromestatus.com/features or http://caniuse.com/).
- The debug version of MM5 contains tools to look under the cover and debug JS scripts or HTML/CSS layouts. One option is to use Ctrl+Alt+Shift hotkey to show Chromium Developer Tools. Another option is to right-click anywhere in the UI, where the last two items give you direct access to the Developer Tools, including Inspect Element feature.
- Naming conventions: We follow this naming convention https://google.github.io/styleguide/jsguide.html#naming and suggest all the scripts do the same.
- Enable Developer Mode. Under Help > About, you can enable Developer Mode. This will prevent crash logs from being automatically sent to MediaMonkey staff.
- To avoid having to constantly re-package and re-install addons that you are working on, you can create a hard-link from the Scripts subfolder to your project folder. To do this, open PowerShell, then enter:
Code: Select all
New-Item -ItemType Junction -Path "C:\path\to\MediaMonkey\Scripts\My Addon" -Target "C:\path\to\ProjectFolder\My Addon"
- When editing HTML/JS for dialogs, you do not need to restart MM5 for changes to take place. Re-opening the dialog will open the most recent version of the files.
After packing an MMIP, you can upload an addon to the site here.
First, select the category appropriate for your addon. (Make sure it's within the MediaMonkey 5 main category.) Then click Submit New Addon and follow the instructions from there. After it's submitted, it will be reviewed and approved by a member of the team.
A note on overriding methods, expandability, and copy-paste
While we have taken much care in making MediaMonkey 5 as modular as possible to allow for addons to easily change its behavior, sometimes there are oversights. A few times already, we have encountered situations where a particular feature could be implemented by changing just a few lines of code; but would require a lot of copy-and-paste in order to to implement those code changes in an addon. For example, if a submenu function depends on an internal (local scoped) function, if one wishes to tweak that internal function for an addon, they would need to copy-and-paste both the submenu function and the internal function in their addon, in order to redefine them with the tweaked functionality.
While we allow modifying and redistributing some code from MM5, as described in the Ventis limited reciprocal license; and we highly encourage modifying MediaMonkey (as you all hopefully know); heavy dependence on copy-pasted code can lead to other issues. If an addon depends on a significant amount of code that is copy-pasted from the source, and then the original code is modified to fix a bug or add a new feature, then the author would need to update their addon in order to reflect the new changes. To continue with the previous example, if a new entry was added to the submenu in question in a future update, then users with the addon installed would not see the new item in that submenu - Even if the addon had nothing to do with the submenu in question. (Remember, their goal was to tweak something in the internal function, not necessarily the items in the submenu.)
It's doubtful that anyone would want to worry about watching for updates & changes to the code that they copied and modified. It is in everyone's best interest that addons be independent of specific versions of MM, and not need to be updated as changes are made to MediaMonkey. Thus, if you find yourself in a situation where you have no choice but to copy and paste a lot of code to make something work, reach out on this forum instead. We are aware that some code is not easily customizable at the moment, and we will be happy to assist in making it more straightforward / granular based on developers' needs. Our goal has always been for MediaMonkey to thrive with its customizability through addons, so we will be ready to improve the expandability of MM5's code in order to make addons less dependent on copy-paste.