Please bookmark this page to avoid losing your image tool!

Android Ringtone MP3 Photo 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, 
    audioUrl = "https://www.soundhelix.com/examples/mp3/SoundHelix-Song-1.mp3", 
    songTitle = "Incoming Call Ringtone", 
    artistName = "Android MP3 Player", 
    themeColor = "#3ddc84"
) {
    // Create the outer wrapper
    const wrapper = document.createElement('div');
    wrapper.style.display = "flex";
    wrapper.style.justifyContent = "center";
    wrapper.style.alignItems = "center";
    wrapper.style.padding = "20px";
    wrapper.style.fontFamily = "'Roboto', 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif";
    
    // Create scoped styles for the player
    const style = document.createElement('style');
    style.innerHTML = `
        @import url('https://fonts.googleapis.com/css2?family=Roboto:wght@300;400;700&display=swap');
        
        .android-player {
            width: 320px;
            background: #1e1e22;
            border-radius: 28px;
            padding: 28px 24px;
            box-sizing: border-box;
            display: flex;
            flex-direction: column;
            align-items: center;
            box-shadow: 0 20px 40px rgba(0,0,0,0.4), inset 0 1px 1px rgba(255,255,255,0.1);
            color: #ffffff;
            position: relative;
            overflow: hidden;
            font-family: 'Roboto', sans-serif;
        }
        
        .ap-header {
            font-size: 11px;
            text-transform: uppercase;
            letter-spacing: 2.5px;
            color: #999999;
            margin-bottom: 24px;
            font-weight: 700;
        }
        
        .ap-album {
            width: 220px;
            height: 220px;
            border-radius: 20px;
            box-shadow: 0 12px 28px rgba(0,0,0,0.6);
            margin-bottom: 30px;
            background: #222;
        }
        
        .ap-info {
            text-align: center;
            width: 100%;
            margin-bottom: 24px;
        }
        
        .ap-title {
            font-size: 22px;
            font-weight: 700;
            margin: 0 0 6px 0;
            white-space: nowrap;
            overflow: hidden;
            text-overflow: ellipsis;
            color: #ffffff;
        }
        
        .ap-artist {
            font-size: 15px;
            color: #aaaaaa;
            margin: 0;
            font-weight: 400;
        }
        
        .ap-progress {
            width: 100%;
            display: flex;
            flex-direction: column;
            margin-bottom: 24px;
        }
        
        .ap-time {
            display: flex;
            justify-content: space-between;
            font-size: 11px;
            color: #888888;
            margin-top: 10px;
            font-weight: 500;
        }
        
        input[type=range].ap-slider {
            -webkit-appearance: none;
            width: 100%;
            background: transparent;
            margin: 0;
        }
        
        input[type=range].ap-slider::-webkit-slider-thumb {
            -webkit-appearance: none;
            height: 12px;
            width: 12px;
            border-radius: 50%;
            background: ${themeColor};
            cursor: pointer;
            margin-top: -4px;
            box-shadow: 0 0 8px rgba(0,0,0,0.3);
            transition: transform 0.1s;
        }

        input[type=range].ap-slider::-webkit-slider-thumb:hover {
            transform: scale(1.3);
        }
        
        input[type=range].ap-slider::-webkit-slider-runnable-track {
            width: 100%;
            height: 4px;
            cursor: pointer;
            background: #444;
            border-radius: 2px;
        }
        
        .ap-controls {
            display: flex;
            width: 100%;
            justify-content: space-evenly;
            align-items: center;
        }
        
        .ap-btn {
            background: none;
            border: none;
            color: #ffffff;
            cursor: pointer;
            display: flex;
            align-items: center;
            justify-content: center;
            outline: none;
            transition: transform 0.15s, color 0.2s;
            padding: 0;
        }
        
        .ap-btn:hover {
            color: ${themeColor};
        }
        
        .ap-btn:active {
            transform: scale(0.9);
        }
        
        .ap-btn-play {
            width: 68px;
            height: 68px;
            border-radius: 50%;
            background: ${themeColor};
            color: #1a1a1a;
            box-shadow: 0 6px 16px rgba(0,0,0,0.3);
        }
        
        .ap-btn-play:hover {
            color: #1a1a1a;
            transform: scale(1.05);
            background: ${themeColor};
            filter: brightness(1.1);
        }

        .ap-btn-play:active {
            transform: scale(0.95);
        }
        
        .ap-btn svg {
            width: 28px;
            height: 28px;
        }
        
        .ap-btn-play svg {
            width: 36px;
            height: 36px;
        }
    `;
    wrapper.appendChild(style);

    // Build Player UI layout
    const player = document.createElement('div');
    player.className = 'android-player';

    const header = document.createElement('div');
    header.className = 'ap-header';
    header.innerText = 'Now Playing';

    // Album Art Canvas setup (covers the image intelligently)
    const canvas = document.createElement('canvas');
    canvas.className = 'ap-album';
    const canvasSize = 400; // Render target size
    canvas.width = canvasSize;
    canvas.height = canvasSize;
    const ctx = canvas.getContext('2d');
    
    // Provide defaults to avoid NaN if image structure is somewhat corrupted
    const imgW = originalImg.width || 1;
    const imgH = originalImg.height || 1;
    
    // Scale and center to mimic object-fit: cover
    const scale = Math.max(canvasSize / imgW, canvasSize / imgH);
    const w = imgW * scale;
    const h = imgH * scale;
    const x = (canvasSize - w) / 2;
    const y = (canvasSize - h) / 2;
    
    ctx.fillStyle = "#1e1e22";
    ctx.fillRect(0, 0, canvasSize, canvasSize);
    
    // Make sure we have drawn the actual image
    try {
        ctx.drawImage(originalImg, x, y, w, h);
    } catch(e) {
        console.error("Could not draw image", e);
    }

    // Info section (Title and Artist)
    const info = document.createElement('div');
    info.className = 'ap-info';
    
    const title = document.createElement('h2');
    title.className = 'ap-title';
    title.innerText = songTitle;
    
    const artist = document.createElement('p');
    artist.className = 'ap-artist';
    artist.innerText = artistName;
    
    info.appendChild(title);
    info.appendChild(artist);

    // Audio Element configuration
    const audio = document.createElement('audio');
    audio.src = audioUrl;
    audio.crossOrigin = "anonymous";

    // Progress Bar Elements
    const progressContainer = document.createElement('div');
    progressContainer.className = 'ap-progress';
    
    const slider = document.createElement('input');
    slider.type = 'range';
    slider.className = 'ap-slider';
    slider.min = 0;
    slider.max = 100;
    slider.value = 0;

    const timeRow = document.createElement('div');
    timeRow.className = 'ap-time';
    const currTimeLabel = document.createElement('span');
    currTimeLabel.innerText = '0:00';
    const durTimeLabel = document.createElement('span');
    durTimeLabel.innerText = '0:00';
    
    timeRow.appendChild(currTimeLabel);
    timeRow.appendChild(durTimeLabel);
    progressContainer.appendChild(slider);
    progressContainer.appendChild(timeRow);

    // Utility: format seconds into MM:SS
    function formatTime(seconds) {
        if (isNaN(seconds) || !isFinite(seconds) || seconds < 0) return '0:00';
        const m = Math.floor(seconds / 60);
        const s = Math.floor(seconds % 60);
        return m + ':' + (s < 10 ? '0' : '') + s;
    }

    // Audio event listeners for timeline
    audio.addEventListener('loadedmetadata', () => {
        slider.max = audio.duration;
        durTimeLabel.innerText = formatTime(audio.duration);
    });

    let isSeeking = false;
    
    audio.addEventListener('timeupdate', () => {
        if (!isSeeking) {
            slider.value = audio.currentTime;
            currTimeLabel.innerText = formatTime(audio.currentTime);
        }
    });

    slider.addEventListener('input', () => {
        isSeeking = true;
        currTimeLabel.innerText = formatTime(slider.value);
    });

    slider.addEventListener('change', () => {
        audio.currentTime = slider.value;
        isSeeking = false;
    });

    // Control Elements (Prev, Play, Next)
    const controls = document.createElement('div');
    controls.className = 'ap-controls';

    const btnPrev = document.createElement('button');
    btnPrev.className = 'ap-btn';
    btnPrev.innerHTML = `<svg viewBox="0 0 24 24"><path fill="currentColor" d="M6,18V6H8V18H6M9.5,12L18,6V18L9.5,12Z" /></svg>`;

    const btnPlay = document.createElement('button');
    btnPlay.className = 'ap-btn ap-btn-play';
    const playIcon = `<svg viewBox="0 0 24 24"><path fill="currentColor" d="M8,5.14V19.14L19,12.14L8,5.14Z" /></svg>`;
    const pauseIcon = `<svg viewBox="0 0 24 24"><path fill="currentColor" d="M14,19H18V5H14M6,19H10V5H6V19Z" /></svg>`;
    btnPlay.innerHTML = playIcon;

    const btnNext = document.createElement('button');
    btnNext.className = 'ap-btn';
    btnNext.innerHTML = `<svg viewBox="0 0 24 24"><path fill="currentColor" d="M16,18H18V6H16M6,18L14.5,12L6,6V18Z" /></svg>`;

    // Audio Playback Functionality
    btnPlay.addEventListener('click', () => {
        if (audio.paused) {
            audio.play().catch(e => console.warn("Audio playback was blocked", e));
            btnPlay.innerHTML = pauseIcon;
        } else {
            audio.pause();
            btnPlay.innerHTML = playIcon;
        }
    });

    audio.addEventListener('ended', () => {
        btnPlay.innerHTML = playIcon;
        slider.value = 0;
        currTimeLabel.innerText = formatTime(0);
    });

    // Previous decreases time by 5s or goes back to start
    btnPrev.addEventListener('click', () => {
        audio.currentTime = Math.max(0, audio.currentTime - 5);
    });
    
    // Next increases time by 5s or goes to end
    btnNext.addEventListener('click', () => {
        audio.currentTime = Math.min(audio.duration || 0, audio.currentTime + 5);
    });

    // Append controls
    controls.appendChild(btnPrev);
    controls.appendChild(btnPlay);
    controls.appendChild(btnNext);

    // Assembly of Player UI
    player.appendChild(header);
    player.appendChild(canvas);
    player.appendChild(info);
    player.appendChild(progressContainer);
    player.appendChild(controls);
    player.appendChild(audio);

    wrapper.appendChild(player);

    return wrapper;
}

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 create a customized, Android-style MP3 music player interface using an image of your choice. It generates a sleek, dark-themed UI that includes an album art display, song title, artist name, progress bar, and playback controls (play/pause, skip forward, and skip backward). This tool is ideal for content creators, web designers, or social media users who want to create visually appealing mockups of music players or stylized graphics for music-related presentations.

Leave a Reply

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