aiwebvvv / public /index.html
lord6ablo's picture
Upload 5 files
d3036fc verified
raw
history blame
16.4 kB
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>V-Pod</title>
<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="risenfall.mp3" autoplay></audio>
<script src="/mpegts.js"></script>
</head>
<body>
<div
class="h-screen w-screen grid place-content-center place-items-center overflow-hidden bg-gradient-to-b from-slate-900 to-black"
>
<div id="backgroundVideo" class="absolute inset-0 z-0" style="background-size: cover; background-position: center;">
<video autoplay muted loop class="w-full h-full object-cover">
<source src="v1.mp4" type="video/mp4">
</video>
>
<div class="flex place-content-center justify-between flex-row">
<h1 class="display-flex text-4xl font-black text-teal-300">VGФЙЧ</h1>
<h2 class="cursive text-6xl font-bold text-fuchsia-500">forever</h2>
</div>
</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-2">
<video
id="videoElement"
class="aspect-video mx-auto w-auto border-4 border-6 border-orange-900/20 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">
<a class="flex grid place-content-end mr-8" href="https://vgony.tech">
<svg xmlns="http://www.w3.org/2000/svg" class="h-6 w-6" fill="none" viewBox="0 0 24 24" stroke="white">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M17 16l4-4m0 0l-4-4m4 4H7m6 4v1a3 3 0 01-3 3H6a3 3 0 01-3-3V7a3 3 0 013-3h4a3 0 013 3v1"></path>
</svg>
</a>
<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="10" height="10" />
<a class="tooltip-text">1 New Message</a>
</button>
</div>
</div>
</div>
<div id="placeholder" class="relative inset-0 z-0"></div>
<script>
// Get the audio element and play/pause button
// Get the audio element and play/pause button
const audioPlayer = document.getElementById('audioPlayer');
const playPauseBtn = document.getElementById('playPauseBtn');
// Array of audio file paths
const audioFiles = [
'hold.mp3',
'hold.mp3',
'risenfall.mp3',
'hold.mp3',
'risenfall.mp3',
'hold.mp3',
'risenfall.mp3',
'hold.mp3',
'tst.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;
}
// 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();
}
// Add a click event listener to 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';
}
});
// Shuffle the audio files array on page load
shuffleArray(audioFiles);
audioPlayer.src = audioFiles[0];
audioPlayer.play();
// Automatically play the next audio file after the current one finishes
audioPlayer.addEventListener('ended', playNextAudio);
document.addEventListener("DOMContentLoaded", function () {
setTimeout(function () {
showVideo();
fadeBackgroundImage();
}, 6500); //
});
function showVideo() {
var videoElement = document.getElementById("videoElement");
videoElement.classList.add("fade-in");
}
function fadeBackgroundImage() {
var backgroundElement = document.getElementById("backgroundImage");
backgroundElement.classList.add("fade-out");
}
</script>
<script>
// Get the audio element and play/pause button
// Get the audio element and play/pause button
const audioPlayer = document.getElementById('audioPlayer');
const playPauseBtn = document.getElementById('playPauseBtn');
// Array of audio file paths
const audioFiles = [
'overthink.mp3',
'overthink.mp3',
'overthink.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;
}
// 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();
}
// Add a click event listener to 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';
}
});
// Shuffle the audio files array on page load
shuffleArray(audioFiles);
audioPlayer.src = audioFiles[0];
audioPlayer.play();
// Automatically play the next audio file after the current one finishes
audioPlayer.addEventListener('ended', playNextAudio);
document.addEventListener("DOMContentLoaded", function () {
setTimeout(function () {
showVideo();
}, 3000); // 10 seconds
});
document.addEventListener("DOMContentLoaded", function () {
setTimeout(function () {
showVideo();
fadeBackgroundImage();
}, 1000); //
});
function showVideo() {
var videoElement = document.getElementById("videoElement");
videoElement.classList.add("fade-in");
}
function fadeBackgroundImage() {
var backgroundElement = document.getElementById("backgroundImage");
backgroundElement.classList.add("fade-out");
}
</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: "#random",
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: "#comedy",
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: "#documentary",
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>