### Apache full example configuration Source: https://jcorporation.github.io/myMPD/070-additional-topics/behind-a-reverse-proxy.html A complete virtual host configuration example combining proxying, authentication, and access control. ```apache MergeSlashes OFF ServerName yourserver.example.com ProxyRequests Off ProxyPreserveHost on ProxyVia On Require host localhost Require ip 192.168.1.0/24 AuthType Basic AuthName "Authentication Required" AuthUserFile /etc/apache2/.passwds/mympd Require valid-user ProxyPass /mympd/ws/ ws://127.0.0.1:8080/ws/ Redirect /mympd /mympd/ ProxyPass /mympd/ http://127.0.0.1:8080/ ProxyPassReverse /mympd/ http://127.0.0.1:8080/ ``` -------------------------------- ### Install PulseAudio packages Source: https://jcorporation.github.io/myMPD/070-additional-topics/multiroom-audio-using-pulseaudio-rtp.html Install PulseAudio and utilities on all systems (NAS and receivers) using apt. ```bash apt install pulseaudio,pulseaudio-utils,pulsemixer ``` -------------------------------- ### Install myMPD from ports Source: https://jcorporation.github.io/myMPD/010-installation/compiling/freebsd.html Compile, install, and clean up the build files for myMPD. ```bash make install make clean ``` -------------------------------- ### Configure myMPD Repository and Install Source: https://jcorporation.github.io/myMPD/010-installation/prebuild-packages-debian.html This script retrieves the OS version, imports the repository signing key, verifies the fingerprint, adds the repository to the sources list, and installs myMPD. Replace 'Debian' with 'xUbuntu' in the repository URL for Ubuntu installations. ```bash # Get Debian VERSION_ID from os-release file . /etc/os-release echo $VERSION_ID # Download the signing key and install it in a dedicated keyring # Debian Bookworm and older curl http://download.opensuse.org/repositories/home:/jcorporation/Debian_$VERSION_ID/Release.key | gpg --no-default-keyring --keyring /usr/share/keyrings/jcorporation.github.io.gpg --import # Debian Trixie curl http://download.opensuse.org/repositories/home:/jcorporation/Debian_$VERSION_ID/Release.key | gpg --dearmor --output /usr/share/keyrings/jcorporation.github.io.gpg # ⚠️ VERIFY the fingerprint of the downloaded key (A37A ADC4 0A1C C6BE FB75 372F AA09 B8CC E895 BD7D - home:jcorporation OBS Project ) gpg --no-default-keyring --keyring /usr/share/keyrings/jcorporation.github.io.gpg --fingerprint # Make the imported keyring world-readable chmod 644 /usr/share/keyrings/jcorporation.github.io.gpg # Add the myMPD APT repository and ensure releases are signed with the repository's official keys cat < /etc/apt/sources.list.d/jcorporation.list deb [signed-by=/usr/share/keyrings/jcorporation.github.io.gpg] http://download.opensuse.org/repositories/home:/jcorporation/Debian_$VERSION_ID/ ./ EOF cat /etc/apt/sources.list.d/jcorporation.list # Install MyMPD apt update apt install mympd ``` -------------------------------- ### Start first myMPD instance with environment variables Source: https://jcorporation.github.io/myMPD/070-additional-topics/multiple-myMPD-instances-on-same-host.html Configure and start the first myMPD instance, connecting to the MPD socket at /run/mpd1/socket, listening on HTTP port 8001 without SSL, and using /var/lib/mympd1 as the working directory and /var/cache/mympd1 as the cache directory. ```bash export MPD_HOST=/run/mpd1/socket export MYMPD_HTTP_PORT=8001 export MYMPD_SSL=false mympd -w /var/lib/mympd1 -a /var/cache/mympd1 ``` -------------------------------- ### Build myMPD with cmake Source: https://jcorporation.github.io/myMPD/010-installation/compiling/cmake.html Commands to configure, build, and install myMPD. Run cmake as user, build in the 'build' directory, and install with sudo. ```bash # Build as user cmake -B build -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=/usr . # binaries are placed in build/bin cmake --build build # Run install as root sudo cmake --install build ``` -------------------------------- ### Install dependencies via build.sh Source: https://jcorporation.github.io/myMPD/010-installation/compiling/index.html Run this command as root to automatically install build dependencies on supported distributions. ```bash ./build.sh installdeps ``` -------------------------------- ### Start second myMPD instance with environment variables Source: https://jcorporation.github.io/myMPD/070-additional-topics/multiple-myMPD-instances-on-same-host.html Configure and start the second myMPD instance, connecting to the MPD socket at /run/mpd2/socket, listening on HTTP port 8002 and SSL port 4432 with SSL enabled, and using /var/lib/mympd2 as the working directory and /var/cache/mympd2 as the cache directory. ```bash export MPD_HOST=/run/mpd2/socket export MYMPD_HTTP_PORT=8002 export MYMPD_SSL_PORT=4432 export MYMPD_SSL=true mympd -w /var/lib/mympd2 -a /var/cache/mympd2 ``` -------------------------------- ### Start the application Source: https://jcorporation.github.io/myMPD/jsdoc/init.js.html Calls appInitStart to begin the myMPD application initialization. ```javascript appInitStart(); ``` -------------------------------- ### Install myMPD package Source: https://jcorporation.github.io/myMPD/010-installation/compiling/freebsd.html Install the built myMPD package using the pkg manager. ```bash pkg install myMPD ``` -------------------------------- ### Run myMPD on Termux Source: https://jcorporation.github.io/myMPD/010-installation/compiling/termux.html Run myMPD normally after the initial setup; the environment variables are only needed for the first start. ```shell $HOME/myMPD/release/bin/mympd -w $HOME/.config/mympd ``` -------------------------------- ### Start myMPD manually with systemd-run Source: https://jcorporation.github.io/myMPD/030-running.html Starts myMPD in a console session on systems using systemd without a static mympd user. ```bash systemd-run -t -p DynamicUser=yes -p StateDirectory=mympd -p CacheDirectory=mympd /usr/bin/mympd ``` -------------------------------- ### Custom navbar icons examples Source: https://jcorporation.github.io/myMPD/060-references/customization.html Examples of custom navbar icon definitions. The first opens the Filesystem view under Browse, the second opens the Radio Favorites view. ```json { "ligature": "library_music", "title":"Browse", "options": ["Browse", "Filesystem"] }, { "ligature": "radio", "title":"Radio Favorites", "options": ["Browse", "Radio", "Favorites"] } ``` -------------------------------- ### MYMPD_API_PLAYER_PLAY Source: https://jcorporation.github.io/myMPD/060-references/api/methods.html Starts playing. This method is not protected and takes no parameters. ```APIDOC ## MYMPD_API_PLAYER_PLAY ### Description Starts playing. ### Parameters None ``` -------------------------------- ### MEASURE_START Source: https://jcorporation.github.io/myMPD/doxygen/html/lib_2utility_8h.html Starts time measurement by recording the current monotonic clock time. ```APIDOC ## MEASURE_START ### Description Starts time measurement by recording the current monotonic clock time. ### Macro Definition #define MEASURE_START (void)clock_gettime(CLOCK_MONOTONIC, &tic); ``` -------------------------------- ### Select and build myMPD in buildroot Source: https://jcorporation.github.io/myMPD/010-installation/compiling/openwrt.html Use menuconfig to select the package and then run the make command to build it. ```bash make menuconfig make -j$(nproc) BUILD_LOG=1 ``` -------------------------------- ### Example API call: MYMPD_API_PLAYER_STATE Source: https://jcorporation.github.io/myMPD/060-references/api/index.html A JSON-RPC 2 request to get the player state. The id is 0 and params is an empty object. ```json {"jsonrpc":"2.0","id":0,"method":"MYMPD_API_PLAYER_STATE","params":{}} ``` -------------------------------- ### mympd_api_timer_calc_starttime Source: https://jcorporation.github.io/myMPD/doxygen/html/mympd__api_2timer_8h_source.html Calculates the start time for a timer based on the start hour, start minute, and interval. This function returns the start time as an integer. ```APIDOC ## mympd_api_timer_calc_starttime ### Description Calculates the start time for a timer based on the start hour, start minute, and interval. This function returns the start time as an integer. ### Function Signature int mympd_api_timer_calc_starttime(int start_hour, int start_minute, int interval) ### Parameters - **start_hour** (int) - Required - The start hour (0-23). n- **start_minute** (int) - Required - The start minute (0-59). n- **interval** (int) - Required - The interval in seconds. ### Return Value - **int** - Returns the calculated start time. ``` -------------------------------- ### mymp d_api_timer_calc_starttime Source: https://jcorporation.github.io/myMPD/doxygen/html/mympd__api_2timer_8h.html Calculates the offset from now for the next start time for a timer based on the given start hour, start minute, and reschedule interval. ```APIDOC ## mympd_api_timer_calc_starttime ### Description Calculates the offset from now for next start time for a timer. ### Function Signature int mympd_api_timer_calc_starttime(int _start_hour_, int _start_minute_, int _interval_) ### Parameters - **_start_hour_** (int) - Required - Start hour - **_start_minute_** (int) - Required - Start minute - **_interval_** (int) - Required - Reschedule interval ### Returns - **int** - Unix timestamp of next start ``` -------------------------------- ### appInitStart - Start the myMPD app Source: https://jcorporation.github.io/myMPD/jsdoc/init.js.html Initializes the app by loading assets, adding a hashchange event listener for routing, creating pre-generated elements, handling webapp manifest shortcuts, setting up a ResizeObserver for table height updates, setting mobile view, translating the splash screen alert, setting log level based on debugMode, and registering or unregistering the service worker depending on debugMode and protocol. ```JavaScript function appInitStart() { getAssets(); //add app routing event handler window.addEventListener('hashchange', function() { if (app.goto === false) { appRoute(); } else { app.goto = false; } }, false); // create pre-generated elements createPreGeneratedElements(); //webapp manifest shortcuts const params = new URLSearchParams(window.location.search); const action = params.get('action'); switch(action) { case 'clickPlay': clickPlay(); break; case 'clickStop': clickStop(); break; case 'clickNext': clickNext(); break; // No Default } //update table height on window resize const resizeObserver = new ResizeObserver(function() { requestAnimationFrame(() => { const list = elGetById(app.id + 'List'); if (list) { setScrollViewHeight(list); } }); }); resizeObserver.observe(document.querySelector('body')); setMobileView(); i18nHtml(elGetById('splashScreenAlert')); //set loglevel if (debugMode === true) { settings.loglevel = 7; } //serviceworker handling if ('serviceWorker' in navigator) { //add serviceworker if (debugMode === false && window.location.protocol === 'https:') { window.addEventListener('load', function() { navigator.serviceWorker.register('sw.js', {scope: subdir + '/'}).then(function(registration) { //Registration was successful logDebug('ServiceWorker registration successful.'); registration.update(); }, function(err) { //Registration failed logError('ServiceWorker registration failed: ' + err); }); }); } //debugMode - delete serviceworker if (debugMode === true) { let serviceWorkerExists = false; navigator.serviceWorker.getRegistrations().then(function(registrations) { for (const registration of registrations) { registration.unregister(); serviceWorkerExists = true; } if (serviceWorkerExists === true) { clearAndReload(); } }); } } } ``` -------------------------------- ### appInitStart() Source: https://jcorporation.github.io/myMPD/jsdoc/module-init_js.html Starts the app. This function is called to begin the application's main initialization process. ```APIDOC ## appInitStart() ### Description Starts the app. ### Method Function call ### Endpoint appInitStart() ### Parameters None ### Returns void ``` -------------------------------- ### appInit() Source: https://jcorporation.github.io/myMPD/jsdoc/module-init_js.html Initializes the html elements. This function is called to set up the user interface elements during app startup. ```APIDOC ## appInit() ### Description Initializes the html elements. ### Method Function call ### Endpoint appInit() ### Parameters None ### Returns void ``` -------------------------------- ### Initialize partition modal event listeners Source: https://jcorporation.github.io/myMPD/jsdoc/modalPartitions.js.html Sets up click and show event listeners for the partition modal. Handles delete actions and partition switching. ```javascript function initModalPartitions() { elGetById('modalPartitionsPartitionsList').addEventListener('click', function(event) { event.stopPropagation(); event.preventDefault(); if (event.target.nodeName === 'A') { const action = getData(event.target, 'action'); const partition = getData(event.target.parentNode.parentNode, 'partition'); switch(action) { case 'delete': deletePartition(event.target, partition); break; default: logError('Invalid action: ' + action); } return; } const target = event.target.closest('TR'); if (checkTargetClick(target) === true) { switchPartition(getData(target, 'partition')); } }, false); elGetById('modalPartitions').addEventListener('show.bs.modal', function () { showListPartitions(); }); } ``` -------------------------------- ### Show splash screen and initialize app Source: https://jcorporation.github.io/myMPD/jsdoc/init.js.html Displays the splash screen, fetches settings, and initializes the app after settings are parsed. ```javascript //show splash screen elShowId('splashScreen'); domCache.body.classList.add('overflow-hidden'); elGetById('splashScreenAlert').textContent = tn('Fetch myMPD settings'); //initialize app appInited = false; settingsParsed = 'no'; sendAPI("MYMPD_API_SETTINGS_GET", {}, function(obj) { parseSettings(obj); if (settingsParsed === 'parsed') { //connect to websocket in background setTimeout(function() { webSocketConnect(); }, 0); //app initialized elGetById('splashScreenAlert').textContent = tn('Applying settings'); elGetById('splashScreen').classList.add('hide-fade'); setTimeout(function() { elHideId('splashScreen'); elGetById('splashScreen').classList.remove('hide-fade'); domCache.body.classList.remove('overflow-hidden'); }, 500); appInit(); appInited = true; appRoute(); logDebug('Startup duration: ' + (Date.now() - startTime) + 'ms'); } }, true); ``` -------------------------------- ### Notifications: mympd.notify_client and mympd.notify_partition Source: https://jcorporation.github.io/myMPD/050-scripting/functions/util.html Sends a notification to the client that started the script or to all clients in the partition from which the client started the script. Severity can be a number or string. ```lua -- Send a notification to the client that has started the script mympd.notify_client(severity, message) -- Send a notification to all clients in the partition from which the client started the script mympd.notify_partition(severity, message) ``` -------------------------------- ### initViewBrowseFilesystem Source: https://jcorporation.github.io/myMPD/jsdoc/viewBrowseFilesystem.js.html Initializes the browse filesystem view, sets up breadcrumb click listeners, and activates the view. ```javascript function initViewBrowseFilesystem() { initSearchSimple('BrowseFilesystem'); elGetById('BrowseFilesystemBreadcrumb').addEventListener('click', function(event) { if (event.target.nodeName === 'A') { event.preventDefault(); const uri = getData(event.target, 'uri'); const offset = browseFilesystemHistory[uri] !== undefined ? browseFilesystemHistory[uri].offset : 0; const scrollPos = browseFilesystemHistory[uri] !== undefined ? browseFilesystemHistory[uri].scrollPos : 0; appGoto('Browse', 'Filesystem', undefined, offset, app.current.limit, uri, app.current.sort, 'dir', '', scrollPos); } }, false); setView('BrowseFilesystem'); } ``` -------------------------------- ### Create directories for myMPD images Source: https://jcorporation.github.io/myMPD/070-additional-topics/mpd-satellite-setup.html Initializes the background and thumbnail directories for myMPD images on the central server. ```bash mkdir /srv/mpd/images/backgrounds /srv/mpd/images/thumbs ``` -------------------------------- ### removeFromQueueRange(start, endopt) Source: https://jcorporation.github.io/myMPD/jsdoc/module-queue_js.html Removes a range of songs from the queue. The start parameter is inclusive, and the optional end parameter is exclusive; use -1 for an open end. ```APIDOC ## removeFromQueueRange(start, endopt) ### Description Removes a song range from the queue. ### Method Function call ### Parameters - **start** (number) - Required - Start of the range (including). - **end** (number) - Optional - End of the range (excluding), -1 for open end. ### Returns void ``` -------------------------------- ### log_init(void) Source: https://jcorporation.github.io/myMPD/doxygen/html/log_8c.html Initializes the logging sub-system. This function should be called before using other logging functions. ```APIDOC ## log_init(void) ### Description Initializes the logging sub-system. ### Parameters None. ``` -------------------------------- ### mympd.tmpvar_get Source: https://jcorporation.github.io/myMPD/jsdoc/globales.js.html Get a tmp variable. ```lua local value, expiration = mympd.tmpvar_get(key) ``` -------------------------------- ### handleHome function Source: https://jcorporation.github.io/myMPD/jsdoc/viewHome.js.html Initializes the home screen by requesting the icon list from the API. ```javascript function handleHome() { sendAPI("MYMPD_API_HOME_ICON_LIST", {}, parseHomeIcons, false); } ``` -------------------------------- ### getTimestamp() Source: https://jcorporation.github.io/myMPD/jsdoc/module-utility_js.html Gets a unix timestamp. ```APIDOC ## getTimestamp() ### Description Gets a unix timestamp. ### Returns - **number** - the unix timestamp ``` -------------------------------- ### Create PulseAudio systemd unit file and enable service Source: https://jcorporation.github.io/myMPD/070-additional-topics/multiroom-audio-using-pulseaudio-rtp.html Create a systemd unit file for PulseAudio to run as a system service, then reload and enable it. ```bash # cat < /lib/systemd/system/pulseaudio.service [Unit] Description=PulseAudio Daemon After=network.target [Install] WantedBy=multi-user.target [Service] Type=simple PrivateTmp=true ExecStart=/usr/bin/pulseaudio --system --realtime --disallow-exit --no-cpu-limit --disable-shm EOF systemctl daemon-reload systemctl enable pulseaudio ``` -------------------------------- ### stickerdb_find_stickers_by_name() Source: https://jcorporation.github.io/myMPD/doxygen/html/stickerdb_8h.html Gets all stickers by name. ```APIDOC ## stickerdb_find_stickers_by_name() ### Description Gets all stickers by name. ### Function Signature rax * stickerdb_find_stickers_by_name(struct t_stickerdb_state *_stickerdb_, enum mympd_sticker_type _type_, const char *_name_) ### Parameters - **_stickerdb_** (struct t_stickerdb_state *) - pointer to the stickerdb state - **_type_** (enum mympd_sticker_type) - MPD sticker type - **_name_** (const char *) - sticker name ### Returns - **rax *** - newly allocated radix tree or NULL on error ``` -------------------------------- ### getScriptList Source: https://jcorporation.github.io/myMPD/jsdoc/modalScripts.js.html Gets the list of scripts from the API. ```javascript function getScriptList(all) { sendAPI("MYMPD_API_SCRIPT_LIST", { "all": all }, parseScriptList, true); } ``` -------------------------------- ### Download OpenWrt SDK dependencies Source: https://jcorporation.github.io/myMPD/010-installation/compiling/openwrt.html Run these commands within the unpacked OpenWrt SDK directory to fetch the necessary package recipes. ```bash scripts/feeds update -a scripts/feeds install libflac libid3tag liblua5.3 libopenssl libpcre2 ``` -------------------------------- ### stickerdb_get_names() Source: https://jcorporation.github.io/myMPD/doxygen/html/stickerdb_8c.html Gets all sticker names by type. ```APIDOC ## stickerdb_get_names() ### Description Gets all sticker names by type ### Function Signature bool stickerdb_get_names(struct t_stickerdb_state * _stickerdb_, enum mympd_sticker_type _type_, struct t_list * _sticker_names_) ### Parameters - **stickerdb** (struct t_stickerdb_state *) - Required - pointer to the stickerdb state - **type** (enum mympd_sticker_type) - Required - MPD sticker type - **sticker_names** (struct t_list *) - Required - List to populate ### Returns true on success, else false ``` -------------------------------- ### initLocalPlayback() → {void} Source: https://jcorporation.github.io/myMPD/jsdoc/module-localplayback_js.html Initializes the local playback related elements. ```APIDOC ## initLocalPlayback() → {void} ### Description Initializes the local playback related elements. ### Parameters None. ### Returns - **void** - No return value. ### Source - localplayback.js, line 12 ``` -------------------------------- ### stickerdb_get_int64() Source: https://jcorporation.github.io/myMPD/doxygen/html/stickerdb_8c.html Gets an int64_t value sticker. ```APIDOC ## stickerdb_get_int64() ### Description Gets an int64_t value sticker. ### Function Signature int64_t stickerdb_get_int64(struct t_stickerdb_state * _stickerdb_, enum mympd_sticker_type _type_, const char * _uri_, const char * _name_) ### Parameters - **stickerdb** (struct t_stickerdb_state *) - Required - pointer to the stickerdb state - **type** (enum mympd_sticker_type) - Required - MPD sticker type - **uri** (const char *) - Required - sticker uri - **name** (const char *) - Required - sticker name ### Returns sticker value or 0 on error ``` -------------------------------- ### stickerdb_find_stickers_by_name_value() Source: https://jcorporation.github.io/myMPD/doxygen/html/stickerdb_8h.html Gets all stickers by name and value. ```APIDOC ## stickerdb_find_stickers_by_name_value() ### Description Gets all stickers by name and value. ### Function Signature rax * stickerdb_find_stickers_by_name_value(struct t_stickerdb_state *_stickerdb_, enum mympd_sticker_type _type_, const char *_name_, enum mpd_sticker_operator _op_, const char *_value_) ### Parameters - **_stickerdb_** (struct t_stickerdb_state *) - pointer to the stickerdb state - **_type_** (enum mympd_sticker_type) - MPD sticker type - **_name_** (const char *) - sticker name - **_op_** (enum mpd_sticker_operator) - compare operator: MPD_STICKER_OP_EQ, MPD_STICKER_OP_GT, MPD_STICKER_OP_LT - **_value_** (const char *) - sticker value ### Returns - **rax *** - newly allocated radix tree or NULL on error ``` -------------------------------- ### Initialize Playback View Source: https://jcorporation.github.io/myMPD/jsdoc/viewPlayback.js.html Sets up event listeners for the playback list tags to enable navigation. ```javascript function initViewPlayback() { elGetById('PlaybackListTags').addEventListener('click', function(event) { if ((event.target.nodeName === 'P' && event.target.classList.contains('clickable') === true) || (event.target.nodeName === 'SPAN' && event.target.parentNode.classList.contains('clickable') === true) ) { gotoBrowse(event); } }, false); } ``` -------------------------------- ### album_cache_get_album Source: https://jcorporation.github.io/myMPD/doxygen/html/cache__rax__album_8c.html Gets the album from the album cache. ```APIDOC ## album_cache_get_album ### Description Gets the album from the album cache. ### Function Signature struct t_album *album_cache_get_album(struct t_cache *album_cache, sds key) ### Parameters - **album_cache** (struct t_cache*) - Pointer to t_cache struct. - **key** (sds) - The album key. ### Returns mpd_song struct representing the album or NULL on error. ``` -------------------------------- ### gotoFilesystem function Source: https://jcorporation.github.io/myMPD/jsdoc/browse.js.html Navigates to the filesystem view by clearing the search string and calling appGoto with the specified URI and type. ```javascript function gotoFilesystem(uri, type) { elGetById('BrowseFilesystemSearchStr').value = ''; appGoto('Browse', 'Filesystem', undefined, 0, undefined, uri, {'tag':'', 'desc': false}, type, ''); } ``` -------------------------------- ### album_get_unknown Source: https://jcorporation.github.io/myMPD/doxygen/html/album_8c.html Gets the unknown marker for an album. ```APIDOC ## album_get_unknown() ### Description Gets the unknown marker for an album. ### Function Signature bool album_get_unknown(const struct t_album *album) ### Parameters - **album** (const struct t_album *) - Required - t_album struct representing the album. ### Returns - **bool** - True if it is an unknown album, else false. ``` -------------------------------- ### Initializes outputs HTML elements (initOutputs) Source: https://jcorporation.github.io/myMPD/jsdoc/outputs.js.html Sets up event listeners for the volume slider and the outputs dropdown. It sends MYMPD_API_PLAYER_OUTPUT_LIST when the volume menu is shown, handles clicks on the output list to either toggle an output or open attributes, and toggles the button state. ```javascript "use strict"; // SPDX-License-Identifier: GPL-3.0-or-later // myMPD (c) 2018-2026 Juergen Mang // https://github.com/jcorporation/mympd // @module outputs_js function initOutputs() { domCache.volumeBar.addEventListener('change', function() { setVolume(); }, false); elGetById('volumeMenu').parentNode.addEventListener('show.bs.dropdown', function() { sendAPI("MYMPD_API_PLAYER_OUTPUT_LIST", {}, parseOutputs, true); }); elGetById('outputs').addEventListener('click', function(event) { if (event.target.nodeName === 'A') { event.preventDefault(); BSN.Dropdown.getInstance(elGetById('volumeMenu')).toggle(); showModalOutputAttributes(getData(event.target.parentNode, 'output-name')); } else { const target = event.target.nodeName === 'BUTTON' ? event.target : event.target.parentNode; event.preventDefault(); sendAPI("MYMPD_API_PLAYER_OUTPUT_TOGGLE", { "outputId": Number(getData(target, 'output-id')), "enabled": (target.classList.contains('active') ? false : true) }, null, false); toggleBtn(target, undefined); } }, false); } ``` -------------------------------- ### Initialize Modal Partition Outputs Source: https://jcorporation.github.io/myMPD/jsdoc/modalPartitionOutputs.js.html Initializes the event listeners for the partition outputs modal, including click handling for selection and loading data when the modal is shown. ```javascript function initModalPartitionOutputs() { elGetById('modalPartitionOutputsList').addEventListener('click', function(event) { event.stopPropagation(); event.preventDefault(); if (event.target.nodeName === 'BUTTON') { toggleBtnChk(event.target, undefined); } else if (event.target.nodeName === 'TD') { const target = event.target.parentNode.firstChild.firstChild; toggleBtnChk(target, undefined); } }, false); elGetById('modalPartitionOutputs').addEventListener('show.bs.modal', function() { //get all outputs sendAPIpartition("default", "MYMPD_API_PLAYER_OUTPUT_LIST", {}, function(allOutputs) { const outputList = elGetById('modalPartitionOutputsList'); if (checkResult(allOutputs, outputList, 'modalTable') === false) { return; } //get partition specific outputs sendAPI("MYMPD_API_PLAYER_OUTPUT_LIST", {}, function(partitionOutputs) { parsePartitionOutputsList(allOutputs, partitionOutputs); uiElements.modalPartitionOutputs.show(); }, true); }, true); }); } ``` -------------------------------- ### dirname(uri) Source: https://jcorporation.github.io/myMPD/jsdoc/module-utility_js.html Gets the directory from the given uri. ```APIDOC ## dirname(uri) ### Description Gets the directory from the given uri. ### Parameters - **uri** (string) - Required - the uri ### Returns - **string** - directory part of the uri ``` -------------------------------- ### Initialize myMPD status with mympd.init() Source: https://jcorporation.github.io/myMPD/050-scripting/functions/mympd_init.html Call this function to populate the mympd_state table with the current configuration and status values of myMPD and MPD. It returns a response code and a result table. ```lua mympd.init() ``` -------------------------------- ### mympd_api_get_elapsed_seconds Source: https://jcorporation.github.io/myMPD/doxygen/html/status_8h.html Function to get elapsed seconds from mpd_status. ```APIDOC ## mympd_api_get_elapsed_seconds ### Description Replacement for deprecated mpd_status_get_elapsed_time. Returns the elapsed seconds from the given mpd_status struct. ### Signature unsigned mympd_api_get_elapsed_seconds(struct mpd_status *status) ### Parameters - **status** (struct mpd_status *) - Required - Pointer to mpd_status struct. ### Returns - **unsigned** - Elapsed seconds. ``` -------------------------------- ### json_get_int64() Source: https://jcorporation.github.io/myMPD/doxygen/html/json__query_8h.html Gets an int64_t value by json path. ```APIDOC ## json_get_int64() ### Description Gets an int64_t value by json path. ### Function Signature bool json_get_int64(sds _s_, const char *_path_, int64_t _min_, int64_t _max_, int64_t *_result_, struct t_json_parse_error *_error_) ### Parameters - **s** (sds) - Required - json object to parse - **path** (const char *) - Required - mjson path expression - **min** (int64_t) - Required - minimum value (including) - **max** (int64_t) - Required - maximum value (including) - **result** (int64_t *) - Required - pointer to int64_t with the result - **error** (struct t_json_parse_error *) - Required - pointer to t_json_parse_error ### Returns - **bool** - true on success, else false ``` -------------------------------- ### mympd.init() Source: https://jcorporation.github.io/myMPD/050-scripting/functions/mympd_init.html Populates the lua table mympd_state with configuration values and current status of myMPD and MPD. No parameters required. ```APIDOC ## mympd.init() ### Description Populates the lua table `mympd_state` with configuration values and current status of myMPD and MPD. ### Method Function call ### Endpoint mympd.init() ### Parameters No parameters required. ### Returns | FIELD | TYPE | DESCRIPTION | |-------|------|-------------| | rc | integer | response code: 0 = success, 1 = error | | result | lua table | jsonrpc result or error as lua table | ### mympd_state Table The lua table `mympd_state` is populated with the following fields: | KEY | TYPE | DESCRIPTION | |-----|------|-------------| | `auto_play` | Boolean | true = enabled, false = disabled | | `consume_state` | Integer | MPD consume state: 0 = off, 1 = on, 2 = oneshot, 3 = unknown | | `current_album` | String | myMPD AlbumId | | `crossfade` | Integer | MPD crossfade option | | `current_song` | Table | Current MPD song | | `elapsed_time` | Integer | Elapsed time of current song | | `jukebox_ignore_hated` | Boolean | Ignore hated songs for jukebox | | `jukebox_last_played` | Integer | Don’t add songs that are played in the last x hours | | `jukebox_max_song_duration` | Integer | Only songs with this minimum length will be considered. | | `jukebox_min_song_duration` | Integer | If greater then zero: Only songs with this maximum length will be considered. | | `jukebox_mode` | Integer | Jukebox mode: 0 = off, 1 = song, 2 = album, 3 = script | | `jukebox_playlist` | String | Jukebox playlist: Database or MPD playlist name | | `jukebox_queue_length` | Integer | Number of songs in the queue before the jukebox add’s more songs. | | `jukebox_uniq_tag` | String | Build the jukebox queue with this tag as uniq constraint: Song, Album, Artist | | `listenbrainz_token` | String | ListenBrainz Token | | `mixrampdelay` | Float | Mixramp delay | | `mixrampdb` | Float | Mixramp DB | | `music_directory` | String | Path to the mpd music directory | | `mympd_uri` | String | Canonical myMPD uri | | `mympd_uri_plain` | String | Canonical myMPD uri (http://) | | `next_song_id` | Integer | Next song id in queue | | `next_song_pos` | Integer | Next song position in queue | | `play_state` | Integer | Player state: 0 = unknown, 1 = stop, 2 = play, 3 = pause | | `playlist_directory` | String | path to the mpd playlist directory | | `queue_length` | Integer | Length of the queue | | `queue_version` | Integer | Version of the queue | | `repeat` | Boolean | MPD repeat option | | `replaygain` | Integer | 0 = off, 1 = track, 2 = album, 3 = auto, 4 = unknown | | `random` | Boolean | MPD random option | | `single_state` | Integer | MPD single state: 0 = off, 1 = on, 2 = oneshot, 3 = unknown | | `song_id` | Integer | Song id of current song | | `song_pos` | Integer | Current song position in queue | | `start_time` | Integer | Current song start playing timestamp | | `total_time` | Integer | Total time of current song | | `volume` | Integer | 0 - 100 percent | ### mympd_state.current_song | KEY | TYPE | DESCRIPTION | |-----|------|-------------| | `uri` | String | Song uri | | `Duration` | Integer | Song duration in seconds | | Tag | Tag value(s) | MPD tag name with values. | ``` -------------------------------- ### json_get_int() Source: https://jcorporation.github.io/myMPD/doxygen/html/json__query_8h.html Gets an int value by json path. ```APIDOC ## json_get_int() ### Description Gets an int value by json path. ### Function Signature bool json_get_int(sds _s_, const char *_path_, int _min_, int _max_, int *_result_, struct t_json_parse_error *_error_) ### Parameters - **s** (sds) - Required - json object to parse - **path** (const char *) - Required - mjson path expression - **min** (int) - Required - minimum value (including) - **max** (int) - Required - maximum value (including) - **result** (int *) - Required - pointer to int with the result - **error** (struct t_json_parse_error *) - Required - pointer to t_json_parse_error ### Returns - **bool** - true on success, else false ``` -------------------------------- ### initModalAbout: Populate shortcuts tab and add modal event listener Source: https://jcorporation.github.io/myMPD/jsdoc/modalAbout.js.html Initializes the about modal by clearing the shortcuts tab, sorting keymap entries by order, and rendering each key or section header. Adds a 'show.bs.modal' event listener that sends MYMPD_API_STATS and calls getServerinfo(). ```javascript function initModalAbout() { const tab = elGetById('modalAboutTabShortcuts'); elClear(tab); const keys = Object.keys(keymap).sort((a, b) => { return keymap[a].order - keymap[b].order; }); for (const key of keys) { if (keymap[key].cmd === undefined) { tab.appendChild( elCreateNode('div', {"class": ["row", "mb-2", "mt-3"]}, elCreateNode('div', {"class": ["col-12"]}, elCreateTextTn('h5', {}, keymap[key].desc) ) ) ); tab.appendChild( elCreateEmpty('div', {"class": ["row"]}) ); continue; } const col = elCreateEmpty('div', {"class": ["col", "col-6", "mb-3", "align-items-center"]}); if (keymap[key].feature !== undefined) { col.classList.add(keymap[key].feature); } const k = elCreateText('div', {"class": ["key", "float-start", "rounded-2"]}, (keymap[key].key !== undefined ? keymap[key].key : key)); if (keymap[key].key && keymap[key].key.length > 1) { k.classList.add('mi', 'mi-sm'); } col.appendChild(k); col.appendChild( elCreateTextTn('div', {}, keymap[key].desc) ); tab.lastChild.appendChild(col); } elGetById('modalAbout').addEventListener('show.bs.modal', function () { sendAPI("MYMPD_API_STATS", {}, parseStats, false); getServerinfo(); }, false); } ``` -------------------------------- ### Application Settings Initialization Source: https://jcorporation.github.io/myMPD/jsdoc/settings.js.html Initializes preset dropdowns, notification severity, and MPD connection status. ```javascript //presets populatePresetDropdowns(); // Set severity for filtering notifications and logs elGetById('modalNotificationsSeveritySelect').value = settings.loglevel; //parse mpd settings if connected if (settings.partition.mpdConnected === true) { parseMPDSettings(); } else { logWarn('Skip parsing MPD settings'); } ``` -------------------------------- ### MYMPD_API_SCRIPT_TMP_GET Source: https://jcorporation.github.io/myMPD/060-references/api/methods.html Gets a temporary variable. This method is not protected. ```APIDOC ## MYMPD_API_SCRIPT_TMP_GET ### Description Gets a temporary variable. ### Parameters #### Request Body - **key** (String) - Required - Variable name. Example: tmp-var ``` -------------------------------- ### MYMPD_API_SCRIPT_GET Source: https://jcorporation.github.io/myMPD/060-references/api/methods.html Gets options from a timer. This method is not protected. ```APIDOC ## MYMPD_API_SCRIPT_GET ### Description Gets options from a timer. ### Parameters #### Request Body - **script** (String) - Required - Name of the script. Example: testscript ``` -------------------------------- ### Script with arguments: load playlist and broadcast message Source: https://jcorporation.github.io/myMPD/050-scripting/index.html Shows how to use a script argument named 'playlist' and broadcast a message to all connected clients. ```lua -- load a playlist mympd.api("MYMPD_API_QUEUE_REPLACE_PLAYLIST", {plist = mympd_arguments.playlist}) -- start playing mympd.api("MYMPD_API_PLAYER_PLAY") -- broadcast message to all connected myMPD clients return("Loaded playlist:" .. mympd_arguments.playlist) ``` -------------------------------- ### mympd_api_settings_get() Source: https://jcorporation.github.io/myMPD/doxygen/html/settings_8h.html Prints all settings. This function takes the mympd state, partition state, a buffer to append the response, and a request ID, and returns the pointer to the buffer. ```APIDOC ## mympd_api_settings_get() ### Description Prints all settings. ### Function Signature sds mympd_api_settings_get(struct t_mympd_state *mympd_state, struct t_partition_state *partition_state, sds buffer, unsigned request_id) ### Parameters - **mympd_state** (struct t_mympd_state *) - Required - Pointer to mympd state. - **partition_state** (struct t_partition_state *) - Required - Pointer to partition state. - **buffer** (sds) - Required - Already allocated sds string to append the response. - **request_id** (unsigned) - Required - JSON-RPC request id. ### Returns - **sds** - Pointer to buffer. ``` -------------------------------- ### MYMPD_API_LYRICS_GET Source: https://jcorporation.github.io/myMPD/060-references/api/methods.html Gets all lyrics from uri. This method is not protected. ```APIDOC ## MYMPD_API_LYRICS_GET ### Description Gets all lyrics from uri. ### Protected No ### Parameters #### Query Parameters - **uri** (String) - Required - Relativ song uri. Example: Alben/Einstürzende_Neubauten/Ende_Neu/01.Was_ist_ist.mp3 ``` -------------------------------- ### initModalHomeWidget() → {void} Source: https://jcorporation.github.io/myMPD/jsdoc/module-modalHomeWidget_js.html Initializes the modalHomeWidget. No parameters are required. ```APIDOC ## initModalHomeWidget() → {void} ### Description Initializes the modalHomeWidget. ### Method Function call ### Parameters None ### Returns void ### Source modalHomeWidget.js, line 12 ``` -------------------------------- ### get_lua_global_config Source: https://jcorporation.github.io/myMPD/doxygen/html/interface_8h.html Gets the config struct from lua userdata. ```APIDOC ## get_lua_global_config ### Description Gets the config struct from lua userdata. ### Function Signature struct t_config * get_lua_global_config(lua_State *lua_vm) ### Parameters - **lua_vm** (lua_State*) - Required - lua instance ### Returns - pointer to mympd config struct ``` -------------------------------- ### Build myMPD package with SDK Source: https://jcorporation.github.io/myMPD/010-installation/compiling/openwrt.html Execute the make command to compile the package after copying the packaging files into the SDK directory. ```bash make -j$(nproc) BUILD_LOG=1 ``` -------------------------------- ### album_get_total_time Source: https://jcorporation.github.io/myMPD/doxygen/html/album_8c.html Gets the album duration from the album struct. ```APIDOC ## album_get_total_time() ### Description Gets the album duration. ### Function Signature unsigned album_get_total_time(const struct t_album *album) ### Parameters - **album** (const struct t_album *) - Required - t_album struct representing the album. ### Returns - **unsigned** - Album duration. ``` -------------------------------- ### mympd.gpio_get(gpio) Source: https://jcorporation.github.io/myMPD/050-scripting/functions/mygpiod.html Gets the active state of a GPIO. ```APIDOC ## mympd.gpio_get(gpio) ### Description Gets the active state of a GPIO. ### Parameters - **gpio** (integer) - Required - The GPIO number. ### Return Value - **state** (string) - The active state ("active" or "inactive"). ### Example ```lua local state = mympd.gpio_get(gpio) ``` ``` -------------------------------- ### signal_eventfd_init Source: https://jcorporation.github.io/myMPD/doxygen/html/signal_8h.html Initializes the eventfd and installs a minimal signal handler for SIGTERM, SIGINT, and SIGHUP. Returns true on success, else false. ```APIDOC ## signal_eventfd_init ### Description Initializes the eventfd and installs a minimal signal handler for SIGTERM, SIGINT, and SIGHUP. ### Function Signature bool signal_eventfd_init(void) ### Parameters None ### Returns - **bool** - true on success, else false ``` -------------------------------- ### mympd_api_timer_calc_starttime Source: https://jcorporation.github.io/myMPD/doxygen/html/mympd__api_2timer_8c.html Calculates the offset from now for the next start time for a timer. ```APIDOC ## mympd_api_timer_calc_starttime ### Description Calculates the offset from now for the next start time for a timer. ### Function Signature int mympd_api_timer_calc_starttime(int _start_hour_, int _start_minute_, int _interval_) ### Parameters - **_start_hour_** (int) - Required - Start hour. - **_start_minute_** (int) - Required - Start minute. - **_interval_** (int) - Required - Reschedule interval. ### Returns - **int** - Unix timestamp of next start. ``` -------------------------------- ### Switch to a partition and save to localStorage Source: https://jcorporation.github.io/myMPD/jsdoc/modalPartitions.js.html Sets the current partition in local settings and attempts to persist it to localStorage. Logs an error if saving fails. ```javascript function switchPartition(partition) { //save localSettings in browsers localStorage localSettings.partition = partition; try { localStorage.setItem('partition', partition); } catch(err) { const obj = { "error": { "message": "Can not save settings to localStorage: %{error}", "data": { "error": err.message } } }; } } ``` -------------------------------- ### Show new partition tab Source: https://jcorporation.github.io/myMPD/jsdoc/modalPartitions.js.html Switches the modal to the 'new partition' tab, clears the name input, and focuses it. ```javascript function showNewPartition() { cleanupModalId('modalPartitions'); elGetById('modalPartitionsListTab').classList.remove('active'); elGetById('modalPartitionsNewTab').classList.add('active'); elHideId('modalPartitionsListFooter'); elShowId('modalPartitionsNewFooter'); const nameEl = elGetById('modalPartitionsNameInput'); nameEl.value = ''; setFocus(nameEl); } ``` -------------------------------- ### jsonrpc_notify_start() Source: https://jcorporation.github.io/myMPD/doxygen/html/json__rpc_8h.html Creates the start of a JSON-RPC notification with a specified event. ```APIDOC ## jsonrpc_notify_start() ### Description Creates the start of a jsonrpc notification. ### Signature sds jsonrpc_notify_start(sds _buffer_, enum jsonrpc_events _event_) ### Parameters - **buffer** (sds) - Required - pointer to already allocated sds string - **event** (enum jsonrpc_events) - Required - the event to use ### Returns pointer to buffer with jsonrpc string ``` -------------------------------- ### http_client_response_init() Source: https://jcorporation.github.io/myMPD/doxygen/html/http__client_8h.html Initializes the mg_client_response_t structure. ```APIDOC ## Function: http_client_response_init() ### Description Initializes the http_client_response_t structure. ### Signature ```c void http_client_response_init(struct mg_client_response_t *mg_client_response) ``` ### Parameters - **mg_client_response** (struct mg_client_response_t*) - pointer to the response structure to initialize ### Returns Nothing (void) ``` -------------------------------- ### Configure MPD on central server (/etc/mpd.conf) Source: https://jcorporation.github.io/myMPD/070-additional-topics/mpd-satellite-setup.html Sets the music and playlist directories and defines the database plugin and sticker file location on the central server. ```text music_directory "/srv/mpd/music" playlist_directory "/srv/mpd/playlists" database { plugin "simple" path "/var/lib/mpd/tag_cache" cache_directory "/var/lib/mpd/cache" } sticker_file "/var/lib/mpd/sticker.sql" bind_to_address "0.0.0.0" ``` -------------------------------- ### getScrollPosY(elopt) → {number} Source: https://jcorporation.github.io/myMPD/jsdoc/module-elements_js.html Gets the y-scrolling position. ```APIDOC ## getScrollPosY(elopt) → {number} ### Description Gets the y-scrolling position. ### Parameters - `el` (HTMLElement | Element) - Optional - element ### Returns - the vertical scrolling position (number) ``` -------------------------------- ### getBtnChkValueId(id) Source: https://jcorporation.github.io/myMPD/jsdoc/module-elements_js.html Gets the enabled state of a check button. ```APIDOC ## getBtnChkValueId(id) ### Description Gets the enabled state of a check button. ### Parameters - **id** (string) - Required - check button id ### Returns - **boolean** - enabled = true, disabled = false ``` -------------------------------- ### list_init() Source: https://jcorporation.github.io/myMPD/doxygen/html/list_8c.html Inits an already allocated list. ```APIDOC ## list_init() ### Description Inits an already allocated list. ### Signature void list_init(struct t_list *l) ### Parameters - **l** (struct t_list *) - Pointer to the list to initialize. ``` -------------------------------- ### getBtnChkValue(btn) Source: https://jcorporation.github.io/myMPD/jsdoc/module-elements_js.html Gets the enabled state of a check button. ```APIDOC ## getBtnChkValue(btn) ### Description Gets the enabled state of a check button. ### Parameters - **btn** (HTMLElement | EventTarget) - Required - check button id ### Returns - **boolean** - enabled = true, disabled = false ```