view mrjunejune/src/tools/file_converter/index.html @ 92:655ea0b661fd

[Seobeo] Added few endpoints for handling files. [Dowa] Added few functions for random number and generating uuids
author June Park <parkjune1995@gmail.com>
date Fri, 02 Jan 2026 17:47:10 -0800
parents
children be91a73d801a
line wrap: on
line source

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>File Format Converter</title>
    {{/parts/base_head.html}}
    <style>
        .container {
            max-width: 800px;
            margin: 2rem auto;
            padding: 2rem;
        }

        .converter-section {
            border-radius: 8px;
            border: 2px solid var(--lightgray);
            padding: 2rem;
            margin-bottom: 2rem;
        }

        .converter-section h2 {
            margin-top: 0;
            color: var(--black);
        }

        .file-input-wrapper {
            margin: 1rem 0;
        }

        .file-input-wrapper label {
            display: block;
            margin-bottom: 0.5rem;
            font-weight: 600;
        }

        input[type="file"] {
            width: 50%;
            padding: 0.5rem;
            border: 2px dashed #ccc;
            border-radius: 4px;
            background: white;
        }

        button {
            background: var(--purple);
            font-family: "More Thin", sans-serif;
            color: var(--gray-gradient);
            border: none;
            padding: 0.75rem 1.5rem;
            border-radius: 4px;
            cursor: pointer;
            font-size: 1rem;
            margin-top: 1rem;
        }

        button:hover {
            background: var(--orange);
        }

        button:disabled {
            background: var(--gray);
            cursor: not-allowed;
        }

        .result {
            margin-top: 1rem;
            padding: 1rem;
            background: white;
            border-radius: 4px;
            display: none;
        }

        .result.show {
            display: block;
        }

        .result.success {
            border-left: 4px solid var(--blue);
        }

        .result.error {
            border-left: 4px solid var(--red);
        }

        .download-link {
            display: inline-block;
            margin-top: 0.5rem;
            color: var(--awesome);
            text-decoration: none;
        }

        .download-link:hover {
            text-decoration: underline;
        }

        .loading {
            display: none;
            margin-top: 1rem;
        }

        .loading.show {
            display: block;
        }
    </style>
</head>
<body>
    {{/parts/header.html}}

    <div class="container">
        <h1>File Format Converter</h1>
        <p>Convert your images and videos to different formats using FFmpeg</p>

        <div class="converter-section">
            <h2>Image to WebP Converter</h2>
            <p>Upload an image file (PNG, JPG, GIF, etc.) to convert it to WebP format</p>

            <div class="file-input-wrapper">
                <label for="imageInput">Choose an image file:</label>
                <input type="file" id="imageInput" accept="image/*">
            </div>

            <button id="convertImageBtn" onclick="convertImageToWebP()">Convert to WebP</button>

            <div class="loading" id="imageLoading">Converting... Please wait.</div>

            <div class="result" id="imageResult">
                <p id="imageMessage"></p>
                <a id="imageDownload" class="download-link" style="display: none;">Download WebP Image</a>
            </div>
        </div>

        <div class="converter-section">
            <h2>Video to MP4 Converter</h2>
            <p>Upload a video file (AVI, MOV, MKV, etc.) to convert it to MP4 format</p>

            <div class="file-input-wrapper">
                <label for="videoInput">Choose a video file:</label>
                <input type="file" id="videoInput" accept="video/*">
            </div>

            <button id="convertVideoBtn" onclick="convertVideoToMP4()">Convert to MP4</button>

            <div class="loading" id="videoLoading">Converting... Please wait.</div>

            <div class="result" id="videoResult">
                <p id="videoMessage"></p>
                <a id="videoDownload" class="download-link" style="display: none;">Download MP4 Video</a>
            </div>
        </div>
    </div>

    <script>
        async function convertImageToWebP() {
            const input = document.getElementById('imageInput');
            const btn = document.getElementById('convertImageBtn');
            const loading = document.getElementById('imageLoading');
            const result = document.getElementById('imageResult');
            const message = document.getElementById('imageMessage');
            const download = document.getElementById('imageDownload');

            if (!input.files || !input.files[0]) {
                alert('Please select an image file first');
                return;
            }

            const file = input.files[0];

            // Show loading state
            btn.disabled = true;
            loading.classList.add('show');
            result.classList.remove('show', 'success', 'error');
            download.style.display = 'none';

            try {
                const response = await fetch('/api/convert/image-to-webp', {
                    method: 'POST',
                    body: file,
                    headers: {
                        'Content-Type': file.type
                    }
                });

                loading.classList.remove('show');
                result.classList.add('show');

                if (response.ok) {
                    const data = await response.json();

                    download.href = data.download_url;
                    download.download = file.name.replace(/\.[^/.]+$/, '') + '.webp';
                    download.style.display = 'inline-block';

                    message.textContent = 'Conversion successful! Link expires in ' + data.expires + '.';
                    result.classList.add('success');
                } else {
                    const text = await response.text();
                    message.textContent = 'Conversion failed: ' + text;
                    result.classList.add('error');
                }
            } catch (error) {
                loading.classList.remove('show');
                result.classList.add('show', 'error');
                message.textContent = 'Error: ' + error.message;
            } finally {
                btn.disabled = false;
            }
        }

        async function convertVideoToMP4() {
            const input = document.getElementById('videoInput');
            const btn = document.getElementById('convertVideoBtn');
            const loading = document.getElementById('videoLoading');
            const result = document.getElementById('videoResult');
            const message = document.getElementById('videoMessage');
            const download = document.getElementById('videoDownload');

            if (!input.files || !input.files[0]) {
                alert('Please select a video file first');
                return;
            }

            const file = input.files[0];

            // Show loading state
            btn.disabled = true;
            loading.classList.add('show');
            result.classList.remove('show', 'success', 'error');
            download.style.display = 'none';

            try {
                const response = await fetch('/api/convert/video-to-mp4', {
                    method: 'POST',
                    body: file,
                    headers: {
                        'Content-Type': file.type
                    }
                });

                loading.classList.remove('show');
                result.classList.add('show');

                if (response.ok) {
                    const data = await response.json();

                    download.href = data.download_url;
                    download.download = file.name.replace(/\.[^/.]+$/, '') + '.mp4';
                    download.style.display = 'inline-block';

                    message.textContent = 'Conversion successful! Link expires in ' + data.expires + '.';
                    result.classList.add('success');
                } else {
                    const text = await response.text();
                    message.textContent = 'Conversion failed: ' + text;
                    result.classList.add('error');
                }
            } catch (error) {
                loading.classList.remove('show');
                result.classList.add('show', 'error');
                message.textContent = 'Error: ' + error.message;
            } finally {
                btn.disabled = false;
            }
        }
    </script>
</body>
</html>