<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Ecstasy AI - Face Swap</title>
    <style>

        /* Body Styling */
        body {
            background-color: #000000;
            margin: 0;  /* Remove default margin */
            color: #ffffff;
            font-size: 16px;
            display: flex;
            height: 100vh;
            flex-direction: column;
            overflow: hidden;
            padding: 0 15px;
            position: relative;  /* This is important to position the video behind */
            text-align: center;
            justify-content: center;
            align-items: center;
            overflow-y: auto;  /* Allow vertical scroll */
        }

        #video-container {
            position: absolute;
            top: 0;
            left: 0;
            width: 100%;
            height: 100%;
         }

        /* Video Styling */
        #background-video {
            position: absolute;
            top: 50%;
            left: 50%;
            transform: translate(-50%, -50%); /* Centers the video */
            width: 100%;
            height: 100%;
            object-fit: cover;  /* Ensures the video covers the entire screen */
            z-index: -1;  /* Makes sure the video stays in the background */
            display: none; 
           
        }

        /* Content Styling */
        .content {
            position: relative;
            z-index: 1;  /* Content will appear above the video */
            /* Other content styles here */
            text-align: center;
            justify-content: center;
            align-items: center;
            overflow-y: auto; 
        }


        h1 {
            font-size: 26px;
            color: #e8f0fe;
        }

        p {
            font-size: 15px;
            color: #e8f0fe;
        }

        .originaluploadtitle{
            border: none;
            background-color: #000000;
            color: white;
            cursor: pointer;
            font-weight: bold;
            box-shadow: 0 0px 20px rgb(255, 56, 159);
            transition: background-color 0.3s ease, box-shadow 0.3s ease;
            width: 100%;
            height: 40px;
            text-align: center;
            margin-top: 50px;
            margin-bottom: 10px;
            padding-top: 15px;
            font-size: 18px;
        }


        .uploadoriginalimage{
        
            color: white;
            cursor: pointer;
            font-weight: bold;
            transition: background-color 0.3s ease, box-shadow 0.5s ease;
            width: 200px;
            margin-right: 30px;
           
        }


        .uploadoriginalurl{
            color: rgb(255, 255, 255);
            font-weight: bold;
            transition: background-color 0.3s ease, box-shadow 0.5s ease;
            width: 230px;
            margin-right: 30px;
            display: none;
           
        }

        .targetuploadtitle{
            border: none;
            background-color: #000000;
            color: white;
            cursor: pointer;
            font-weight: bold;
            box-shadow: 0 0px 20px rgb(59, 255, 147);
            transition: background-color 0.3s ease, box-shadow 0.3s ease;
            width: 100%;
            height: 40px;
            text-align: center;
            margin-top: 50px;
            margin-bottom: 10px;
            padding-top: 15px;
            font-size: 18px;
         
        }

        .uploadtargetimage{
          
            color: white;
            cursor: pointer;
            font-weight: bold;
            transition: background-color 0.3s ease, box-shadow 0.5s ease;
            width: 200px;
            margin-right: 30px;
            
           
        }


        .targetfaceurl{
            color: rgb(255, 255, 255);
            font-weight: bold;
            transition: background-color 0.3s ease, box-shadow 0.5s ease;
            width: 230px;
            margin-right: 30px;
            display: none;
           
        }
        
        input[type="text"], button, input[type="file"] {
            width: 100%;
            padding: 12px;
            border: 2px solid #ffffff;
            border-radius: 6px;
            font-size: 15px;
            transition: box-shadow 0.3s ease;
            text-align: center;
            align-items: center;
            justify-content: center;
            margin-top: 20px;
            margin-left: 20px;
            color: #ffffff;

        }

        input[type="text"]:focus {
            width: 100%;
            text-align: center;
            justify-content: center;
        }

        button {
            border: none;
            background-color: #000000;
            color: white;
            cursor: pointer;
            font-weight: bold;
            transition: background-color 0.3s ease, box-shadow 0.6s ease;
            box-shadow: 0 0 10px rgba(255, 255, 255, 0.912);
        }

        .swapfacesbutton {
            width: 100%;
            margin-bottom: 10px;
            margin-left: -20px;
            border-radius: 10px;
            color: white;
            font-weight: bold;
            margin-top: 5px;
            margin-bottom: 10px;
            align-items: center;
            text-align: center;
       
    
        }

        .processingimagemessage{

            display: none;
            font-size: 18px;
            width: 350px;
            margin-top: 10px;
            margin-bottom: 10px;
            
            color: rgb(255, 255, 255);
            font-weight: bold;
            transition: background-color 0.3s ease, box-shadow 0.6s ease;

            }
    

        .uploadbothmessage{
        display: none;
        font-size: 15px;
        text-align: center;
        width: 350px;
        margin-top: 10px;
        margin-bottom: 10px;
        color: rgb(255, 255, 255);
        font-weight: bold;
        transition: background-color 0.3s ease, box-shadow 0.6s ease;

        }    

        .successmessage{

        display: none;
        font-size: 24px;
        text-align: center;
        width: 350px;
        margin-top: 10px;
        margin-bottom: 10px;
        color: rgb(58, 255, 55);
        font-weight: bold;
        transition: background-color 0.3s ease, box-shadow 0.6s ease;

        }

        .modelbusymessage{

        display: none;
        font-size: 18px;
        text-align: center;
        width: 350px;
        margin-top: 10px;
        margin-bottom: 10px;
        color: rgb(0, 139, 246);
        font-weight: bold;
        transition: background-color 0.3s ease, box-shadow 0.6s ease;

        }



        .swapanotherbutton {
        width: 60%;
        margin-top: 5px;
        margin-left: -40px;
        margin-bottom: 30px;
        border-radius: 20px;
        font-weight: bold;
        transition: background-color 0.3s ease, box-shadow 0.6s ease;
        text-align: center;
        align-items: center;
        }

   
        button:hover {
            background-color: #000000;
            box-shadow: 0 5px 15px rgba(0, 91, 191, 0.4);
        }
        
        .wave {
            display: none;
            margin-top: 8px;
            margin-bottom: 8px;
        }

        .wave span {
            display: inline-block;
            width: 10px;
            height: 10px;
            margin: 0 8px;
            background-color: #ff9933;
            border-radius: 50%;
            animation: wave 1s ease infinite;
        }

        .wave span:nth-child(2) { animation-delay: 0.2s; }
        .wave span:nth-child(3) { animation-delay: 0.4s; }
        .wave span:nth-child(4) { animation-delay: 0.6s; }
        .wave span:nth-child(5) { animation-delay: 0.8s; }

        @keyframes wave {
            0%, 60%, 100% { transform: initial; }
            30% { transform: translateY(-10px); }
        }

 
        .output,.preview img {
            max-width: 100%;
            border-radius: 4px;
            margin-top: 10px;
            box-shadow: 0 0 10px rgba(255, 255, 255, 0.912);
        }

       .output img{
            max-width: 100%;
            height: 50%;
            border-radius: 4px;
            margin-top: 10px;
        }

        .output img{
        box-shadow: 0 0 20px rgba(255, 255, 255, 0.912);
        }


        .download-button {
            display: none;
            width: 60%;
            margin-top: 10px;
            margin-bottom: 5px;
            padding: 10px;
            background-color: #00c33b;
            color: white;
            text-decoration: none;
            border-radius: 5px;
            font-weight: bold;
            box-shadow: 0 0 10px rgba(255, 255, 255, 0.912);
            transition: background-color 0.3s ease, box-shadow 0.3s ease;
            text-align: center;
            align-items: center;
        }

        .download-button:hover {
            background-color: #00a424;
            box-shadow: 0 0 10px rgba(255, 255, 255, 0.912);
        }


        .preview {
            margin-bottom: 10px;
            display: flex;
            justify-content: space-around;
            margin-top: 50px;
            margin-bottom: 5px;
        }

        .preview img {
            width: 45%;
            margin-bottom: 10px;
            border-radius: 8px;
            box-shadow: 0 0 10px rgba(255, 255, 255, 0.912);
        }
   
    </style>
</head>
<body>

    <video autoplay muted loop id="background-video" preload="auto">
        <source src="https://od.lk/s/NzdfNTkxMzEzMDRf/Orange%20Smoke.mp4" type="video/mp4">
        Your browser does not support the video tag.
    </video>


    <div class="container">
        
        <h1>Ecstasy AI - Face Swap</h1>
        <p>Unlimited Face Swapping </p>
        <p>Upload images in JPG / PNG / WebP format </p>
        <p>Max Supported size of images is 5 MB</p> 
        <p>Upload Photos with Single person </p> 
        <p>Uploaded and Processed Faceswapped Images will be destroyed in 24 hours Automatically from the Servers </p> 

        
        <div class="originaluploadtitle" id = "originaluploadtitle">
            <span> Upload Original Image below </span>
        </div>

        <div class= "uploadoriginalimage" id = "uploadoriginalimage" >
            <input type="file" id="sourceFile" accept="image/*" onchange="uploadToImgBB('source')">
        </div>

        <div class= "uploadoriginalurl">
            <input type="text" id="sourceUrl" placeholder="Paste Original Image URL" oninput="previewImage('source')">
        </div>




        <div class="targetuploadtitle" id = "targetuploadtitle">
            <span> Upload Target Face below </span>
        </div>

        <div class= "uploadtargetimage" id = "uploadtargetimage">
            <input type="file" id="targetFile" accept="image/*" onchange="uploadToImgBB('target')">
        </div>
        
        <div class= "targetfaceurl">
            <input type="text" id="targetUrl" placeholder="Paste Target Face URL" oninput="previewImage('target')">
        </div>

        <div class="uploadbothmessage" id="uploadbothmessage" style="display: none;"> Please Upload both Source and Target images !  </div>
        
 
    

        <div class="preview" id = "preview" >
            <img id="sourcePreview" src="" alt="">
            <img id="targetPreview" src="" alt="">
        </div>


        <div class= "swapfacesbutton" id = "swapfacesbutton">
            <button onclick="swapFaces()">Swap Faces</button>
        </div>

        <div class="processingimagemessage" id="processingimageMessage"> 
            <span> Swapping Faces with AI ......  </span>
            <span> Please wait 1 to 2 minutes ..... </span>
            <span> You will be notified when Faceswap is completed !</span>
        </div>

        <div class="wave" id="waveAnimation">
            <span></span><span></span><span></span><span></span><span></span>
        </div>

        <div class="successmessage" id="successMessage"> Face Swap Completed  ✔ </div>
        <div class="output" id="outputImage" style="display: none;" > </div>

        <div class="modelbusymessage" id="modelbusymessage" style="display: none;"> Model too busy ! Try Again later  </div>

        <a id="downloadButton" class="download-button" download="face-swapped-image.jpg"> Download Image </a>
       
        <div class= "swapanotherbutton" id = "swapanotherbutton" style="display: none;" >
                <button onclick="refresh()">Swap Another</button>
        </div>

    </div>

    <script src="https://cdn.jsdelivr.net/npm/axios/dist/axios.min.js"></script>
    <script>

        // Get the video element and the video container
        const video = document.getElementById('background-video');
        const videoContainer = document.getElementById('video-container');

        // Add an event listener to handle when the video is ready to play
        video.addEventListener('canplaythrough', function() {
            // When the video is ready, hide the black background and show the video
            video.style.display = 'block'; // Show the video
        });

        // Optionally, handle the case where the video fails to load
        video.addEventListener('error', function() {
            video.style.display = 'none'
        });


         // App Sounds

        let audio;  // Declare audio globally to be accessible across multiple functions

        function buttonclick() {
        const audio = new Audio('https://od.lk/s/NzdfNTkwNDMyNDlf/Button%20Click.mp3');
        audio.play();
        }   

        function errorsound() {
        const audio = new Audio('https://od.lk/s/NzdfNTkwNDQzMDhf/Error%20Sound.mp3');
        audio.play();
        }  
  
        function processingvoice() {
        const audio = new Audio('https://od.lk/s/NzdfNTkxMDkyNDFf/Processing%20Images.mp3');
        audio.play();
        }    

 
        function finish() {
        const audio = new Audio('https://od.lk/s/NzdfNTkwNDMxNDRf/finish.mp3');
        audio.play();
        } 

        function taskcompletedvoice() {
        const audio = new Audio('https://od.lk/s/NzdfNTkxMDkyMzlf/Face%20swapping%20Success.mp3');
        audio.play();
        }  

        function processingmusic() {
        // If the audio object is not initialized, create a new one
        if (!audio) {
            audio = new Audio('https://od.lk/s/NzdfNTkxMDk0ODFf/Music%201.mp3');
        }

        // Play the audio if it is not playing
        if (audio.paused) {
            audio.play();
        }
        }

        // Function to stop the processing music (pause and reset)
        function stopProcessingMusic() {
        if (audio && !audio.paused) {
            audio.pause();  // Pause the music
            audio.currentTime = 0;  // Optionally reset to the start
        }
        }

    



        function previewImage(type) {
            const url = document.getElementById(type + "Url").value;
            const previewElement = document.getElementById(type + "Preview");
            previewElement.src = url;
            
        }

        async function uploadToImgBB(type) {
            const fileInput = document.getElementById(type + "File");
            const previewElement = document.getElementById(type + "Preview");
            const urlField = document.getElementById(type + "Url");
            

            if (!fileInput.files.length) return;

            const formData = new FormData();
            formData.append("image", fileInput.files[0]);

            try {
                const response = await axios.post("https://api.imgbb.com/1/upload", formData, {
                    params: { key: "8234ea62c0ce2c45d902731551e5cbb8" }
                });
                const imageUrl = response.data.data.url;
                urlField.value = imageUrl;
                previewElement.src = imageUrl;

               
                
               
            } catch (error) {
                console.error("Error uploading image to ImgBB:", error);             
                errorsound()
            }
        }

        async function swapFaces() {
            const sourceUrl = document.getElementById("sourceUrl").value;
            const targetUrl = document.getElementById("targetUrl").value;
            const waveAnimation = document.getElementById("waveAnimation");
            const processingimageMessage = document.getElementById("processingimageMessage");
            const successMessage = document.getElementById("successMessage");
            const outputImageDiv = document.getElementById("outputImage");


            const downloadButton = document.getElementById("downloadButton");

            document.getElementById("swapanotherbutton").style.display = "none";
            document.getElementById("uploadbothmessage").style.display = "none";
             
           
            


            if (!sourceUrl || !targetUrl) {
                document.getElementById("uploadbothmessage").style.display = "block";  
                errorsound()
                return;
            }

            waveAnimation.style.display = "inline-block";
            processingimageMessage.style.display = "block";
            successMessage.style.display = "none";
            outputImageDiv.innerHTML = "";
            downloadButton.style.display = "none";

            document.getElementById("swapfacesbutton").style.display = "none";

            document.getElementById("uploadoriginalimage").style.display = "none";
            document.getElementById("uploadtargetimage").style.display = "none";

            document.getElementById("originaluploadtitle").style.display = "none";
            document.getElementById("targetuploadtitle").style.display = "none";

            document.getElementById("modelbusymessage").style.display = "none"; 

            buttonclick()
            processingvoice()
            processingmusic()

            

            const options = {
                method: 'POST',
                url: 'https://face-app-face-detection-face-swapper-face-restoration.p.rapidapi.com/swap/url',
                params: { match_gender: 'false', match_age: 'false', match_largest: '1' },
                headers: {
                    'x-rapidapi-key': 'ead0eebc51mshb675588a12fe410p1a6f96jsn6e4111e4fa7e',
                    'x-rapidapi-host': 'face-app-face-detection-face-swapper-face-restoration.p.rapidapi.com',
                    'Content-Type': 'application/json'
                },
                data: { target_url: targetUrl, source_url: sourceUrl }
            };

            try {
                const response = await axios.request(options);
                const imageUrl = response.data.url;
                waveAnimation.style.display = "none";
                processingimageMessage.style.display = "none";
                document.getElementById("swapfacesbutton").style.display = "none";
                successMessage.style.display = "block";

                outputImageDiv.innerHTML = `<img src="${imageUrl}" alt="Face Swapped Image">`;
                downloadButton.href = imageUrl;
                document.getElementById("outputImage").style.display = "block";

                

                document.getElementById("swapanotherbutton").style.display = "inline-block";
                downloadButton.style.display = "inline-block";

                stopProcessingMusic()
                finish() 
                taskcompletedvoice()

            } catch (error) {
                errorsound()
                console.error(" Error swapping faces ", error);
                document.getElementById("modelbusymessage").style.display = "block"; 
                waveAnimation.style.display = "none";
                processingimageMessage.style.display = "none";
                document.getElementById("swapfacesbutton").style.display = "none";
                document.getElementById("swapanotherbutton").style.display = "inline-block";
            }
        }

        function refresh() {
            location.reload(); // Reload the current page
        }

    </script>
</body>
</html>
