<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>BahbahUncapped</title>
    <link rel="stylesheet" href="mainstyles.css">
    <style>
        * {
            margin: 0;
            box-sizing: border-box;
            font-family: 'Poppins', sans-serif;
        }

        body {
            margin: 0;
            display: flex;
            justify-content: center;
            align-items: center;
            height: 100vh;
            background-image: url('background-image.jpg');
            background-size: cover;
        }

        .container {
            width: 80%;
            max-width: 800px;
            text-align: center;
            color: #fff;
            background: rgba(255, 255, 255, 0.1);
            border-radius: 15px;
            padding: 30px;
            box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
            backdrop-filter: blur(5px);
        }

        h1 {
            font-size: 2.5rem;
            margin-bottom: 20px;
        }

        p {
            font-size: 1rem;
            margin-bottom: 20px;
        }

        .form-container {
            display: flex;
            flex-direction: column;
            align-items: center;
        }

        .form-container input,
        .form-container select,
        .form-container button {
            padding: 10px;
            margin: 10px 0;
            width: 80%;
            max-width: 400px;
            border-radius: 8px;
            background: transparent;
            border: 1px solid #fff;
            color: #fff;
        }

        .form-container input:focus,
        .form-container select:focus,
        .form-container button:focus {
            outline: none;
        }

        .form-container button {
            cursor: pointer;
            background-color: #fff;
            color: black;
            border: 1px solid #fff;
        }

        .form-container button:hover {
            background-color: transparent;
            color: #fff;
            outline: 1px solid #fff;
        }

        #status {
            margin-top: 20px;
            font-size: 1.2rem;
        }

        video {
            margin-top: 20px;
            width: 100%;
            border-radius: 10px;
        }
    </style>
</head>

<body>
    <div class="container">
        <h1>Welcome to BahbahUncapped</h1>
        <p>Enter the URL to start streaming or download your video</p>

        <div class="form-container">
            <label for="url">URL:</label>
            <input type="text" id="url" placeholder="Enter URL here" onkeyup="if (event.key == 'Enter') stream()" />

            <div class="resolution-section">
                <label for="resolution">Select Resolution:</label>
                <select id="resolution">
                    <option value="1500">720p</option>
                    <option value="2500">1080p</option>
                    <option value="4500">4K</option>
                </select>
            </div>

            <div class="video-name-section">
                <label for="videoName">Video Name:</label>
                <input type="text" id="videoName" placeholder="Enter video name (without extension)" />
            </div>

            <button class="button-7" onclick="stream()">Stream</button>
            <button class="button-42" onclick="downloadAndMergeVideo()">Download</button>
        </div>

        <div id="status" class="status"></div>

        <video id="video" controls autoplay></video>
    </div>

    <script src="https://cdn.jsdelivr.net/npm/hls.js@latest"></script>
    <script>
        window.onload = function () {
            // Target all options in the resolution dropdown and change their font color to black
            var resolutionSelect = document.getElementById('resolution');
            var options = resolutionSelect.options;
            for (let i = 0; i < options.length; i++) {
                options[i].style.color = "black"; // Set each option's font color to black
            }
        };

        var hls = null;

        if (Hls.isSupported()) {
            var hlsjsConfig = {
                "maxBufferSize": 0,
                "maxBufferLength": 30,
                "startPosition": 0
            }
            hls = new Hls(hlsjsConfig);
            hls.on(Hls.Events.MANIFEST_PARSED, function () {
                video.play();
            });
        }

        const rgx = /([a-z0-9]{10})(:?\/|$)/g;

        async function stream() {
            if (hls == null) {
                alert("HLS not supported, please use a modern browser such as Chrome");
                return;
            }

            let rawUrl = document.getElementById("url").value;
            rawUrl = rawUrl.replace(/\/[^/]*$/, '');
            let ids = [];
            let match = null;

            while ((match = rgx.exec(rawUrl)) !== null) {
                ids.push(match[1]);
            }

            if (ids.length < 1) {
                alert("Invalid URL");
                return;
            }

            const videoId = rawUrl.includes("browse3") ? ids[0] : ids[ids.length - 1];
            let statusLabel = document.getElementById("status");

            console.log(`Video ID is ${videoId}`);
            console.log("Looking for the final part...");
            let last = 0;
            let jump = true;

            for (let i = 300; i <= 1000; i++) {
                if (i == 1000) {
                    alert("Error finding the last part");
                    return;
                }

                if (i == 0) i = 1;

                const url = `https://d13z5uuzt1wkbz.cloudfront.net/${videoId}/HIDDEN4500-${String(i).padStart(5, "0")}.ts`;
                console.log(`Testing ${url}`);
                statusLabel.innerText = `Looking for the final part; Testing ${i}...`;
                try {
                    const resp = await fetch(url, { method: 'HEAD' });
                    if (resp.status === 403) {
                        if (i >= 50 && i % 50 === 0 && jump) {
                            last = i;
                            jump = true;
                            i -= 51;
                            continue;
                        }

                        break;
                    }
                    last = i;
                    jump = false;
                } catch (e) {
                    alert("Fetch failed, please install a Cross-Origin disabler extension for your browser or check your internet connectivity.");
                    return;
                }
            }

            statusLabel.innerText = "";

            let data = "#EXTM3U\n#EXT-X-PLAYLIST-TYPE:VOD\n#EXT-X-TARGETDURATION:10";
            for (let i = 0; i <= last; i++) {
                data += `#EXTINF:10,\nhttps://d13z5uuzt1wkbz.cloudfront.net/${videoId}/HIDDEN4500-${String(i).padStart(5, "0")}.ts\n`
            }

            console.log(data);

            hls.loadSource("data:application/x-mpegURL;base64," + btoa(data));
            hls.attachMedia(video);
        }

        async function downloadAndMergeVideo() {
            const rawUrl = document.getElementById("url").value.replace(/\/[^/]*$/, '');
            const selectedResolution = document.getElementById("resolution").value;
            const videoName = document.getElementById("videoName").value;

            if (!videoName) {
                document.getElementById("status").innerText = "Please enter a video name.";
                return;
            }

            let ids = [];
            let match = null;

            while ((match = rgx.exec(rawUrl))) {
                ids.push(match[1]);
            }

            if (ids.length < 1) {
                document.getElementById("status").innerText = "PLS INSERT LINK AND DOWNLOAD";
                return;
            }

            const videoId = rawUrl.includes("browse3") ? ids[0] : ids[ids.length - 1];

            const lastFileIndex = 1000;

            const tsUrls = [];
            for (let i = 1; i <= lastFileIndex; i++) {
                const tsUrl = `https://d13z5uuzt1wkbz.cloudfront.net/${videoId}/HIDDEN${selectedResolution}-${String(i).padStart(5, "0")}.ts`;
                tsUrls.push(tsUrl);
            }

            document.getElementById("status").innerText = "IN PROGRESS";

            const tsFileContents = [];
            for (const [index, tsUrl] of tsUrls.entries()) {
                try {
                    const resp = await fetch(tsUrl);
                    if (resp.status === 200) {
                        const tsData = await resp.arrayBuffer();
                        tsFileContents.push(tsData);
                    } else {
                        console.warn(`Failed to download ${tsUrl}, finishing download.`);
                        break;
                    }
                } catch (e) {
                    console.warn(`Fetch failed for ${tsUrl}, finishing download.`);
                    break;
                }
            }

            if (tsFileContents.length === 0) {
                document.getElementById("status").innerText = "No valid .ts files were downloaded.";
                return;
            }

            const mergedVideoBlob = new Blob(tsFileContents, { type: 'video/mp2t' });
            const downloadLink = document.createElement('a');
            downloadLink.href = URL.createObjectURL(mergedVideoBlob);
            downloadLink.download = `${videoName}.ts`;
            document.body.appendChild(downloadLink);
            downloadLink.click();
            document.body.removeChild(downloadLink);

            document.getElementById("status").innerText = "DONE";
            setTimeout(() => {
                document.getElementById("status").innerText = "";
            }, 1000);
        }
    </script>
</body>

</html>
