Add background video support to Quick Play

- Added video mode selection (none, background, popup, multi-screen)
- Implemented BaseVideoPlayer integration for background videos
- Added video opacity, sound, and control options
- Enhanced video library initialization for Quick Play mode
- Added user-friendly notifications when no videos are available
- Improved video container styling with proper layering
- Added automatic random video loading and rotation
- Enhanced task display readability over background video
This commit is contained in:
dilgenfritz 2025-11-03 19:44:01 -06:00
parent a10a6bafef
commit 8fb373afdb
1 changed files with 515 additions and 2 deletions

View File

@ -127,6 +127,47 @@
</div>
</div>
<!-- Video Settings -->
<div class="setting-group">
<h3>🎬 Video Experience</h3>
<div class="video-settings">
<div class="setting-row">
<label for="video-mode">Video Mode:</label>
<select id="video-mode">
<option value="none">None - Focus Mode</option>
<option value="background" selected>Background Video</option>
<option value="popup">Popup Rewards</option>
<option value="multi-screen">Multi-Screen (Advanced)</option>
</select>
</div>
<div class="video-options" id="video-options">
<div class="video-option">
<input type="checkbox" id="enable-video-sound" checked>
<label for="enable-video-sound">
<span class="option-icon">🔊</span>
<span class="option-text">Video Audio</span>
</label>
</div>
<div class="video-option">
<input type="checkbox" id="enable-video-controls">
<label for="enable-video-controls">
<span class="option-icon">🎛️</span>
<span class="option-text">Show Video Controls</span>
</label>
</div>
<div class="setting-row">
<label for="video-opacity">Video Opacity:</label>
<select id="video-opacity">
<option value="0.3">30% - Subtle</option>
<option value="0.5">50% - Balanced</option>
<option value="0.7" selected>70% - Prominent</option>
<option value="1.0">100% - Full</option>
</select>
</div>
</div>
</div>
</div>
<!-- Visual Settings -->
<div class="setting-group">
<h3>🖼️ Visual Experience</h3>
@ -287,6 +328,10 @@
<script src="src/features/ui/flashMessageManager.js"></script>
<script src="src/features/images/popupImageManager.js"></script>
<script src="src/features/audio/audioManager.js"></script>
<script src="src/features/media/baseVideoPlayer.js"></script>
<script src="src/features/media/overlayVideoPlayer.js"></script>
<script src="src/features/media/quadVideoPlayer.js"></script>
<script src="src/features/media/videoLibrary.js"></script>
<script src="src/features/video/videoPlayerManager.js"></script>
<script src="src/features/webcam/webcamManager.js"></script>
<script src="src/features/tasks/aiTaskManager.js"></script>
@ -307,11 +352,17 @@
enableFlashMessages: true,
difficulty: 'medium',
includeStandardTasks: true,
includeScenarioTasks: false // Scenarios disabled by default
includeScenarioTasks: false, // Scenarios disabled by default
// Video settings
videoMode: 'background',
enableVideoSound: true,
enableVideoControls: false,
videoOpacity: 0.7
};
let gameInstance = null;
let isGameRunning = false;
let backgroundVideoPlayer = null;
// Initialize Quick Play when page loads
document.addEventListener('DOMContentLoaded', async function() {
@ -419,6 +470,12 @@
document.getElementById('enable-ambient-audio').checked = quickPlaySettings.enableAmbientAudio;
document.getElementById('enable-voice-commands').checked = quickPlaySettings.enableVoiceCommands;
// Apply video settings
document.getElementById('video-mode').value = quickPlaySettings.videoMode;
document.getElementById('enable-video-sound').checked = quickPlaySettings.enableVideoSound;
document.getElementById('enable-video-controls').checked = quickPlaySettings.enableVideoControls;
document.getElementById('video-opacity').value = quickPlaySettings.videoOpacity;
// Apply task type settings
document.getElementById('include-standard-tasks').checked = quickPlaySettings.includeStandardTasks;
document.getElementById('include-scenario-tasks').checked = quickPlaySettings.includeScenarioTasks;
@ -435,6 +492,220 @@
preset.classList.add('active');
}
});
// Show/hide video options based on mode
updateVideoOptionsVisibility();
}
async function initializeBackgroundVideo() {
try {
console.log('🎬 Initializing background video player...');
// Create BaseVideoPlayer instance for background video
backgroundVideoPlayer = new BaseVideoPlayer('#background-video-container', {
showControls: quickPlaySettings.enableVideoControls,
autoHide: true,
showProgress: false,
showVolume: true,
showFullscreen: false,
showQuality: false,
showSpeed: false,
keyboardShortcuts: false, // Disable to avoid conflicts with game controls
minimal: !quickPlaySettings.enableVideoControls
});
// Set initial volume based on settings
backgroundVideoPlayer.setVolume(quickPlaySettings.enableVideoSound ? 0.3 : 0);
// Set video opacity
const videoElement = backgroundVideoPlayer.videoElement;
if (videoElement) {
videoElement.style.opacity = quickPlaySettings.videoOpacity;
}
// Setup background video specific event listeners
setupBackgroundVideoListeners();
// Load random video
await loadRandomBackgroundVideo();
console.log('✅ Background video player initialized');
} catch (error) {
console.error('❌ Error initializing background video:', error);
}
}
async function loadRandomBackgroundVideo() {
try {
// Get all available videos using the same logic as other video players
let allVideos = [];
// First check if we have a video library instance
if (window.videoLibrary && typeof window.videoLibrary.getAllVideos === 'function') {
allVideos = window.videoLibrary.getAllVideos();
console.log(`🎬 Got ${allVideos.length} videos from VideoLibrary instance`);
}
// Try desktop file manager
if (allVideos.length === 0 && window.desktopFileManager) {
allVideos = window.desktopFileManager.getAllVideos();
console.log(`🎬 Got ${allVideos.length} videos from DesktopFileManager`);
}
// Fallback to unified storage
if (allVideos.length === 0) {
const unifiedData = JSON.parse(localStorage.getItem('unifiedVideoLibrary') || '{}');
allVideos = unifiedData.allVideos || [];
console.log(`🎬 Got ${allVideos.length} videos from unified storage`);
}
// Fallback to legacy storage
if (allVideos.length === 0) {
const storedVideos = JSON.parse(localStorage.getItem('videoFiles') || '{}');
allVideos = Object.values(storedVideos).flat();
console.log(`🎬 Got ${allVideos.length} videos from legacy storage`);
}
// If still no videos, try to initialize video library
if (allVideos.length === 0) {
console.log('🎬 No videos found, attempting to initialize video library...');
await initializeVideoLibrary();
// Try again after initialization
const unifiedData = JSON.parse(localStorage.getItem('unifiedVideoLibrary') || '{}');
allVideos = unifiedData.allVideos || [];
console.log(`🎬 After initialization: ${allVideos.length} videos available`);
}
if (allVideos.length === 0) {
console.warn('⚠️ No videos available for background playback');
showVideoSetupNotification();
return;
}
// Select random video
const randomIndex = Math.floor(Math.random() * allVideos.length);
const randomVideo = allVideos[randomIndex];
console.log(`🎬 Loading background video: ${randomVideo.name || randomVideo.title}`);
// Load video without autoplay initially
backgroundVideoPlayer.loadVideo(randomVideo.path || randomVideo.filePath, false);
// Start playing after a short delay to ensure task focus isn't disrupted
setTimeout(() => {
if (backgroundVideoPlayer && backgroundVideoPlayer.videoElement) {
backgroundVideoPlayer.play();
}
}, 2000);
} catch (error) {
console.error('❌ Error loading background video:', error);
}
}
function setupBackgroundVideoListeners() {
if (!backgroundVideoPlayer) return;
// Random video button
const randomBtn = document.querySelector('.random-video-btn');
if (randomBtn) {
randomBtn.addEventListener('click', () => {
loadRandomBackgroundVideo();
});
}
// Video ended - load next random video
if (backgroundVideoPlayer.videoElement) {
backgroundVideoPlayer.videoElement.addEventListener('ended', () => {
setTimeout(() => {
loadRandomBackgroundVideo();
}, 1000);
});
// Handle video errors
backgroundVideoPlayer.videoElement.addEventListener('error', () => {
console.warn('Background video error, loading new video...');
setTimeout(() => {
loadRandomBackgroundVideo();
}, 2000);
});
}
}
function updateVideoOptionsVisibility() {
const videoOptions = document.getElementById('video-options');
const videoMode = document.getElementById('video-mode').value;
if (videoMode === 'none') {
videoOptions.style.display = 'none';
} else {
videoOptions.style.display = 'block';
}
}
async function initializeVideoLibrary() {
try {
console.log('🎬 Attempting to initialize video library for Quick Play...');
// Check if we have linked video directories
const linkedDirs = JSON.parse(localStorage.getItem('linkedVideoDirectories') || '[]');
if (linkedDirs.length > 0) {
console.log(`🎬 Found ${linkedDirs.length} linked directories, scanning...`);
// Initialize VideoLibrary to scan directories
if (typeof VideoLibrary !== 'undefined') {
const tempVideoLibrary = new VideoLibrary({
videoContainer: document.createElement('div')
});
await tempVideoLibrary.loadVideoLibrary();
window.videoLibrary = tempVideoLibrary;
console.log('🎬 VideoLibrary initialized successfully');
}
return true;
}
console.log('🎬 No linked directories found');
return false;
} catch (error) {
console.error('❌ Error initializing video library:', error);
return false;
}
}
function showVideoSetupNotification() {
// Show a user-friendly notification about setting up videos
const taskTitle = document.getElementById('task-title');
const taskText = document.getElementById('task-text');
if (taskTitle && taskText) {
// Temporarily show setup message
const originalTitle = taskTitle.textContent;
const originalText = taskText.textContent;
taskTitle.textContent = '🎬 Background Video Setup';
taskText.innerHTML = `
No videos found for background playback.<br>
To enable background videos:<br>
1. Go to the main menu → Porn Cinema<br>
2. Add video directories or files<br>
3. Return to Quick Play<br><br>
<small>Continuing without background video...</small>
`;
// Restore original content after 8 seconds
setTimeout(() => {
if (taskTitle && taskText) {
taskTitle.textContent = originalTitle;
taskText.textContent = originalText;
}
}, 8000);
}
console.log('📋 Video setup notification shown to user');
}
function setupEventListeners() {
@ -550,6 +821,21 @@
quickPlaySettings.enableVoiceCommands = e.target.checked;
});
// Video settings
document.getElementById('video-mode').addEventListener('change', (e) => {
quickPlaySettings.videoMode = e.target.value;
updateVideoOptionsVisibility();
});
document.getElementById('enable-video-sound').addEventListener('change', (e) => {
quickPlaySettings.enableVideoSound = e.target.checked;
});
document.getElementById('enable-video-controls').addEventListener('change', (e) => {
quickPlaySettings.enableVideoControls = e.target.checked;
});
document.getElementById('video-opacity').addEventListener('change', (e) => {
quickPlaySettings.videoOpacity = parseFloat(e.target.value);
});
// Task type checkboxes
document.getElementById('include-standard-tasks').addEventListener('change', (e) => {
quickPlaySettings.includeStandardTasks = e.target.checked;
@ -614,9 +900,39 @@
function initializeGameInstance() {
const gameContainer = document.getElementById('game-container-wrapper');
// Create the game interface structure
// Create the game interface structure with optional background video
const hasBackgroundVideo = quickPlaySettings.videoMode === 'background';
gameContainer.innerHTML = `
<div class="game-container">
${hasBackgroundVideo ? `
<!-- Background Video Container -->
<div id="background-video-container" class="background-video-container">
<video id="background-video" class="background-video" preload="metadata" loop>
<source id="background-video-source" src="" type="video/mp4">
Your browser does not support the video tag.
</video>
<!-- Video Controls (optional) -->
<div class="video-controls background-video-controls" style="display: ${quickPlaySettings.enableVideoControls ? 'flex' : 'none'};">
<div class="controls-row">
<button class="control-btn play-pause-btn" title="Play/Pause"></button>
<div class="volume-control">
<button class="control-btn mute-btn" title="Mute">🔊</button>
<input type="range" class="volume-slider" min="0" max="100" value="70">
</div>
<button class="control-btn random-video-btn" title="Random Video">🎲</button>
</div>
</div>
<!-- Video Loading Indicator -->
<div class="video-loading" id="background-video-loading" style="display: none;">
<div class="loading-spinner"></div>
<p>Loading video...</p>
</div>
</div>
` : ''}
<!-- Include main game interface elements here -->
<div class="game-content">
<div class="main-content-area">
@ -648,6 +964,15 @@
console.log('Game button listeners set up after DOM creation');
}, 100);
// Initialize background video if enabled
if (hasBackgroundVideo) {
setTimeout(() => {
initializeBackgroundVideo();
}, 200);
} else {
console.log('🎬 Background video disabled - video mode:', quickPlaySettings.videoMode);
}
// Initialize the game instance with Quick Play specific settings
setTimeout(() => {
initializeFullGame();
@ -974,6 +1299,20 @@
}
}
// Clean up background video
if (backgroundVideoPlayer) {
console.log('Stopping background video');
try {
backgroundVideoPlayer.pause();
if (backgroundVideoPlayer.destroy) {
backgroundVideoPlayer.destroy();
}
backgroundVideoPlayer = null;
} catch (videoError) {
console.warn('Error stopping background video:', videoError);
}
}
// Collect results
const timer = document.getElementById('game-timer');
const tasksElement = document.getElementById('tasks-completed');
@ -2075,6 +2414,180 @@
padding: 20px 0;
}
}
/* Background Video Styles */
.background-video-container {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
z-index: 1;
overflow: hidden;
border-radius: 15px;
}
.background-video {
width: 100%;
height: 100%;
object-fit: cover;
object-position: center;
transition: opacity 0.3s ease;
}
.background-video-controls {
position: absolute;
bottom: 10px;
left: 50%;
transform: translateX(-50%);
background: rgba(0, 0, 0, 0.7);
border-radius: 20px;
padding: 8px 16px;
opacity: 0;
transition: opacity 0.3s ease;
z-index: 10;
}
.background-video-container:hover .background-video-controls {
opacity: 1;
}
.background-video-controls .controls-row {
display: flex;
align-items: center;
gap: 12px;
}
.background-video-controls .control-btn {
background: transparent;
border: none;
color: white;
font-size: 14px;
cursor: pointer;
padding: 4px 8px;
border-radius: 4px;
transition: background-color 0.2s ease;
}
.background-video-controls .control-btn:hover {
background: rgba(255, 255, 255, 0.2);
}
.background-video-controls .volume-control {
display: flex;
align-items: center;
gap: 6px;
}
.background-video-controls .volume-slider {
width: 60px;
height: 4px;
background: rgba(255, 255, 255, 0.3);
border-radius: 2px;
outline: none;
cursor: pointer;
-webkit-appearance: none;
appearance: none;
}
.background-video-controls .volume-slider::-webkit-slider-thumb {
appearance: none;
width: 12px;
height: 12px;
border-radius: 50%;
background: #00d4ff;
cursor: pointer;
border: none;
}
.background-video-controls .volume-slider::-moz-range-thumb {
width: 12px;
height: 12px;
border-radius: 50%;
background: #00d4ff;
cursor: pointer;
border: none;
}
/* Ensure game content appears above background video */
.game-content {
position: relative;
z-index: 2;
background: rgba(0, 0, 0, 0.1); /* Slight overlay for better text readability */
border-radius: 15px;
}
/* Enhance task display container for better visibility over video */
.task-display-container {
background: rgba(0, 0, 0, 0.7) !important;
backdrop-filter: blur(5px);
border: 2px solid rgba(0, 212, 255, 0.5) !important;
}
.control-sidebar {
background: rgba(0, 0, 0, 0.8) !important;
backdrop-filter: blur(5px);
border: 1px solid rgba(0, 212, 255, 0.5) !important;
}
/* Video mode selection styles */
.video-settings {
display: flex;
flex-direction: column;
gap: 15px;
}
.video-options {
margin-left: 20px;
padding: 15px;
background: rgba(0, 212, 255, 0.05);
border: 1px solid rgba(0, 212, 255, 0.2);
border-radius: 8px;
}
.video-option {
display: flex;
align-items: center;
margin-bottom: 10px;
}
.video-option label {
display: flex;
align-items: center;
gap: 10px;
cursor: pointer;
color: #fff;
font-size: 14px;
}
/* Mobile adjustments for background video */
@media (max-width: 768px) {
.background-video-controls {
bottom: 5px;
padding: 6px 12px;
}
.background-video-controls .control-btn {
font-size: 12px;
padding: 3px 6px;
}
.background-video-controls .volume-slider {
width: 40px;
}
.game-content {
background: rgba(0, 0, 0, 0.2);
}
.task-display-container {
background: rgba(0, 0, 0, 0.8) !important;
}
.control-sidebar {
background: rgba(0, 0, 0, 0.9) !important;
}
}
</style>
</body>
</html>