Please bookmark this page to avoid losing your image tool!

Android Ringtone MP3 Audio Player

(Free & Supports Bulk Upload)

Drag & drop your images here or

The result will appear here...
You can edit the below JavaScript code to customize the image tool.
function processImage(originalImg, title = "Ringtone.mp3", themeColor = "#4CAF50") {
    // 1. Create a data URL from the original image for the album art and background
    const canvas = document.createElement('canvas');
    canvas.width = originalImg.width || 300;
    canvas.height = originalImg.height || 300;
    const ctx = canvas.getContext('2d');
    ctx.drawImage(originalImg, 0, 0, canvas.width, canvas.height);
    const imgDataUrl = canvas.toDataURL('image/png');

    // 2. Generate a synthetic Android-style Ringtone (WAV format encoded in JS)
    // 6 seconds duration: double chime, pause, double chime, pause
    const sampleRate = 22050; 
    const duration = 6; 
    const numSamples = sampleRate * duration;
    const buffer = new ArrayBuffer(44 + numSamples * 2);
    const view = new DataView(buffer);

    // Helper to write WAV strings
    const writeString = (view, offset, string) => {
        for (let i = 0; i < string.length; i++) {
            view.setUint8(offset + i, string.charCodeAt(i));
        }
    };

    // Write WAV header
    writeString(view, 0, 'RIFF');
    view.setUint32(4, 36 + numSamples * 2, true);
    writeString(view, 8, 'WAVE');
    writeString(view, 12, 'fmt ');
    view.setUint32(16, 16, true);
    view.setUint16(20, 1, true); // PCM Format
    view.setUint16(22, 1, true); // Mono
    view.setUint32(24, sampleRate, true);
    view.setUint32(28, sampleRate * 2, true); // Byte rate
    view.setUint16(32, 2, true); // Block align
    view.setUint16(34, 16, true); // Bits per sample
    writeString(view, 36, 'data');
    view.setUint32(40, numSamples * 2, true);

    // Synthesize the ringtone audio data
    let offset = 44;
    for (let i = 0; i < numSamples; i++) {
        const t = i / sampleRate;
        let sample = 0;
        const cycle = t % 3.0; // 3 seconds loop cycle

        // A pleasant double-chirp ringing pattern
        if (cycle < 1.0) {
            if ((cycle > 0.0 && cycle < 0.3) || (cycle > 0.4 && cycle < 0.7)) {
                // Electronic chime frequencies
                sample = (Math.sin(t * 2 * Math.PI * 800) + Math.sin(t * 2 * Math.PI * 1040)) * 0.5;
                
                // Add an envelope mapping to avoid audio clicks
                let localT = cycle > 0.4 ? cycle - 0.4 : cycle;
                let env = 1;
                if (localT < 0.05) env = localT / 0.05; // Attack
                else if (localT > 0.25) env = (0.3 - localT) / 0.05; // Release
                
                sample *= env;
            }
        }

        // Apply master volume and write 16-bit PCM integer
        sample = sample * 0.4;
        let v = sample * 32767;
        view.setInt16(offset, v, true);
        offset += 2;
    }

    // Create an audio blob and object URL
    const audioBlob = new Blob([view], { type: 'audio/wav' });
    const audioUrl = URL.createObjectURL(audioBlob);
    const audioNode = new Audio(audioUrl);
    audioNode.loop = true;

    // 3. Build the MP3 Player UI
    const container = document.createElement('div');
    container.style.position = 'relative';
    container.style.width = '320px';
    container.style.height = '480px';
    container.style.borderRadius = '24px';
    container.style.overflow = 'hidden';
    container.style.boxShadow = '0 12px 36px rgba(0,0,0,0.4)';
    container.style.fontFamily = '-apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif';
    container.style.color = '#fff';
    container.style.margin = '20px auto';

    // Blurred Background
    const bg = document.createElement('div');
    bg.style.position = 'absolute';
    bg.style.top = '-20px';
    bg.style.left = '-20px';
    bg.style.right = '-20px';
    bg.style.bottom = '-20px';
    bg.style.backgroundImage = `url(${imgDataUrl})`;
    bg.style.backgroundSize = 'cover';
    bg.style.backgroundPosition = 'center';
    bg.style.filter = 'blur(18px) brightness(0.3)';
    bg.style.zIndex = '1';
    container.appendChild(bg);

    // Frontend UI Layer
    const ui = document.createElement('div');
    ui.style.position = 'absolute';
    ui.style.top = '0';
    ui.style.left = '0';
    ui.style.width = '100%';
    ui.style.height = '100%';
    ui.style.zIndex = '2';
    ui.style.display = 'flex';
    ui.style.flexDirection = 'column';
    ui.style.alignItems = 'center';
    ui.style.padding = '40px 24px';
    ui.style.boxSizing = 'border-box';
    container.appendChild(ui);

    // Album Art
    const albumArt = document.createElement('img');
    albumArt.src = imgDataUrl;
    albumArt.style.width = '200px';
    albumArt.style.height = '200px';
    albumArt.style.borderRadius = '20px';
    albumArt.style.objectFit = 'cover';
    albumArt.style.boxShadow = '0 10px 20px rgba(0,0,0,0.5)';
    albumArt.style.marginBottom = '25px';
    ui.appendChild(albumArt);

    // Song Title & Artist
    const titleEl = document.createElement('h2');
    titleEl.innerText = title;
    titleEl.style.margin = '0 0 5px 0';
    titleEl.style.fontSize = '20px';
    titleEl.style.fontWeight = '600';
    titleEl.style.textAlign = 'center';
    titleEl.style.whiteSpace = 'nowrap';
    titleEl.style.overflow = 'hidden';
    titleEl.style.textOverflow = 'ellipsis';
    titleEl.style.width = '100%';
    ui.appendChild(titleEl);

    const subEl = document.createElement('p');
    subEl.innerText = "Android Audio Player";
    subEl.style.margin = '0 0 35px 0';
    subEl.style.fontSize = '13px';
    subEl.style.color = 'rgba(255, 255, 255, 0.7)';
    subEl.style.textAlign = 'center';
    ui.appendChild(subEl);

    // Progress Bar Wrapper
    const progWrapper = document.createElement('div');
    progWrapper.style.width = '100%';
    progWrapper.style.marginBottom = '25px';
    ui.appendChild(progWrapper);

    // Seek Slider
    const progress = document.createElement('input');
    progress.type = 'range';
    progress.min = 0;
    progress.max = 100;
    progress.value = 0;
    progress.style.width = '100%';
    progress.style.cursor = 'pointer';
    progress.style.margin = '0';
    progWrapper.appendChild(progress);

    // Timestamps
    const timeInfo = document.createElement('div');
    timeInfo.style.display = 'flex';
    timeInfo.style.justifyContent = 'space-between';
    timeInfo.style.fontSize = '11px';
    timeInfo.style.fontWeight = '500';
    timeInfo.style.color = 'rgba(255, 255, 255, 0.6)';
    timeInfo.style.marginTop = '8px';
    
    const currTimeEl = document.createElement('span');
    currTimeEl.innerText = '0:00';
    const totalTimeEl = document.createElement('span');
    totalTimeEl.innerText = '0:06';
    
    timeInfo.appendChild(currTimeEl);
    timeInfo.appendChild(totalTimeEl);
    progWrapper.appendChild(timeInfo);

    // Controller Buttons
    const controls = document.createElement('div');
    controls.style.display = 'flex';
    controls.style.alignItems = 'center';
    controls.style.justifyContent = 'center';
    controls.style.gap = '25px';
    ui.appendChild(controls);

    const createBtn = (icon, size, fontSize) => {
        const btn = document.createElement('button');
        btn.innerText = icon;
        btn.style.width = size;
        btn.style.height = size;
        btn.style.borderRadius = '50%';
        btn.style.border = 'none';
        btn.style.backgroundColor = 'rgba(255, 255, 255, 0.15)';
        btn.style.color = '#fff';
        btn.style.fontSize = fontSize;
        btn.style.cursor = 'pointer';
        btn.style.display = 'flex';
        btn.style.justifyContent = 'center';
        btn.style.alignItems = 'center';
        btn.style.transition = 'all 0.2s ease-in-out';
        
        btn.addEventListener('mouseover', () => btn.style.backgroundColor = 'rgba(255, 255, 255, 0.25)');
        btn.addEventListener('mouseout', () => btn.style.backgroundColor = 'rgba(255, 255, 255, 0.15)');
        return btn;
    };

    const prevBtn = createBtn('⏪', '44px', '16px');
    const playBtn = createBtn('▶', '64px', '26px');
    const nextBtn = createBtn('⏩', '44px', '16px');

    // Customize main Play button layout
    playBtn.style.backgroundColor = themeColor;
    playBtn.style.boxShadow = '0 6px 16px rgba(0,0,0,0.3)';
    playBtn.addEventListener('mouseover', () => playBtn.style.transform = 'scale(1.05)');
    playBtn.addEventListener('mouseout', () => playBtn.style.transform = 'scale(1.0)');

    controls.appendChild(prevBtn);
    controls.appendChild(playBtn);
    controls.appendChild(nextBtn);

    // 4. Implement Audio Player Logic
    let isPlaying = false;
    let isDragging = false;

    playBtn.addEventListener('click', () => {
        if (isPlaying) {
            audioNode.pause();
            playBtn.innerText = '▶';
        } else {
            audioNode.play();
            playBtn.innerText = '⏸';
        }
        isPlaying = !isPlaying;
    });

    prevBtn.addEventListener('click', () => {
        audioNode.currentTime = Math.max(0, audioNode.currentTime - 1);
    });

    nextBtn.addEventListener('click', () => {
        audioNode.currentTime = Math.min(audioNode.duration || duration, audioNode.currentTime + 1);
    });

    const formatTime = (secs) => {
        const m = Math.floor(secs / 60);
        const s = Math.floor(secs % 60);
        return `${m}:${s < 10 ? '0' : ''}${s}`;
    };

    audioNode.addEventListener('timeupdate', () => {
        if (!isDragging) {
            const percent = (audioNode.currentTime / audioNode.duration) * 100;
            progress.value = percent || 0;
            currTimeEl.innerText = formatTime(audioNode.currentTime);
        }
    });

    // Cleanup drag issues and seek properly
    progress.addEventListener('input', () => {
        isDragging = true;
        currTimeEl.innerText = formatTime((progress.value / 100) * (audioNode.duration || duration));
    });

    progress.addEventListener('change', () => {
        audioNode.currentTime = (progress.value / 100) * (audioNode.duration || duration);
        isDragging = false;
    });

    return container;
}

Free Image Tool Creator

Can't find the image tool you're looking for?
Create one based on your own needs now!

Description

This tool allows you to transform an image into a stylized, Android-inspired MP3 audio player interface. When you upload an image, the tool uses it as both the album art and a blurred background for a custom-designed media player UI. Additionally, it synthesizes a custom electronic ringtone audio track to accompany the visual interface. This can be used for creating unique social media assets, mockups for mobile UI designs, or personalized digital aesthetic elements.

Leave a Reply

Your email address will not be published. Required fields are marked *