Greasy Fork is available in English.

Download Icon Adder for Suno.ai

Add download icons for songs on Suno.ai

// ==UserScript==
// @name           Download Icon Adder for Suno.ai
// @name:en        Download Icon Adder for Suno.ai
// @namespace      http://tampermonkey.net/
// @version        0.1.4
// @description    Add download icons for songs on Suno.ai
// @description:en Add download icons for songs on Suno.ai
// @author         aspen138
// @match          *://*.suno.ai/*
// @match          *://*.suno.com/*
// @grant          none
// @icon           https://www.google.com/s2/favicons?sz=64&domain=suno.ai
// @license        MIT
// ==/UserScript==




(function() {
    'use strict';

    // Function to create a download button
    function createDownloadButton(downloadURL, fileType) {
        let button = document.createElement('button');
        button.innerText = fileType.toUpperCase();
        button.onclick = function() { window.open(downloadURL, '_blank').focus(); };
        button.style.marginLeft = '5px';
        button.style.fontSize = '12px';
        button.style.padding = '5px';
        return button;
    }

    // Function to extract song ID and add download buttons
    function addDownloadButtons() {
        // Updated regex pattern to correct the domain name and match the song ID
        const regexPattern = /https:\/\/suno\.com\/song\/([a-zA-Z0-9-]+)/;
        // Updated cssSelector for matching the element to append the download button
        const cssSelector= '.css-1f1sfso';
        document.querySelectorAll(cssSelector).forEach(function(element) {
            let match = regexPattern.exec(window.location.href);
            if (match && match[1] && !element.dataset.downloadsAdded) {
                let songId = match[1];
                let mp3DownloadURL = `https://cdn1.suno.ai/${songId}.mp3`;
                let mp4DownloadURL = `https://cdn1.suno.ai/${songId}.mp4`;

                let mp3Button = createDownloadButton(mp3DownloadURL, 'mp3');
                let mp4Button = createDownloadButton(mp4DownloadURL, 'mp4');

                element.insertAdjacentElement('afterend', mp3Button);
                element.insertAdjacentElement('afterend', mp4Button);
                element.dataset.downloadsAdded = true; // Mark the element to prevent duplicate buttons
            }
        });
    }

    // MutationObserver to handle dynamic content loading
    const observer = new MutationObserver(function(mutations) {
        mutations.forEach(function(mutation) {
            if (mutation.type === 'childList') {
                addDownloadButtons(); // Re-run when DOM changes are detected
            }
        });
    });

    // Specify what to observe
    const config = { childList: true, subtree: true };

    // Start observing the body for changes
    observer.observe(document.body, config);

    // Initial invocation
    addDownloadButtons();
})();