Please bookmark this page to avoid losing your image tool!

AI Video Language Dubbing And Translation Generator

(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, dubbingText = "Hello! This is an AI simulated video dubbing and translation. Click here to play.", languageCode = "en-US", fontSize = 32, fontColor = "#FEFEFE") {
    // Create an interactive container for our "video" mockup
    const container = document.createElement('div');
    container.style.position = 'relative';
    container.style.display = 'inline-block';
    container.style.maxWidth = '100%';
    container.style.cursor = 'pointer';
    container.title = 'Click to play/pause AI dubbing audio';

    // Create the canvas rendering the mock video frame
    const canvas = document.createElement('canvas');
    const width = originalImg.width;
    const height = originalImg.height;
    
    canvas.width = width;
    canvas.height = height;
    canvas.style.maxWidth = '100%';
    canvas.style.height = 'auto';
    canvas.style.display = 'block';
    canvas.style.borderRadius = '8px';
    canvas.style.boxShadow = '0 4px 12px rgba(0,0,0,0.3)';
    
    const ctx = canvas.getContext('2d');
    
    // Draw the original image as the background video frame
    ctx.drawImage(originalImg, 0, 0);

    // Apply a subtle darkening vignette layer for video realism
    ctx.fillStyle = "rgba(0, 0, 0, 0.35)";
    ctx.fillRect(0, 0, width, height);

    // Draw the Play Button Overlay
    const minDim = Math.min(width, height);
    const centerX = width / 2;
    const centerY = height / 2;
    const radius = minDim * 0.12;

    // Play button background
    ctx.fillStyle = "rgba(0, 0, 0, 0.65)";
    ctx.beginPath();
    ctx.arc(centerX, centerY, radius, 0, 2 * Math.PI);
    ctx.fill();
    ctx.lineWidth = 3;
    ctx.strokeStyle = "rgba(255, 255, 255, 0.8)";
    ctx.stroke();
    
    // Play button triangle
    ctx.fillStyle = "rgba(255, 255, 255, 0.95)";
    ctx.beginPath();
    const iconSize = radius * 0.45;
    ctx.moveTo(centerX - iconSize * 0.4, centerY - iconSize);
    ctx.lineTo(centerX + iconSize, centerY);
    ctx.lineTo(centerX - iconSize * 0.4, centerY + iconSize);
    ctx.closePath();
    ctx.fill();

    // Prepare Subtitle Text Parameters
    let parsedFontSize = parseInt(String(fontSize), 10) || 32;
    // Scale font safely based on image height to avoid overflow issues on small images
    parsedFontSize = Math.min(parsedFontSize, Math.max(12, Math.floor(height * 0.08)));
    
    ctx.font = `bold ${parsedFontSize}px Arial, sans-serif`;
    ctx.textAlign = "center";
    ctx.textBaseline = "middle";

    const maxWidth = width * 0.90; 
    const words = String(dubbingText).split(' ');
    let currentLine = "";
    const lines = [];

    // Word Wrap Logic for Subtitles
    for(let i = 0; i < words.length; i++) {
        const testLine = currentLine + words[i] + " ";
        const metrics = ctx.measureText(testLine);
        if (metrics.width > maxWidth && i > 0) {
            lines.push(currentLine.trim());
            currentLine = words[i] + " ";
        } else {
            currentLine = testLine;
        }
    }
    lines.push(currentLine.trim());

    // Subtitle Container Layout
    const lineHeight = parsedFontSize * 1.4;
    const padding = Math.max(10, parsedFontSize * 0.5);
    const marginB = Math.max(height * 0.06, 20);

    let maxLineWidth = 0;
    for (let line of lines) {
        maxLineWidth = Math.max(maxLineWidth, ctx.measureText(line).width);
    }
    
    const boxWidth = Math.min(maxLineWidth + padding * 4, width * 0.95);
    const boxHeight = lines.length * lineHeight + padding * 2;
    
    const boxX = (width - boxWidth) / 2;
    const boxY = height - marginB - boxHeight;

    // Draw Subtitle Background
    ctx.fillStyle = "rgba(0, 0, 0, 0.75)";
    if (ctx.roundRect) {
        ctx.beginPath();
        ctx.roundRect(boxX, boxY, boxWidth, boxHeight, 12);
        ctx.fill();
    } else {
        ctx.fillRect(boxX, boxY, boxWidth, boxHeight);
    }

    // Draw Subtitle Text Lines
    ctx.fillStyle = fontColor || "#FFFFFF";
    let textY = boxY + padding + (lineHeight / 2);
    
    for (let i = 0; i < lines.length; i++) {
        ctx.fillText(lines[i], centerX, textY);
        textY += lineHeight;
    }

    // Add Canvas to Output Container
    container.appendChild(canvas);

    // Audio Playback Integration (Web Speech API)
    let isPlaying = false;
    
    container.addEventListener('click', () => {
        if (!('speechSynthesis' in window)) {
            alert("Text-to-Speech is not supported in your current browser.");
            return;
        }

        // Toggle pause/play behavior
        if (isPlaying) {
            window.speechSynthesis.cancel();
            isPlaying = false;
            return;
        }

        window.speechSynthesis.cancel(); 
        
        const utterance = new SpeechSynthesisUtterance(String(dubbingText));
        utterance.lang = String(languageCode);
        utterance.rate = 0.9; // Slightly slower for dubbing feels
        
        // Ensure best voice match
        const applyVoice = () => {
            const voices = window.speechSynthesis.getVoices();
            if (voices.length > 0) {
                let match = voices.find(v => v.lang.toLowerCase() === utterance.lang.toLowerCase());
                if (!match) {
                    match = voices.find(v => v.lang.split('-')[0].toLowerCase() === utterance.lang.split('-')[0].toLowerCase());
                }
                if (match) utterance.voice = match;
            }
        };

        applyVoice();
        if (window.speechSynthesis.getVoices().length === 0) {
            window.speechSynthesis.onvoiceschanged = applyVoice;
        }

        utterance.onstart = () => { isPlaying = true; };
        utterance.onend = () => { isPlaying = false; };
        utterance.onerror = () => { isPlaying = false; };

        window.speechSynthesis.speak(utterance);
    });

    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 generates an interactive video mockup from a static image, simulating an AI-driven dubbing and translation experience. It overlays a play button and customizable subtitles onto your image, and uses text-to-speech technology to read the provided text aloud in a specified language. It is useful for creators looking to preview how translated content might look and sound in a video format, or for developers demonstrating language localization concepts.

Leave a Reply

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