music / index.html
Enoughking's picture
Add 2 files
0d9e07c verified
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>JioSaavn Clone</title>
<script src="https://cdn.tailwindcss.com"></script>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
<style>
@import url('https://fonts.googleapis.com/css2?family=Montserrat:wght@300;400;500;600;700&display=swap');
body {
font-family: 'Montserrat', sans-serif;
background-color: #121212;
color: white;
}
.sidebar {
scrollbar-width: thin;
scrollbar-color: #535353 transparent;
}
.sidebar::-webkit-scrollbar {
width: 8px;
}
.sidebar::-webkit-scrollbar-thumb {
background-color: #535353;
border-radius: 4px;
}
.progress-bar {
-webkit-appearance: none;
height: 4px;
background: #535353;
border-radius: 2px;
}
.progress-bar::-webkit-slider-thumb {
-webkit-appearance: none;
width: 12px;
height: 12px;
background: white;
border-radius: 50%;
cursor: pointer;
opacity: 0;
transition: opacity 0.2s;
}
.progress-bar:hover::-webkit-slider-thumb {
opacity: 1;
}
.album-art:hover .play-button {
opacity: 1;
transform: translateY(0);
}
.play-button {
opacity: 0;
transform: translateY(10px);
transition: all 0.3s ease;
}
.song-row:hover {
background-color: #282828;
}
.search-results {
max-height: 400px;
overflow-y: auto;
scrollbar-width: thin;
scrollbar-color: #535353 transparent;
}
.search-results::-webkit-scrollbar {
width: 8px;
}
.search-results::-webkit-scrollbar-thumb {
background-color: #535353;
border-radius: 4px;
}
.blinking {
animation: blink 1.5s infinite;
}
@keyframes blink {
0% { opacity: 1; }
50% { opacity: 0.5; }
100% { opacity: 1; }
}
.wave-animation {
display: flex;
align-items: center;
justify-content: space-between;
width: 30px;
height: 20px;
}
.wave-bar {
width: 3px;
background-color: #1db954;
border-radius: 3px;
animation: wave 1.5s ease-in-out infinite;
}
.wave-bar:nth-child(1) { height: 60%; animation-delay: 0.1s; }
.wave-bar:nth-child(2) { height: 30%; animation-delay: 0.3s; }
.wave-bar:nth-child(3) { height: 75%; animation-delay: 0.5s; }
.wave-bar:nth-child(4) { height: 40%; animation-delay: 0.7s; }
.wave-bar:nth-child(5) { height: 60%; animation-delay: 0.9s; }
@keyframes wave {
0%, 100% { transform: scaleY(1); }
50% { transform: scaleY(1.5); }
}
</style>
</head>
<body class="h-screen flex overflow-hidden">
<!-- Sidebar -->
<div class="sidebar w-60 bg-black flex flex-col overflow-y-auto">
<div class="p-6">
<div class="flex items-center mb-8">
<i class="fas fa-music text-3xl text-green-500 mr-2"></i>
<span class="text-xl font-bold">JioSaavn</span>
</div>
<div class="mb-8">
<div class="mb-4">
<a href="#" class="flex items-center text-white hover:text-green-500 transition" id="home-link">
<i class="fas fa-home text-xl mr-4"></i>
<span class="font-medium">Home</span>
</a>
</div>
<div class="mb-4">
<a href="#" class="flex items-center text-gray-400 hover:text-white transition" id="search-link">
<i class="fas fa-search text-xl mr-4"></i>
<span class="font-medium">Search</span>
</a>
</div>
<div class="mb-4">
<a href="#" class="flex items-center text-gray-400 hover:text-white transition" id="library-link">
<i class="fas fa-book text-xl mr-4"></i>
<span class="font-medium">Your Library</span>
</a>
</div>
</div>
<div class="mb-8">
<div class="mb-4">
<a href="#" class="flex items-center text-gray-400 hover:text-white transition" id="create-playlist">
<i class="fas fa-plus-square text-xl mr-4"></i>
<span class="font-medium">Create Playlist</span>
</a>
</div>
<div class="mb-4">
<a href="#" class="flex items-center text-gray-400 hover:text-white transition" id="liked-songs">
<i class="fas fa-heart text-xl mr-4"></i>
<span class="font-medium">Liked Songs</span>
</a>
</div>
</div>
<div class="border-t border-gray-800 pt-4">
<div class="text-gray-400 text-sm mb-2">PLAYLISTS</div>
<div id="playlists-container">
<!-- Playlists will be loaded here -->
<div class="mb-2">
<a href="#" class="text-gray-400 hover:text-white transition block truncate playlist-link" data-id="8291463">Top Hindi Hits</a>
</div>
<div class="mb-2">
<a href="#" class="text-gray-400 hover:text-white transition block truncate playlist-link" data-id="106114462">Romantic Hits</a>
</div>
<div class="mb-2">
<a href="#" class="text-gray-400 hover:text-white transition block truncate playlist-link" data-id="103581706">Bollywood Dance</a>
</div>
</div>
</div>
</div>
</div>
<!-- Main Content -->
<div class="flex-1 flex flex-col overflow-hidden">
<!-- Header -->
<div class="bg-gradient-to-r from-purple-900 to-blue-900 p-6" id="main-header">
<div class="flex justify-between items-center mb-6">
<div class="flex space-x-4">
<button class="bg-black bg-opacity-30 rounded-full w-8 h-8 flex items-center justify-center" id="nav-back">
<i class="fas fa-chevron-left"></i>
</button>
<button class="bg-black bg-opacity-30 rounded-full w-8 h-8 flex items-center justify-center" id="nav-forward">
<i class="fas fa-chevron-right"></i>
</button>
</div>
<div class="flex items-center space-x-4">
<button class="bg-white text-black px-4 py-1 rounded-full font-bold text-sm hover:scale-105 transition">
Upgrade
</button>
<div class="flex items-center bg-black bg-opacity-70 rounded-full px-2 py-1 cursor-pointer hover:bg-opacity-90 transition">
<div class="w-6 h-6 rounded-full bg-purple-500 mr-2"></div>
<span class="text-sm font-medium">Profile</span>
<i class="fas fa-chevron-down ml-2 text-xs"></i>
</div>
</div>
</div>
<h1 class="text-5xl font-bold mb-6" id="greeting">Good afternoon</h1>
<div class="grid grid-cols-2 md:grid-cols-3 gap-4" id="quick-access">
<!-- Quick access items will be loaded here -->
<div class="bg-gray-800 bg-opacity-40 rounded flex items-center overflow-hidden hover:bg-gray-700 transition cursor-pointer">
<img src="https://c.saavncdn.com/editorial/JustHits-hindi_20240208054618.jpg" alt="Album" class="w-16 h-16">
<span class="ml-4 font-medium">Today's Top Hits</span>
</div>
<div class="bg-gray-800 bg-opacity-40 rounded flex items-center overflow-hidden hover:bg-gray-700 transition cursor-pointer">
<img src="https://c.saavncdn.com/editorial/BollywoodDanceMusic_20240208054639.jpg" alt="Album" class="w-16 h-16">
<span class="ml-4 font-medium">Bollywood Dance</span>
</div>
<div class="bg-gray-800 bg-opacity-40 rounded flex items-center overflow-hidden hover:bg-gray-700 transition cursor-pointer">
<img src="https://c.saavncdn.com/editorial/NewRomanticHindi_20240208054618.jpg" alt="Album" class="w-16 h-16">
<span class="ml-4 font-medium">Romantic Hits</span>
</div>
</div>
</div>
<!-- Search Section (hidden by default) -->
<div class="hidden p-6 bg-gradient-to-b from-blue-900 to-gray-900" id="search-section">
<div class="relative mb-6">
<i class="fas fa-search absolute left-3 top-3 text-gray-400"></i>
<input type="text" id="search-input" class="w-full bg-gray-700 rounded-full py-2 pl-10 pr-4 text-white placeholder-gray-400 focus:outline-none focus:ring-2 focus:ring-green-500" placeholder="Search for songs, artists, or albums">
</div>
<div class="search-results hidden bg-gray-800 bg-opacity-40 rounded-lg p-4 mb-6" id="search-results">
<!-- Search results will be displayed here -->
</div>
<div class="flex justify-between items-center mb-6">
<h2 class="text-2xl font-bold">Browse all</h2>
</div>
<div class="grid grid-cols-2 md:grid-cols-3 lg:grid-cols-5 gap-6" id="browse-categories">
<!-- Browse categories will be loaded here -->
<div class="bg-gradient-to-br from-purple-600 to-blue-600 rounded-lg p-4 cursor-pointer hover:opacity-90 transition">
<h3 class="font-bold">Hindi</h3>
</div>
<div class="bg-gradient-to-br from-green-600 to-blue-600 rounded-lg p-4 cursor-pointer hover:opacity-90 transition">
<h3 class="font-bold">Punjabi</h3>
</div>
<div class="bg-gradient-to-br from-red-600 to-yellow-600 rounded-lg p-4 cursor-pointer hover:opacity-90 transition">
<h3 class="font-bold">Pop</h3>
</div>
<div class="bg-gradient-to-br from-yellow-600 to-red-600 rounded-lg p-4 cursor-pointer hover:opacity-90 transition">
<h3 class="font-bold">Romantic</h3>
</div>
<div class="bg-gradient-to-br from-blue-600 to-purple-600 rounded-lg p-4 cursor-pointer hover:opacity-90 transition">
<h3 class="font-bold">Dance</h3>
</div>
</div>
</div>
<!-- Content -->
<div class="flex-1 overflow-y-auto p-6 bg-gradient-to-b from-blue-900 to-gray-900" id="main-content">
<div class="flex justify-between items-center mb-6">
<h2 class="text-2xl font-bold">Made For You</h2>
<a href="#" class="text-sm text-gray-400 hover:underline">Show all</a>
</div>
<div class="grid grid-cols-2 md:grid-cols-3 lg:grid-cols-5 gap-6 mb-8" id="featured-playlists">
<!-- Featured playlists will be loaded here -->
<div class="group">
<div class="album-art relative mb-3">
<img src="https://c.saavncdn.com/editorial/JustHits-hindi_20240208054618.jpg" alt="Album" class="w-full rounded shadow-lg">
<button class="play-button absolute bottom-2 right-2 bg-green-500 rounded-full w-12 h-12 flex items-center justify-center shadow-lg group-hover:opacity-100 group-hover:transform group-hover:translate-y-0">
<i class="fas fa-play text-xl"></i>
</button>
</div>
<h3 class="font-medium text-white">Today's Top Hits</h3>
<p class="text-sm text-gray-400">The most played tracks right now</p>
</div>
</div>
<div class="flex justify-between items-center mb-6">
<h2 class="text-2xl font-bold">Recently played</h2>
<a href="#" class="text-sm text-gray-400 hover:underline">Show all</a>
</div>
<div class="bg-gray-800 bg-opacity-40 rounded-lg overflow-hidden" id="recently-played">
<table class="w-full">
<thead>
<tr class="border-b border-gray-700 text-gray-400 text-left">
<th class="p-4 w-12">#</th>
<th class="p-4">TITLE</th>
<th class="p-4">ALBUM</th>
<th class="p-4 text-right">DURATION</th>
</tr>
</thead>
<tbody id="songs-table">
<!-- Songs will be loaded here -->
</tbody>
</table>
</div>
</div>
<!-- Playlist View (hidden by default) -->
<div class="hidden flex-1 overflow-y-auto p-6 bg-gradient-to-b from-blue-900 to-gray-900" id="playlist-view">
<div class="flex items-end mb-8">
<img src="" alt="Playlist" class="w-48 h-48 shadow-2xl mr-6" id="playlist-image">
<div>
<p class="text-sm font-bold mb-2">PLAYLIST</p>
<h1 class="text-5xl font-bold mb-4" id="playlist-title">Playlist Title</h1>
<p class="text-gray-400 mb-2" id="playlist-description"></p>
<div class="flex items-center text-sm">
<span class="font-bold" id="playlist-owner">JioSaavn</span>
<span class="mx-1"></span>
<span id="playlist-song-count">0 songs</span>
</div>
</div>
</div>
<div class="mb-6">
<button class="bg-green-500 hover:bg-green-600 text-white rounded-full px-6 py-2 font-bold mr-4 transition" id="play-playlist">
<i class="fas fa-play mr-2"></i> Play
</button>
<button class="text-gray-400 hover:text-white">
<i class="far fa-heart text-xl"></i>
</button>
</div>
<div class="bg-gray-800 bg-opacity-40 rounded-lg overflow-hidden">
<table class="w-full">
<thead>
<tr class="border-b border-gray-700 text-gray-400 text-left">
<th class="p-4 w-12">#</th>
<th class="p-4">TITLE</th>
<th class="p-4">ALBUM</th>
<th class="p-4 text-right">DURATION</th>
</tr>
</thead>
<tbody id="playlist-songs">
<!-- Playlist songs will be loaded here -->
</tbody>
</table>
</div>
</div>
</div>
<!-- Player -->
<div class="fixed bottom-0 left-0 right-0 bg-gray-900 border-t border-gray-800 h-20 flex items-center px-4">
<div class="w-1/4 flex items-center">
<img src="" alt="Album" class="w-14 h-14 mr-3" id="player-album-art">
<div>
<div class="text-sm font-medium truncate max-w-xs" id="player-song-title">No song selected</div>
<div class="text-xs text-gray-400 truncate max-w-xs" id="player-song-artist">-</div>
</div>
<button class="ml-4 text-gray-400 hover:text-white" id="like-song">
<i class="far fa-heart"></i>
</button>
</div>
<div class="w-2/4 flex flex-col items-center">
<div class="flex items-center mb-2">
<button class="mx-2 text-gray-400 hover:text-white" id="shuffle">
<i class="fas fa-random"></i>
</button>
<button class="mx-2 text-gray-400 hover:text-white" id="prev-song">
<i class="fas fa-step-backward"></i>
</button>
<button class="mx-3 bg-white rounded-full w-8 h-8 flex items-center justify-center hover:scale-105 transition" id="play-pause">
<i class="fas fa-play text-black" id="play-pause-icon"></i>
</button>
<button class="mx-2 text-gray-400 hover:text-white" id="next-song">
<i class="fas fa-step-forward"></i>
</button>
<button class="mx-2 text-gray-400 hover:text-white" id="repeat">
<i class="fas fa-redo"></i>
</button>
</div>
<div class="w-full flex items-center">
<span class="text-xs text-gray-400 mr-2" id="current-time">0:00</span>
<input type="range" class="progress-bar flex-1" min="0" max="100" value="0" id="progress-bar">
<span class="text-xs text-gray-400 ml-2" id="duration">0:00</span>
</div>
</div>
<div class="w-1/4 flex justify-end items-center">
<button class="mx-2 text-gray-400 hover:text-white" id="queue">
<i class="fas fa-list"></i>
</button>
<button class="mx-2 text-gray-400 hover:text-white">
<i class="fas fa-laptop"></i>
</button>
<button class="mx-2 text-gray-400 hover:text-white">
<i class="fas fa-volume-up"></i>
</button>
<input type="range" class="w-20 progress-bar" min="0" max="100" value="70" id="volume-control">
</div>
<!-- Audio element -->
<audio id="audio-player"></audio>
</div>
<script>
// Global variables
let currentAudio = null;
let currentPlaylist = [];
let currentSongIndex = -1;
let isPlaying = false;
let isShuffleOn = false;
let isRepeatOn = false;
let searchTimeout = null;
// DOM elements
const audioPlayer = document.getElementById('audio-player');
const progressBar = document.getElementById('progress-bar');
const currentTimeDisplay = document.getElementById('current-time');
const durationDisplay = document.getElementById('duration');
const playPauseButton = document.getElementById('play-pause');
const playPauseIcon = document.getElementById('play-pause-icon');
const prevSongButton = document.getElementById('prev-song');
const nextSongButton = document.getElementById('next-song');
const shuffleButton = document.getElementById('shuffle');
const repeatButton = document.getElementById('repeat');
const playerSongTitle = document.getElementById('player-song-title');
const playerSongArtist = document.getElementById('player-song-artist');
const playerAlbumArt = document.getElementById('player-album-art');
// Navigation elements
const homeLink = document.getElementById('home-link');
const searchLink = document.getElementById('search-link');
const libraryLink = document.getElementById('library-link');
const mainHeader = document.getElementById('main-header');
const searchSection = document.getElementById('search-section');
const mainContent = document.getElementById('main-content');
const playlistView = document.getElementById('playlist-view');
const searchInput = document.getElementById('search-input');
const searchResults = document.getElementById('search-results');
const playlistLinks = document.querySelectorAll('.playlist-link');
// Initialize the app
document.addEventListener('DOMContentLoaded', function() {
// Set greeting based on time of day
setGreeting();
// Load featured content
loadFeaturedContent();
// Load recently played (mock data)
loadRecentlyPlayed();
// Event listeners for player controls
playPauseButton.addEventListener('click', togglePlayPause);
prevSongButton.addEventListener('click', playPreviousSong);
nextSongButton.addEventListener('click', playNextSong);
shuffleButton.addEventListener('click', toggleShuffle);
repeatButton.addEventListener('click', toggleRepeat);
progressBar.addEventListener('input', seekAudio);
audioPlayer.addEventListener('timeupdate', updateProgressBar);
audioPlayer.addEventListener('ended', handleSongEnded);
audioPlayer.addEventListener('loadedmetadata', updateDurationDisplay);
// Navigation event listeners
homeLink.addEventListener('click', (e) => {
e.preventDefault();
showMainContent();
});
searchLink.addEventListener('click', (e) => {
e.preventDefault();
showSearchSection();
});
libraryLink.addEventListener('click', (e) => {
e.preventDefault();
showMainContent();
});
// Search functionality
searchInput.addEventListener('input', handleSearchInput);
// Playlist links
playlistLinks.forEach(link => {
link.addEventListener('click', (e) => {
e.preventDefault();
const playlistId = link.getAttribute('data-id');
loadPlaylist(playlistId);
});
});
// Quick access items
document.querySelectorAll('#quick-access > div').forEach(item => {
item.addEventListener('click', () => {
// For demo purposes, we'll just show a playlist
loadPlaylist('8291463'); // Top Hindi Hits
});
});
// Browse categories
document.querySelectorAll('#browse-categories > div').forEach(item => {
item.addEventListener('click', () => {
const category = item.querySelector('h3').textContent;
// For demo purposes, we'll just show a playlist based on category
if (category === 'Hindi') loadPlaylist('8291463');
else if (category === 'Punjabi') loadPlaylist('1268420');
else if (category === 'Pop') loadPlaylist('1268420');
else if (category === 'Romantic') loadPlaylist('106114462');
else if (category === 'Dance') loadPlaylist('103581706');
});
});
});
// Functions
function setGreeting() {
const hour = new Date().getHours();
let greeting = '';
if (hour < 12) greeting = 'Good morning';
else if (hour < 18) greeting = 'Good afternoon';
else greeting = 'Good evening';
document.getElementById('greeting').textContent = greeting;
}
function showMainContent() {
mainHeader.classList.remove('hidden');
searchSection.classList.add('hidden');
mainContent.classList.remove('hidden');
playlistView.classList.add('hidden');
}
function showSearchSection() {
mainHeader.classList.add('hidden');
searchSection.classList.remove('hidden');
mainContent.classList.add('hidden');
playlistView.classList.add('hidden');
searchInput.focus();
}
function showPlaylistView() {
mainHeader.classList.add('hidden');
searchSection.classList.add('hidden');
mainContent.classList.add('hidden');
playlistView.classList.remove('hidden');
}
function handleSearchInput() {
clearTimeout(searchTimeout);
const query = searchInput.value.trim();
if (query.length < 2) {
searchResults.classList.add('hidden');
return;
}
searchResults.innerHTML = '<div class="text-center py-4"><i class="fas fa-spinner fa-spin mr-2"></i>Searching...</div>';
searchResults.classList.remove('hidden');
searchTimeout = setTimeout(() => {
searchJioSaavn(query);
}, 500);
}
function searchJioSaavn(query) {
// Use JioSaavn API for search
fetch(`https://saavn.me/search/songs?query=${encodeURIComponent(query)}&page=1&limit=10`)
.then(response => response.json())
.then(data => {
displaySearchResults(data.data.results);
})
.catch(error => {
console.error('Error searching:', error);
searchResults.innerHTML = '<div class="text-center py-4 text-red-500">Error loading search results</div>';
});
}
function displaySearchResults(results) {
if (!results || results.length === 0) {
searchResults.innerHTML = '<div class="text-center py-4">No results found</div>';
return;
}
let html = '<div class="space-y-2">';
results.forEach((song, index) => {
html += `
<div class="flex items-center p-2 hover:bg-gray-700 rounded cursor-pointer search-result" data-id="${song.id}">
<img src="${song.image[1].link}" alt="${song.name}" class="w-10 h-10 mr-3">
<div class="flex-1">
<div class="font-medium truncate">${song.name}</div>
<div class="text-sm text-gray-400 truncate">${song.primaryArtists}</div>
</div>
<div class="text-sm text-gray-400">${formatDuration(song.duration)}</div>
</div>
`;
});
html += '</div>';
searchResults.innerHTML = html;
// Add click event to search results
document.querySelectorAll('.search-result').forEach(item => {
item.addEventListener('click', () => {
const songId = item.getAttribute('data-id');
playSongById(songId);
});
});
}
function loadFeaturedContent() {
// Use JioSaavn API to get featured playlists
fetch('https://saavn.me/modules?language=hindi,english')
.then(response => response.json())
.then(data => {
displayFeaturedPlaylists(data.data.trending.playlists);
})
.catch(error => {
console.error('Error loading featured content:', error);
});
}
function displayFeaturedPlaylists(playlists) {
const container = document.getElementById('featured-playlists');
let html = '';
// Limit to 5 playlists for demo
playlists.slice(0, 5).forEach(playlist => {
html += `
<div class="group">
<div class="album-art relative mb-3 cursor-pointer" data-id="${playlist.id}">
<img src="${playlist.image}" alt="${playlist.title}" class="w-full rounded shadow-lg">
<button class="play-button absolute bottom-2 right-2 bg-green-500 rounded-full w-12 h-12 flex items-center justify-center shadow-lg group-hover:opacity-100 group-hover:transform group-hover:translate-y-0">
<i class="fas fa-play text-xl"></i>
</button>
</div>
<h3 class="font-medium text-white">${playlist.title}</h3>
<p class="text-sm text-gray-400">${playlist.subtitle || 'Curated playlist'}</p>
</div>
`;
});
container.innerHTML = html;
// Add click event to playlist items
document.querySelectorAll('.album-art').forEach(item => {
item.addEventListener('click', () => {
const playlistId = item.getAttribute('data-id');
loadPlaylist(playlistId);
});
});
}
function loadRecentlyPlayed() {
// Mock data for recently played
const songs = [
{
id: '1',
title: 'Tum Hi Ho',
artist: 'Arijit Singh',
album: 'Aashiqui 2',
duration: '4:22',
image: 'https://c.saavncdn.com/227/Aashiqui-2-Hindi-2013-20230905173600-500x500.jpg'
},
{
id: '2',
title: 'Kesariya',
artist: 'Arijit Singh',
album: 'Brahmāstra',
duration: '4:28',
image: 'https://c.saavncdn.com/191/Kesariya-From-Brahmastra-Hindi-2022-20220717092820-500x500.jpg'
},
{
id: '3',
title: 'Apna Bana Le',
artist: 'Arijit Singh',
album: 'Bhediya',
duration: '4:21',
image: 'https://c.saavncdn.com/391/Apna-Bana-Le-From-Bhediya-Hindi-2022-20221018112233-500x500.jpg'
}
];
const container = document.getElementById('songs-table');
let html = '';
songs.forEach((song, index) => {
html += `
<tr class="song-row border-b border-gray-700 hover:bg-gray-700 cursor-pointer" data-id="${song.id}">
<td class="p-4 text-gray-400">${index + 1}</td>
<td class="p-4">
<div class="flex items-center">
<img src="${song.image}" alt="Album" class="w-10 h-10 mr-3">
<div>
<div class="font-medium">${song.title}</div>
<div class="text-sm text-gray-400">${song.artist}</div>
</div>
</div>
</td>
<td class="p-4 text-gray-400">${song.album}</td>
<td class="p-4 text-right text-gray-400">${song.duration}</td>
</tr>
`;
});
container.innerHTML = html;
// Add click event to song rows
document.querySelectorAll('.song-row').forEach(row => {
row.addEventListener('click', () => {
const songId = row.getAttribute('data-id');
// For demo, we'll just play the first song
playSong(songs[0]);
});
});
}
function loadPlaylist(playlistId) {
showPlaylistView();
// Show loading state
document.getElementById('playlist-title').textContent = 'Loading...';
document.getElementById('playlist-image').src = '';
document.getElementById('playlist-description').textContent = '';
document.getElementById('playlist-owner').textContent = '';
document.getElementById('playlist-song-count').textContent = 'Loading songs...';
document.getElementById('playlist-songs').innerHTML = '<tr><td colspan="4" class="text-center py-4"><i class="fas fa-spinner fa-spin mr-2"></i>Loading playlist...</td></tr>';
// Fetch playlist details from JioSaavn API
fetch(`https://saavn.me/playlists?id=${playlistId}`)
.then(response => response.json())
.then(data => {
const playlist = data.data;
displayPlaylist(playlist);
// Store playlist songs for playback
currentPlaylist = playlist.songs;
})
.catch(error => {
console.error('Error loading playlist:', error);
document.getElementById('playlist-title').textContent = 'Error loading playlist';
document.getElementById('playlist-songs').innerHTML = '<tr><td colspan="4" class="text-center py-4 text-red-500">Error loading playlist</td></tr>';
});
}
function displayPlaylist(playlist) {
document.getElementById('playlist-title').textContent = playlist.name;
document.getElementById('playlist-image').src = playlist.image[1].link;
document.getElementById('playlist-description').textContent = playlist.description || 'Curated playlist';
document.getElementById('playlist-owner').textContent = playlist.artistName || 'JioSaavn';
document.getElementById('playlist-song-count').textContent = `${playlist.songCount} songs`;
const container = document.getElementById('playlist-songs');
let html = '';
playlist.songs.forEach((song, index) => {
html += `
<tr class="song-row border-b border-gray-700 hover:bg-gray-700 cursor-pointer" data-id="${song.id}">
<td class="p-4 text-gray-400">${index + 1}</td>
<td class="p-4">
<div class="flex items-center">
<img src="${song.image[1].link}" alt="Album" class="w-10 h-10 mr-3">
<div>
<div class="font-medium">${song.name}</div>
<div class="text-sm text-gray-400">${song.primaryArtists}</div>
</div>
</div>
</td>
<td class="p-4 text-gray-400">${song.album.name}</td>
<td class="p-4 text-right text-gray-400">${formatDuration(song.duration)}</td>
</tr>
`;
});
container.innerHTML = html;
// Add click event to playlist song rows
document.querySelectorAll('#playlist-songs .song-row').forEach((row, index) => {
row.addEventListener('click', () => {
playSongFromPlaylist(index);
});
});
}
function playSongFromPlaylist(index) {
if (!currentPlaylist || index < 0 || index >= currentPlaylist.length) return;
currentSongIndex = index;
const song = currentPlaylist[index];
playSong(song);
}
function playSongById(songId) {
// Fetch song details from JioSaavn API
fetch(`https://saavn.me/songs?id=${songId}`)
.then(response => response.json())
.then(data => {
const song = data.data[0];
playSong(song);
})
.catch(error => {
console.error('Error loading song:', error);
});
}
function playSong(song) {
// Stop current audio if playing
if (currentAudio) {
currentAudio.pause();
currentAudio = null;
}
// Update player UI
playerSongTitle.textContent = song.name || song.title;
playerSongArtist.textContent = song.primaryArtists || song.artist;
playerAlbumArt.src = song.image[1]?.link || song.image || '';
// Get download URL for the song
fetch(`https://saavn.me/songs?id=${song.id}`)
.then(response => response.json())
.then(data => {
const downloadUrl = data.data[0].downloadUrl[4]?.link;
if (downloadUrl) {
audioPlayer.src = downloadUrl;
audioPlayer.play()
.then(() => {
isPlaying = true;
playPauseIcon.classList.remove('fa-play');
playPauseIcon.classList.add('fa-pause');
// Update duration display
updateDurationDisplay();
})
.catch(error => {
console.error('Error playing song:', error);
});
}
})
.catch(error => {
console.error('Error getting song URL:', error);
});
}
function togglePlayPause() {
if (!audioPlayer.src) {
// If no song is selected, play the first song from current playlist
if (currentPlaylist && currentPlaylist.length > 0) {
playSongFromPlaylist(0);
}
return;
}
if (isPlaying) {
audioPlayer.pause();
playPauseIcon.classList.remove('fa-pause');
playPauseIcon.classList.add('fa-play');
} else {
audioPlayer.play()
.then(() => {
playPauseIcon.classList.remove('fa-play');
playPauseIcon.classList.add('fa-pause');
})
.catch(error => {
console.error('Error playing:', error);
});
}
isPlaying = !isPlaying;
}
function playPreviousSong() {
if (!currentPlaylist || currentPlaylist.length === 0) return;
if (isShuffleOn) {
currentSongIndex = Math.floor(Math.random() * currentPlaylist.length);
} else {
currentSongIndex = (currentSongIndex - 1 + currentPlaylist.length) % currentPlaylist.length;
}
playSongFromPlaylist(currentSongIndex);
}
function playNextSong() {
if (!currentPlaylist || currentPlaylist.length === 0) return;
if (isShuffleOn) {
currentSongIndex = Math.floor(Math.random() * currentPlaylist.length);
} else {
currentSongIndex = (currentSongIndex + 1) % currentPlaylist.length;
}
playSongFromPlaylist(currentSongIndex);
}
function handleSongEnded() {
if (isRepeatOn) {
audioPlayer.currentTime = 0;
audioPlayer.play();
} else {
playNextSong();
}
}
function toggleShuffle() {
isShuffleOn = !isShuffleOn;
shuffleButton.classList.toggle('text-green-500', isShuffleOn);
shuffleButton.classList.toggle('text-gray-400', !isShuffleOn);
}
function toggleRepeat() {
isRepeatOn = !isRepeatOn;
repeatButton.classList.toggle('text-green-500', isRepeatOn);
repeatButton.classList.toggle('text-gray-400', !isRepeatOn);
}
function seekAudio() {
if (audioPlayer.duration) {
const seekTime = (progressBar.value / 100) * audioPlayer.duration;
audioPlayer.currentTime = seekTime;
}
}
function updateProgressBar() {
if (audioPlayer.duration) {
const progress = (audioPlayer.currentTime / audioPlayer.duration) * 100;
progressBar.value = progress;
// Update current time display
currentTimeDisplay.textContent = formatTime(audioPlayer.currentTime);
}
}
function updateDurationDisplay() {
if (audioPlayer.duration) {
durationDisplay.textContent = formatTime(audioPlayer.duration);
}
}
function formatTime(seconds) {
const mins = Math.floor(seconds / 60);
const secs = Math.floor(seconds % 60);
return `${mins}:${secs < 10 ? '0' : ''}${secs}`;
}
function formatDuration(durationInSeconds) {
const mins = Math.floor(durationInSeconds / 60);
const secs = durationInSeconds % 60;
return `${mins}:${secs < 10 ? '0' : ''}${secs}`;
}
</script>
<p style="border-radius: 8px; text-align: center; font-size: 12px; color: #fff; margin-top: 16px;position: fixed; left: 8px; bottom: 8px; z-index: 10; background: rgba(0, 0, 0, 0.8); padding: 4px 8px;">Made with <img src="https://enzostvs-deepsite.hf.space/logo.svg" alt="DeepSite Logo" style="width: 16px; height: 16px; vertical-align: middle;display:inline-block;margin-right:3px;filter:brightness(0) invert(1);"><a href="https://enzostvs-deepsite.hf.space" style="color: #fff;text-decoration: underline;" target="_blank" >DeepSite</a> - 🧬 <a href="https://enzostvs-deepsite.hf.space?remix=Enoughking/music" style="color: #fff;text-decoration: underline;" target="_blank" >Remix</a></p></body>
</html>