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.5
// @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-]+)/;
        // Select the button with unique classes and then get its parent div
        const buttons = document.querySelectorAll('button.bg-primary.text-vinylBlack-darker');
        buttons.forEach(function(button) {
            let parentDiv = button.parentElement;
            if (!parentDiv.dataset.downloadsAdded) {
                let match = regexPattern.exec(window.location.href);
                if (match && match[1]) {
                    let songId = match[1];
                    let mp3DownloadURL = `https://cdn1.suno.ai/${songId}.mp3`;
                    let mp4DownloadURL = `https://cdn1.suno.ai/${songId}.mp4`;

                    console.log("mp3DownloadURL=", mp3DownloadURL);
                    console.log("mp4DownloadURL=", mp4DownloadURL);

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

                    parentDiv.insertAdjacentElement('afterend', mp3Button);
                    parentDiv.insertAdjacentElement('afterend', mp4Button);
                    parentDiv.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();
})();