// Multimedia Control System with Transformers.js
class MultimediaController {
constructor() {
this.devices = [];
this.playlist = [];
this.currentVideo = null;
this.isPlaying = false;
this.progress = 0;
this.volume = 50;
this.aiModel = null;
this.modelLoaded = false;
this.initializeDevices();
this.initializePlaylist();
this.initializeAI();
this.startProgressUpdater();
}
initializeDevices() {
// Initialize simulated TV devices
const deviceConfigs = [
{ name: "TV - Sala Principal", location: "Sala", type: "4K Smart TV" },
{ name: "TV - Barra", location: "Bar", type: "HD TV" },
{ name: "TV - Terraza", location: "Terraza", type: "Outdoor TV" }
];
this.devices = deviceConfigs.map((config, index) => ({
id: index + 1,
...config,
status: 'connected',
isPlaying: false,
currentContent: 'Esperando...',
volume: 50,
isMuted: false
}));
this.renderDevices();
this.renderIndividualControls();
}
initializePlaylist() {
this.playlist = [
{
title: "Video Promocional - Restaurante",
source: "YouTube",
url: "https://www.youtube.com/watch?v=dQw4w9WgXcQ",
duration: "3:45",
thumbnail: "https://picsum.photos/seed/promo/60/40"
},
{
title: "Video Corporativo 2024",
source: "Vimeo",
url: "https://vimeo.com/123456789",
duration: "2:30",
thumbnail: "https://picsum.photos/seed/corp/60/40"
},
{
title: "Video Evento Especial",
source: "Directo",
url: "https://commondatastorage.googleapis.com/gtv-videos-bucket/sample/BigBuckBunny.mp4",
duration: "5:15",
thumbnail: "https://picsum.photos/seed/event/60/40"
}
];
this.renderPlaylist();
}
async initializeAI() {
try {
// Initialize a text classification model for content analysis
this.updateLoadingStatus('Cargando modelo de clasificación de texto...');
this.updateLoadingProgress(30);
// Using a lightweight model for text classification
this.aiModel = await pipeline('text-classification', 'Xenova/distilbert-base-uncased-finetuned-sst-2-english');
this.updateLoadingProgress(70);
this.updateLoadingStatus('Modelo cargado exitosamente...');
this.modelLoaded = true;
this.updateLoadingProgress(100);
setTimeout(() => {
document.getElementById('loadingScreen').classList.add('hidden');
this.updateAIModelStatus('Listo');
this.showStatus('✅ Sistema AI inicializado', 'success');
}, 1000);
} catch (error) {
console.error('Error loading AI model:', error);
this.updateLoadingStatus('Error al cargar el modelo AI');
setTimeout(() => {
document.getElementById('loadingScreen').classList.add('hidden');
this.updateAIModelStatus('Error');
this.showStatus('⚠️ AI no disponible (modo offline)', 'warning');
}, 2000);
}
}
updateLoadingProgress(percent) {
document.getElementById('loadingProgress').style.width = percent + '%';
}
updateLoadingStatus(status) {
document.getElementById('loadingStatus').textContent = status;
}
updateAIModelStatus(status) {
const element = document.getElementById('aiModelStatus');
element.textContent = status;
element.className = status === 'Listo' ? 'font-semibold text-green-600' : 'font-semibold text-red-600';
}
renderDevices() {
const container = document.getElementById('devicesContainer');
container.innerHTML = '';
this.devices.forEach(device => {
const statusColor = {
'connected': 'bg-green-100 text-green-800',
'playing': 'bg-blue-100 text-blue-800',
'paused': 'bg-yellow-100 text-yellow-800',
'offline': 'bg-red-100 text-red-800'
}[device.status] || 'bg-gray-100 text-gray-800';
const statusIcon = {
'connected': 'fa-check-circle',
'playing': 'fa-play-circle',
'paused': 'fa-pause-circle',
'offline': 'fa-times-circle'
}[device.status] || 'fa-question-circle';
const deviceCard = `
${device.name}
${device.status}
Ubicación:
${device.location}
Tipo:
${device.type}
Contenido:
${device.currentContent}
Volumen:
${device.volume}% ${device.isMuted ? '🔇' : '🔊'}
`;
container.innerHTML += deviceCard;
});
}
renderIndividualControls() {
const container = document.getElementById('individualControls');
container.innerHTML = '';
this.devices.forEach(device => {
const controls = `
`;
container.innerHTML += controls;
});
}
renderPlaylist() {
const container = document.getElementById('playlistContainer');
container.innerHTML = '';
this.playlist.forEach((video, index) => {
const item = `
${video.title}
${video.source} • ${video.duration}
`;
container.innerHTML += item;
});
}
async loadVideo(url, title = '') {
if (!url) {
this.showStatus('❌ Por favor, introduce una URL válida', 'error');
return;
}
this.currentVideo = {
url: url,
title: title || this.extractVideoTitle(url)
};
// Update all devices
this.devices.forEach(device => {
device.currentContent = this.currentVideo.title;
device.status = 'connected';
});
this.renderDevices();
this.showStatus(`✅ Video cargado: ${this.currentVideo.title}`, 'success');
document.getElementById('videoUrl').value = url;
}
extractVideoTitle(url) {
if (url.includes('youtube.com')) return 'Video de YouTube';
if (url.includes('vimeo.com')) return 'Video de Vimeo';
if (url.includes('.mp4')) return 'Video Directo MP4';
return 'Video Online';
}
playAll() {
if (!this.currentVideo) {
this.showStatus('❌ No hay video cargado', 'error');
return;
}
this.isPlaying = true;
this.devices.forEach(device => {
device.status = 'playing';
device.isPlaying = true;
});
this.renderDevices();
this.showStatus('▶️ Reproduciendo en todos los dispositivos', 'success');
this.updateSystemStatus('Reproduciendo');
}
pauseAll() {
this.isPlaying = false;
this.devices.forEach(device => {
device.status = 'connected';
device.isPlaying = false;
});
this.renderDevices();
this.showStatus('⏸️ Pausado en todos los dispositivos', 'info');
this.updateSystemStatus('Pausado');
}
stopAll() {
this.isPlaying = false;
this.progress = 0;
this.devices.forEach(device => {
device.status = 'connected';
device.isPlaying = false;
device.currentContent = 'Esperando...';
});
this.renderDevices();
this.updateProgress();
this.showStatus('⏹️ Detenido en todos los dispositivos', 'info');
this.updateSystemStatus('Detenido');
}
controlDevice(deviceId, action) {
const device = this.devices.find(d => d.id === deviceId);
if (!device) return;
switch (action) {
case 'play':
if (!this.currentVideo) {
this.showStatus('❌ No hay video cargado', 'error');
return;
}
device.status = 'playing';
device.isPlaying = true;
this.showStatus(`▶️ Reproduciendo en ${device.name}`, 'success');
break;
case 'pause':
device.status = 'connected';
device.isPlaying = false;
this.showStatus(`⏸️ Pausado en ${device.name}`, 'info');
break;
case 'stop':
device.status = 'connected';
device.isPlaying = false;
device.currentContent = 'Esperando...';
this.showStatus(`⏹️ Detenido en ${device.name}`, 'info');
break;
case 'mute':
device.isMuted = !device.isMuted;
this.showStatus(`🔇 ${device.isMuted ? 'Silenciado' : 'Activado'} en ${device.name}`, 'info');
break;
case 'volumeUp':
device.volume = Math.min(100, device.volume + 10);
this.showStatus(`🔊 Volumen ${device.volume}% en ${device.name}`, 'info');
break;
case 'volumeDown':
device.volume = Math.max(0, device.volume - 10);
this.showStatus(`🔉 Volumen ${device.volume}% en ${device.name}`, 'info');
break;
}
this.renderDevices();
}
changeVolume(volume) {
this.volume = parseInt(volume);
this.devices.forEach(device => {
device.volume = this.volume;
});
document.getElementById('volumePercentage').textContent = volume + '%';
this.renderDevices();
this.showStatus(`🔊 Volumen ajustado a ${volume}%`, 'info');
}
muteAll() {
const allMuted = this.devices.every(d => d.isMuted);
this.devices.forEach(device => {
device.isMuted = !allMuted;
});
this.renderDevices();
this.showStatus(`🔇 ${allMuted ? 'Activado' : 'Silenciado'} en todos los dispositivos`, 'info');
}
setVolume(volume) {
document.getElementById('volumeSlider').value = volume;
this.changeVolume(volume);
}
async analyzeContent() {
if (!this.modelLoaded) {
this.showStatus('❌ Modelo AI no disponible', 'error');
return;
}
if (!this.currentVideo) {
this.showStatus('❌ No hay video para analizar', 'error');
return;
}
this.showStatus('🧠 Analizando contenido con AI...', 'info');
try {
// Simulate content analysis
const analysisText = `El video "${this.currentVideo.title}" es un contenido de alta calidad`;
const result = await this.aiModel(analysisText);
const analysisHTML = `
Título: ${this.currentVideo.title}
URL: ${this.currentVideo.url}
Sentimiento: ${result[0].label} (${(result[0].score * 100).toFixed(1)}%)
Calidad: Alta definición detectada
Categoría: ${this.detectCategory()}
Duración recomendada: ${this.recommendDuration()}
`;
document.getElementById('analysisResults').innerHTML = analysisHTML;
document.getElementById('aiAnalysis').classList.remove('hidden');
this.showStatus('✅ Análisis completado exitosamente', 'success');
} catch (error) {
console.error('Analysis error:', error);
this.showStatus('❌ Error en el análisis AI', 'error');
}
}
detectCategory() {
if (!this.currentVideo) return 'Desconocida';
const title = this.currentVideo.title.toLowerCase();
if (title.includes('promocional')) return 'Marketing/Publicidad';
if (title.includes('corporativo')) return 'Corporativo';
if (title.includes('evento')) return 'Eventos';
return 'General';
}
recommendDuration() {
if (!this.currentVideo) return 'N/A';
const category = this.detectCategory();
const recommendations = {
'Marketing/Publicidad': '30-60 segundos',
'Corporativo': '2-5 minutos',
'Eventos': '3-10 minutos',
'General': '1-5 minutos'
};
return recommendations[category] || '1-5 minutos';
}
addToPlaylist(url, title = '') {
if (!url) {
this.showStatus('❌ Introduce una URL válida', 'error');
return;
}
const video = {
title: title || this.extractVideoTitle(url),
source: this.extractSource(url),
url: url,
duration: '--:--',
thumbnail: `https://picsum.photos/seed/${Date.now()}/60/40`
};
this.playlist.push(video);
this.renderPlaylist();
this.showStatus(`✅ "${video.title}" agregado a la playlist`, 'success');
// Clear inputs
document.getElementById('playlistUrl').value = '';
document.getElementById('playlistTitle').value = '';
}
extractSource(url) {
if (url.includes('youtube.com')) return 'YouTube';
if (url.includes('vimeo.com')) return 'Vimeo';
if (url.includes('.mp4')) return 'Directo';
return 'Online';
}
playFromPlaylist(index) {
if (index >= 0 && index < this.playlist.length) { const video=this.playlist[index]; this.loadVideo(video.url,
video.title); this.playAll(); } } loadSampleVideo(type) { const samples={
youtube: 'https://www.youtube.com/watch?v=dQw4w9WgXcQ' , vimeo: 'https://vimeo.com/123456789' ,
direct: 'https://commondatastorage.googleapis.com/gtv-videos-bucket/sample/BigBuckBunny.mp4' }; const
url=samples[type]; this.loadVideo(url); } discoverDevices() { this.showStatus('🔍 Buscando dispositivos...', 'info' );
// Simulate device discovery setTimeout(()=> {
this.renderDevices();
this.showStatus(`✅ ${this.devices.length} dispositivos encontrados`, 'success');
}, 1500);
}
refreshStatus() {
this.renderDevices();
this.showStatus('🔄 Estado actualizado', 'info');
}
rewind() {
this.progress = Math.max(0, this.progress - 10);
this.updateProgress();
this.showStatus('⏪ Retrocediendo 10 segundos', 'info');
}
forward() {
this.progress = Math.min(100, this.progress + 10);
this.updateProgress();
this.showStatus('⏩ Adelantando 10 segundos', 'info');
}
updateProgress() {
const progressBar = document.getElementById('progressBar');
const currentTime = document.getElementById('currentTime');
progressBar.style.width = this.progress + '%';
const totalSeconds = 225; // 3:45 in seconds
const currentSeconds = Math.floor((this.progress / 100) * totalSeconds);
const minutes = Math.floor(currentSeconds / 60);
const seconds = currentSeconds % 60;
currentTime.textContent = `${minutes.toString().padStart(2, '0')}:${seconds.toString().padStart(2, '0')}`;
}
startProgressUpdater() {
setInterval(() => {
if (this.isPlaying && this.progress < 100) { this.progress +=0.5; this.updateProgress(); } }, 1000); }
showStatus(message, type='info' ) { const statusElement=document.getElementById('statusMessage');
statusElement.textContent=message; // Update styling based on type
statusElement.className='mt-3 p-3 rounded-lg text-sm ' ; switch (type) { case 'success' : statusElement.className
+='bg-green-100 text-green-700' ; break; case 'error' : statusElement.className +='bg-red-100 text-red-700' ; break;
case 'warning' : statusElement.className +='bg-yellow-100 text-yellow-700' ; break; default: statusElement.className
+='bg-gray-100 text-gray-700' ; } } updateSystemStatus(status) { const
element=document.getElementById('systemStatus'); element.textContent=status; element.className='font-semibold ' ;
switch (status) { case 'Reproduciendo' : element.className +='text-blue-600' ; break; case 'Pausado' :
element.className +='text-yellow-600' ; break; case 'Detenido' : element.className +='text-gray-600' ; break;
default: element.className +='text-green-600' ; } } } // Global controller instance let controller; // Initialize
when DOM is loaded document.addEventListener('DOMContentLoaded', ()=> {
controller = new MultimediaController();
});
// Global functions for button onclick handlers
function loadVideo() {
const url = document.getElementById('videoUrl').value;
controller.loadVideo(url);
}
function loadSampleVideo(type) {
controller.loadSampleVideo(type);
}
function playAll() {
controller.playAll();
}
function pauseAll() {
controller.pauseAll();
}
function stopAll() {
controller.stopAll();
}
function rewind() {
controller.rewind();
}
function forward() {
controller.forward();
}
function changeVolume(value) {
controller.changeVolume(value);
}
function muteAll() {
controller.muteAll();
}
function setVolume(value) {
controller.setVolume(value);
}
function analyzeContent() {
controller.analyzeContent();
}
function addToPlaylist() {
const url = document.getElementById('playlistUrl').value;
const title = document.getElementById('playlistTitle').value;
controller.addToPlaylist(url, title);
}
function playFromPlaylist(index) {
controller.playFromPlaylist(index);
}
function controlDevice(deviceId, action) {
controller.controlDevice(deviceId, action);
}
function discoverDevices() {
controller.discoverDevices();
}
function refreshStatus() {
controller.refreshStatus();
}