aiwebvvv / public /index.html
lord6ablo's picture
Upload 3 files
2b850a7 verified
raw
history blame
15 kB
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>V Corp</title>
<meta name="twitter:image" content="https://i.imgur.com/JcRLYji.jpeg" />
<meta property="og:image" content="https://i.imgur.com/JcRLYji.jpeg" />
<link rel="stylesheet" href="index.css" />
<link rel="preconnect" href="https://fonts.googleapis.com" />
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
<link
href="https://fonts.googleapis.com/css2?family=Inter:wght@900&family=Satisfy&display=swap"
rel="stylesheet"
/>
<audio id="audioPlayer" src="only.mp3" autoplay></audio>
<script src="/mpegts.js"></script>
</head>
<body>
<div
style="
background-image: url('https://media0.giphy.com/media/v1.Y2lkPTc5MGI3NjExMWZyb3d2ZnM2cGJ5NHNmamtiYWxubTFoa2Jib2NxcmQxY21odDBkaCZlcD12MV9pbnRlcm5hbF9naWZfYnlfaWQmY3Q9Zw/qyXsup1970N5UJNHgI/giphy.gif');
"
class="bg-no-repeat bg-center bg-cover bg-fixed h-screen w-screen grid place-content-center place-items-center overflow-hidden bg-gradient-to-b from-slate-900 to-black"
id="bgimg"
>
<div class="flex place-content-center justify-between flex-row">
<h2 class="cursive text-6xl font-bold text-blue-300">Vgony</h2>
<h1 class="cursive display-flex text-4xl font-black text-grey-300">TV</h1>
<a id="eyeButton" class="flex grid place-content-end mr-25">
<img src="eye.png" alt="Eye Icon" height="30px" width="auto" />
</a>
</div>
<div>
<a href="https://vgony.tech" class="exit-simulation-button">
<img id="exitButton" src="exit.svg" alt="Exit button" />
</a>
</div>
<div x-data="app()" x-init="init()" class="container mx-auto z-10">
<div class="flex grid place-content-center justify-center w-full p-1">
<video
id="videoElement"
class="aspect-video mx-auto w-auto border-4 border-6 border-slate-900/30 rounded-full"
preload="auto"
muted
autoplay
></video>
</div>
<div class="flex justify-center bottom-0 pb-2 z-10">
<div class="container mx-auto px-4 opacity-85">
<div class="flex-row items-center justify-center">
<div
class="flex items-center space-x-6 text-xs focus:cursor-pointer"
>
<template x-for="(chan, index) in channels">
<div
class="text-sm capitalize truncate mr-2"
:class="chan.id === channel.id ? 'font-semibold cursor-pointer text-white' : 'text-slate-100 cursor-pointer hover:underline'"
@click="window.location = `${window.location.origin}/?channel=${chan.id}`"
x-text="chan.label"
>
<span
class="animate-ping absolute inline-flex h-3 w-3 rounded-full bg-blue-500 opacity-75"
></span>
</div>
</template>
</div>
<div class="flex-col justify-center items-center">
<div class="flex items-center justify-center">
<a class="text-white font-bold" x-text="''"></a>
</div>
</div>
</div>
</div>
</div>
<div class="flex-col items-center justify-center pt-14">
<button
id="playPauseBtn"
type="button"
class="dark:bg-slate-100 dark:text-slate-700 flex-none -my-2 mx-auto w-10 h-10 rounded-full shadow-md flex items-center justify-center opacity-90"
aria-label="Pause"
>
<img
src="headphones.svg"
alt="Pause Button"
width="32"
height="32"
/>
</button>
</div>
</div>
</div>
<div id="placeholder" class="w-auto h-vh relative inset-0 z-0 bg-fixed"
style="
background-image: url('https://media2.giphy.com/media/v1.Y2lkPTc5MGI3NjExMnBqODlnemxoanp0cGpuMGR6aG12NWxqbmxkMjdiaDZvZWgxdmozeSZlcD12MV9pbnRlcm5hbF9naWZfYnlfaWQmY3Q9Zw/24FW7JSoZ66w9ALKli/giphy.gif');
background-position: center;
background-repeat: no-repeat;
background-size: 50%;
background-color: black;
transition: background-image 0.5s ease-in-out;
"></div>
<div id="placeholder" class="w-auto h-vh relative inset-0 z-0 bg-fixed"
style="
background-image: url('grimreaper.gif');
background-position: center;
background-repeat: no-repeat;
background-size: 58%;
background-color: black;
transition: background-image 0.5s ease-in-out;
"></div>
<script>
const eyeButton = document.getElementById("eyeButton");
const videoWrapper = document.getElementById("videoElement");
const audioPlayer = document.getElementById("audioPlayer");
const playPauseBtn = document.getElementById("playPauseBtn");
const audioFiles = [
"only.mp3",
"only.mp3",
// Add more audio file paths here
];
// Shuffle the audio files array
function shuffleArray(array) {
for (let i = array.length - 1; i > 0; i--) {
const j = Math.floor(Math.random() * (i + 1));
[array[i], array[j]] = [array[j], array[i]];
}
return array;
}
eyeButton.addEventListener("click", () => {
videoWrapper.classList.toggle("fade-in");
});
// Play the next audio file in the shuffled array
function playNextAudio() {
const currentIndex = audioFiles.findIndex((file) => file === audioPlayer.src);
const nextIndex = (currentIndex + 1) % audioFiles.length;
audioPlayer.src = audioFiles[nextIndex];
audioPlayer.play();
}
// Handle clicking the play/pause button
playPauseBtn.addEventListener("click", () => {
if (audioPlayer.paused) {
audioPlayer.play();
playPauseBtn.querySelector("img").src = "pause.svg";
} else {
audioPlayer.pause();
playPauseBtn.querySelector("img").src = "headphones.svg";
}
});
// Setup audio player
shuffleArray(audioFiles);
audioPlayer.src = audioFiles[0];
audioPlayer.play();
audioPlayer.addEventListener("ended", playNextAudio);
// Display the video once loaded
document.addEventListener("DOMContentLoaded", function () {
setTimeout(function () {
showVideo();
}, 1000);
});
function showVideo() {
var videoElement = document.getElementById("videoElement");
videoElement.classList.add("fade-in");
}
</script>
<script>
// disable analytics (we don't use VideoJS yet anyway)
window.HELP_IMPROVE_VIDEOJS = false;
</script>
<script
defer
src="https://cdn.jsdelivr.net/npm/alpinejs@3.x.x/dist/cdn.min.js"
></script>
<script src="https://cdn.tailwindcss.com?plugins=forms,typography,aspect-ratio"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/iframe-resizer/4.3.2/iframeResizer.contentWindow.min.js"></script>
<script>
function app() {
return {
enabled: false,
channels: {
/*
legacy: {
id: 'legacy',
label: '#older',
audience: 0,
online: false,
visible: false,
url: 'https://jbilcke-hf-media-server.hf.space/live/legacy.flv',
resolution: '576x320',
model: 'zeroscope_v2_576w',
modelUrl: 'https://huggingface.co/cerspense/zeroscope_v2_576w',
},
*/
/*
hdtv: {
id: 'hdtv',
label: '#old',
audience: 0,
online: false,
visible: true,
url: 'https://jbilcke-hf-media-server.hf.space/live/hdtv.flv',
resolution: '1024x576_8FPS',
model: 'zeroscope_v2_XL',
modelUrl: 'https://huggingface.co/cerspense/zeroscope_v2_XL',
},
*/
random: {
id: "random",
label: "#Documentary",
audience: 0,
online: false,
visible: true,
url: "https://jbilcke-hf-media-server.hf.space/live/random.flv",
resolution: "1024x576_24FPS",
model: "zeroscope_v2_XL",
modelUrl: "https://huggingface.co/cerspense/zeroscope_v2_XL",
},
comedy: {
id: "comedy",
label: "#Entertainment",
audience: 0,
online: false,
visible: true,
url: "https://jbilcke-hf-media-server.hf.space/live/comedy.flv",
resolution: "1024x576_24FPS",
model: "zeroscope_v2_XL",
modelUrl: "https://huggingface.co/cerspense/zeroscope_v2_XL",
},
documentary: {
id: "documentary",
label: "#Reset",
audience: 0,
online: false,
visible: true,
url: "https://jbilcke-hf-media-server.hf.space/live/documentary.flv",
resolution: "1024x576_24FPS",
model: "zeroscope_v2_XL",
modelUrl: "https://huggingface.co/cerspense/zeroscope_v2_XL",
},
},
muted: true,
initialized: false,
activityTimeout: null,
defaultChannelId: "random",
video: null,
channel: {},
wakeUp() {
this.showToolbar = true;
},
toggleAudio() {
if (this.video.muted) {
this.video.muted = false;
this.muted = false;
} else {
this.video.muted = true;
this.muted = true;
}
},
async checkAudience() {
let audience = {};
try {
const res = await fetch("/stats");
audience = await res.json();
} catch (err) {
console.log("failed to check the audience, something is wrong");
}
window.DEBUGME = Object.entries(this.channels);
this.channels = Object.entries(this.channels).reduce(
(acc, [channel, data]) => (
console.log("debug:", {
...data,
audience: audience[channel] || 0,
}),
{
...acc,
[channel]: {
...data,
audience: audience[channel] || 0,
},
}
),
{}
);
this.channel = this.channels[this.channel.id];
},
fullscreen() {
if (this.video.requestFullscreen) {
this.video.requestFullscreen();
} else if (this.video.mozRequestFullScreen) {
this.video.mozRequestFullScreen();
} else if (this.video.webkitRequestFullscreen) {
this.video.webkitRequestFullscreen();
} else if (this.video.msRequestFullscreen) {
this.video.msRequestFullscreen();
}
},
init() {
if (this.initialized) {
console.log("already initialized");
return;
}
this.initialized = true;
console.log("initializing..");
const urlParams = new URLSearchParams(window.location.search);
const requestedChannelId = `${
urlParams.get("channel") || "random"
}`;
this.enabled = true;
// this.enabled = `${urlParams.get('beta') || 'false'}` === 'true'
if (!this.enabled) {
return;
}
this.video = document.getElementById("videoElement");
const defaultChannel = this.channels[this.defaultChannelId];
this.channel = this.channels[requestedChannelId] || defaultChannel;
console.log(`Selected channel: ${this.channel.label}`);
console.log(`Stream URL: ${this.channel.url}`);
const handleActivity = () => {
this.wakeUp();
};
handleActivity();
this.checkAudience();
setInterval(() => {
this.checkAudience();
}, 1000);
// detect mute/unmute events
this.video.addEventListener("mute", () => {
this.muted = true;
});
this.video.addEventListener("unmute", () => {
this.muted = false;
});
// as a bonus, we also allow fullscreen on double click
this.video.addEventListener("dblclick", () => {
this.fullscreen();
});
// some devices such as the iPhone don't support MSE Live Playback
if (mpegts.getFeatureList().mseLivePlayback) {
var player = mpegts.createPlayer({
type: "flv", // could also be mpegts, m2ts, flv
isLive: true,
url: this.channel.url,
});
player.attachMediaElement(this.video);
player.on(mpegts.Events.ERROR, function (err) {
console.log("got an error:", err);
if (err.type === mpegts.ErrorTypes.NETWORK_ERROR) {
console.log("Network error");
}
});
player.load();
// due to an issue with our stream when the FFMPEG playlist ends,
// the stream gets interrupted for ~1sec, which causes the frontend to hangs up
// the following code tries to restart the page when that happens, but in the long term
// we should fix the issue on the server side (fix our FFMPEG bash script)
this.video.addEventListener(
"ended",
function () {
console.log("Stream ended, trying to reload...");
setTimeout(() => {
console.log("Reloading the page..");
// Unloading and loading the source again isn't enough it seems
// player.unload()
// player.load()
window.location.reload();
}, 1200);
},
false
);
// Handle autoplay restrictions.
let promise = this.video.play();
if (promise !== undefined) {
this.video.addEventListener("click", function () {
this.video.play();
});
}
player.play();
}
},
};
}
</script>
</body>
</html>