Files
ds-play/app/static/index.html
2025-05-12 10:14:22 +03:00

237 lines
9.2 KiB
HTML
Executable File

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Media Player</title>
<style>
body {
font-family: Arial, sans-serif;
margin: 0;
padding: 0;
background-color: black;
color: white;
display: flex;
flex-direction: column;
height: 100vh;
overflow: hidden; /* Prevent scrolling */
}
.playlist-container {
flex: 1;
overflow: hidden;
display: flex;
justify-content: center;
align-items: center;
background-color: black;
position: relative; /* Enable positioning of child elements */
}
.playlist-container img,
.playlist-container video {
width: 100%; /* Make the video fill the width */
height: 100%; /* Make the video fill the height */
object-fit: cover; /* Ensure the video scales to cover the container */
}
.controls-wrapper {
position: fixed; /* Fix the controls at the bottom of the page */
bottom: 0; /* Align to the bottom */
left: 0; /* Align to the left */
width: 100%; /* Full width */
display: flex;
justify-content: center;
gap: 15px; /* Space between buttons */
padding: 10px;
background-color: rgba(0, 0, 0, 0.5); /* Increased transparency */
border-top: 2px solid #444; /* Add a border at the top */
z-index: 100; /* Ensure buttons are above the media */
transition: opacity 0.5s ease; /* Smooth fade effect */
}
.controls-wrapper.hidden {
opacity: 0; /* Hide the buttons */
pointer-events: none; /* Disable interaction when hidden */
}
button {
margin: 5px;
padding: 10px;
background-color: #444;
color: white;
border: none;
border-radius: 5px;
cursor: pointer;
font-size: 20px;
}
button:hover {
background-color: #666;
}
button i {
pointer-events: none;
}
</style>
<!-- Add Font Awesome for icons -->
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0-beta3/css/all.min.css">
</head>
<body>
<div class="playlist-container" id="playlist-container">
<!-- Content will be dynamically added here -->
</div>
<div class="controls-wrapper" id="controls-wrapper">
<button onclick="previousMedia()"><i class="fas fa-step-backward"></i></button> <!-- Previous -->
<button onclick="refreshPlaylist()"><i class="fas fa-sync-alt"></i></button> <!-- Refresh Playlist -->
<button id="playPauseButton" onclick="togglePlayPause()"><i class="fas fa-play"></i></button> <!-- Play/Pause -->
<button onclick="nextMedia()"><i class="fas fa-step-forward"></i></button> <!-- Next -->
<button onclick="stopMedia()"><i class="fas fa-stop"></i></button> <!-- Stop -->
<button onclick="goToSettings()"><i class="fas fa-cog"></i></button> <!-- Settings -->
</div>
<script>
const apiBase = '/api';
let appConfig = {}; // Global variable to store app configuration
let playlist = []; // Global variable for the playlist
let currentIndex = 0; // Current index in the playlist
let playbackInterval;
let isPaused = false;
// Load configuration on page load
async function loadConfig() {
try {
const response = await fetch('/static/app_config.json'); // Fetch app_config.json
if (!response.ok) {
throw new Error(`Failed to load configuration: ${response.statusText}`);
}
appConfig = await response.json(); // Store configuration in the global variable
console.log("App configuration loaded:", appConfig); // Debug log
} catch (error) {
console.error("Error loading app configuration:", error);
}
}
// Load playlist from updated_playlist.json
async function loadPlaylist() {
try {
const response = await fetch('/updated_playlist.json'); // Fetch updated_playlist.json
if (!response.ok) {
throw new Error(`Failed to load playlist: ${response.statusText}`);
}
playlist = await response.json(); // Store playlist in the global variable
console.log("Updated playlist loaded:", playlist); // Debug log
} catch (error) {
console.error("Error loading updated playlist:", error);
}
}
// Play the current item in the playlist
async function playCurrentItem() {
if (currentIndex >= playlist.length) {
currentIndex = 0; // Loop back to the beginning
}
const currentItem = playlist[currentIndex];
console.log("Playing current item:", currentItem); // Debug log
const playlistContainer = document.getElementById('playlist-container');
playlistContainer.innerHTML = ''; // Clear the container
if (currentItem.type === 'image') {
const img = document.createElement('img');
img.src = currentItem.url;
// Check the orientation of the image and adjust the object-fit property
const image = new Image();
image.src = currentItem.url;
image.onload = () => {
const isImageLandscape = image.width > image.height;
if (
(appConfig.player_orientation === 'landscape' && !isImageLandscape) ||
(appConfig.player_orientation === 'portrait' && isImageLandscape)
) {
img.style.objectFit = 'contain'; // Show the full image without cropping
} else {
img.style.objectFit = 'cover'; // Crop to fit the container
}
};
playlistContainer.appendChild(img);
// Display the image for the specified duration
playbackInterval = setTimeout(() => {
if (!isPaused) {
currentIndex++;
playCurrentItem();
}
}, currentItem.duration * 1000);
} else if (currentItem.type === 'video') {
const video = document.createElement('video');
video.src = currentItem.url;
video.autoplay = true;
video.controls = false;
playlistContainer.appendChild(video);
// Ensure the video starts playing
video.play().catch(error => {
console.error("Error starting video playback:", error);
});
// Play the video and move to the next item after it ends
video.onended = () => {
if (!isPaused) {
currentIndex++;
playCurrentItem();
}
};
}
}
// Function to stop playback
function stopMedia() {
clearTimeout(playbackInterval);
playlistContainer.innerHTML = ''; // Clear the container
}
// Function to play the previous item
function previousMedia() {
stopMedia();
currentIndex = (currentIndex - 1 + playlist.length) % playlist.length;
playCurrentItem();
}
// Function to refresh the playlist
function refreshPlaylist() {
loadPlaylist(); // Reload the playlist
}
// Function to toggle play/pause
function togglePlayPause() {
isPaused = !isPaused;
const playPauseButton = document.getElementById('playPauseButton');
if (isPaused) {
playPauseButton.innerHTML = '<i class="fas fa-pause"></i>'; // Change to pause icon
} else {
playPauseButton.innerHTML = '<i class="fas fa-play"></i>'; // Change to play icon
playCurrentItem(); // Resume playback
}
}
// Function to play the next item
function nextMedia() {
stopMedia();
currentIndex = (currentIndex + 1) % playlist.length;
playCurrentItem();
}
function goToSettings() {
window.location.href = '/static/settings.html';
}
// Initialize the page
async function initialize() {
await loadConfig(); // Load app configuration
await loadPlaylist(); // Load playlist
playCurrentItem(); // Start playing the playlist
}
// Start initialization when the page loads
window.onload = initialize;
// Start periodic playlist reload
setInterval(loadPlaylist, 300000); // Check every 5 minutes (300,000 ms)
</script>
</body>
</html>