generate random track descriptions via an animated dice button, with suggestions taken from using Deepseeks API
edb69f0
verified
| <html lang="en"> | |
| <head> | |
| <meta charset="UTF-8"> | |
| <meta name="viewport" content="width=device-width, initial-scale=1.0"> | |
| <title>Track Generator - Algorithmic Harmony Maestro</title> | |
| <link rel="icon" type="image/x-icon" href="/static/favicon.ico"> | |
| <link rel="stylesheet" href="style.css"> | |
| <script src="https://cdn.tailwindcss.com"></script> | |
| <script src="https://cdn.jsdelivr.net/npm/feather-icons/dist/feather.min.js"></script> | |
| <script src="https://unpkg.com/feather-icons"></script> | |
| </head> | |
| <body class="bg-gradient-to-br from-purple-900 via-blue-900 to-indigo-900 min-h-screen"> | |
| <custom-navbar></custom-navbar> | |
| <main class="container mx-auto px-4 py-8 pt-20"> | |
| <div class="max-w-4xl mx-auto"> | |
| <h1 class="text-4xl md:text-5xl font-bold text-white text-center mb-8"> | |
| AI Music Generator | |
| </h1> | |
| <p class="text-gray-300 text-center mb-12"> | |
| Describe your musical vision and let AI create an algorithm-optimized masterpiece | |
| </p> | |
| <!-- Prompt Input Section --> | |
| <div class="glass rounded-2xl p-8 mb-8"> | |
| <div class="flex items-center justify-between mb-6"> | |
| <h2 class="text-2xl font-semibold text-white">Enter Your Music Prompt</h2> | |
| <div class="flex gap-2"> | |
| <button id="dice-btn" class="bg-purple-600 hover:bg-purple-700 p-3 rounded-full transition-all"> | |
| <i data-feather="dice" class="text-white"></i> | |
| </button> | |
| <button id="voice-btn" class="bg-purple-600 hover:bg-purple-700 p-3 rounded-full transition-all"> | |
| <i data-feather="mic" class="text-white"></i> | |
| </button> | |
| </div> | |
| </div> | |
| <div class="space-y-6"> | |
| <div> | |
| <label class="block text-gray-300 mb-2">Describe your track:</label> | |
| <textarea | |
| id="music-prompt" | |
| placeholder="e.g., 'Upbeat 115 BPM house track with soulful vocals, optimized for workout playlists'" | |
| class="w-full h-32 bg-gray-800/50 border border-gray-700 rounded-lg p-4 text-white resize-none focus:outline-none focus:ring-2 focus:ring-purple-500" | |
| ></textarea> | |
| </div> | |
| <!-- Quick Templates --> | |
| <div> | |
| <label class="block text-gray-300 mb-2">Quick Templates:</label> | |
| <div class="grid grid-cols-1 md:grid-cols-2 gap-4"> | |
| <button class="template-btn bg-gray-800/50 hover:bg-gray-700/50 border border-gray-700 rounded-lg p-4 text-left text-white transition-all"> | |
| <div class="font-semibold">Workout Energy</div> | |
| <div class="text-sm text-gray-400">High BPM, driving beat, motivational</button> | |
| <button class="template-btn bg-gray-800/50 hover:bg-gray-700/50 border border-gray-700 rounded-lg p-4 text-left text-white transition-all"> | |
| <div class="font-semibold">Chill Focus</div> | |
| <div class="text-sm text-gray-400">Ambient, lo-fi, study-friendly</button> | |
| <button class="template-btn bg-gray-800/50 hover:bg-gray-700/50 border border-gray-700 rounded-lg p-4 text-left text-white transition-all"> | |
| <div class="font-semibold">Emotional Ballad</div> | |
| <div class="text-sm text-gray-400">Slow tempo, emotional vocals, cinematic</button> | |
| <button class="template-btn bg-gray-800/50 hover:bg-gray-700/50 border border-gray-700 rounded-lg p-4 text-left text-white transition-all"> | |
| <div class="font-semibold">Party Anthem</div> | |
| <div class="text-sm text-gray-400">Catchy hooks, danceable, festival-ready</button> | |
| </div> | |
| </div> | |
| <!-- Advanced Settings --> | |
| <div class="bg-gray-800/30 rounded-lg p-4"> | |
| <div class="flex items-center justify-between cursor-pointer" onclick="toggleAdvancedSettings()"> | |
| <span class="text-white font-semibold">Advanced Settings</span> | |
| <i data-feather="chevron-down" class="text-gray-400"></i> | |
| </div> | |
| <div id="advanced-settings" class="hidden space-y-4 mt-4"> | |
| <div class="grid grid-cols-2 gap-4"> | |
| <div> | |
| <label class="block text-gray-300 text-sm mb-1">BPM Range</label> | |
| <input type="range" min="60" max="200" value="120" class="w-full"> | |
| </div> | |
| <div> | |
| <label class="block text-gray-300 text-sm mb-1">Energy Level</label> | |
| <input type="range" min="1" max="10" value="7" class="w-full"> | |
| </div> | |
| </div> | |
| <div class="grid grid-cols-2 gap-4"> | |
| <div> | |
| <label class="block text-gray-300 text-sm mb-1">Duration (seconds)</label> | |
| <input type="number" value="180" class="w-full bg-gray-700/50 border border-gray-600 rounded px-3 py-2 text-white"> | |
| </div> | |
| <div> | |
| <label class="block text-gray-300 text-sm mb-1">Key</label> | |
| <select class="w-full bg-gray-700/50 border border-gray-600 rounded px-3 py-2 text-white"> | |
| <option>C Major</option> | |
| <option>A Minor</option> | |
| <option>G Major</option> | |
| <option>E Minor</option> | |
| </select> | |
| </div> | |
| </div> | |
| </div> | |
| </div> | |
| <button id="generate-btn" class="w-full bg-gradient-to-r from-purple-600 to-pink-600 hover:from-purple-700 hover:to-pink-700 text-white font-semibold py-4 rounded-lg transition-all transform hover:scale-105 pulse-glow"> | |
| <i data-feather="zap" class="inline mr-2"></i> | |
| Generate Track | |
| </button> | |
| </div> | |
| </div> | |
| <!-- Results Section --> | |
| <div id="results-section" class="hidden glass rounded-2xl p-8"> | |
| <h2 class="text-2xl font-semibold text-white mb-6">Generated Track</h2> | |
| <!-- Audio Player --> | |
| <div class="mb-6"> | |
| <div class="bg-gray-800/50 rounded-lg p-4"> | |
| <div class="flex items-center justify-between mb-4"> | |
| <div class="text-white font-semibold" id="track-title">Your Generated Track</div> | |
| <div class="text-gray-400 text-sm" id="track-duration">0:00 / 3:00</div> | |
| </div> | |
| <audio id="audio-player" controls class="w-full"> | |
| Your browser does not support the audio element. | |
| </audio> | |
| </div> | |
| <!-- Algorithm Analysis --> | |
| <div class="grid md:grid-cols-2 gap-6 mb-6"> | |
| <div class="bg-gray-800/30 rounded-lg p-4"> | |
| <h3 class="text-white font-semibold mb-3">Algorithm Compatibility</h3> | |
| <div class="space-y-3"> | |
| <div class="flex justify-between items-center"> | |
| <span class="text-gray-300">Spotify Fit</span> | |
| <span class="text-green-400 font-semibold" id="spotify-fit">84%</span> | |
| </div> | |
| <div class="flex justify-between items-center"> | |
| <span class="text-gray-300">SoundCloud Match</span> | |
| <span class="text-green-400 font-semibold" id="soundcloud-match">92%</span> | |
| </div> | |
| <div class="flex justify-between items-center"> | |
| <span class="text-gray-300">Skip Resistance</span> | |
| <span class="text-green-400 font-semibold" id="skip-resistance">88%</span> | |
| </div> | |
| </div> | |
| </div> | |
| <div class="bg-gray-800/30 rounded-lg p-4"> | |
| <h3 class="text-white font-semibold mb-3">Audio Features</h3> | |
| <div class="space-y-2"> | |
| <div class="text-sm text-gray-300">Loudness: -14.2 LUFS</div> | |
| <div class="text-sm text-gray-300">Tempo: 115 BPM</div> | |
| <div class="text-sm text-gray-300">Key: C Major</div> | |
| </div> | |
| </div> | |
| </div> | |
| <!-- Recommended Tags --> | |
| <div class="bg-gray-800/30 rounded-lg p-4"> | |
| <h3 class="text-white font-semibold mb-3">Optimized Metadata</h3> | |
| <div class="space-y-3"> | |
| <div> | |
| <label class="text-gray-300 text-sm">Title Suggestion:</label> | |
| <input type="text" value="Soulful House Workout" class="w-full bg-gray-700/50 border border-gray-600 rounded px-3 py-2 text-white"> | |
| </div> | |
| <div> | |
| <label class="text-gray-300 text-sm">Tags:</label> | |
| <div class="flex flex-wrap gap-2 mt-2"> | |
| <span class="bg-purple-600/50 text-white px-3 py-1 rounded-full text-sm"> | |
| house | |
| </span> | |
| <span class="bg-blue-600/50 text-white px-3 py-1 rounded-full text-sm"> | |
| workout | |
| </span> | |
| <span class="bg-pink-600/50 text-white px-3 py-1 rounded-full text-sm"> | |
| soulful | |
| </span> | |
| <span class="bg-indigo-600/50 text-white px-3 py-1 rounded-full text-sm"> | |
| electronic | |
| </span> | |
| </div> | |
| </div> | |
| </div> | |
| <!-- Action Buttons --> | |
| <div class="flex flex-col sm:flex-row gap-4 mt-6"> | |
| <button class="flex-1 bg-green-600 hover:bg-green-700 text-white py-3 rounded-lg font-semibold transition-all"> | |
| <i data-feather="upload" class="inline mr-2"></i> | |
| Upload to SoundCloud | |
| </button> | |
| <button class="flex-1 bg-blue-600 hover:bg-blue-700 text-white py-3 rounded-lg font-semibold transition-all"> | |
| <i data-feather="music" class="inline mr-2"></i> | |
| Submit to Spotify | |
| </button> | |
| <button class="flex-1 bg-gray-600 hover:bg-gray-700 text-white py-3 rounded-lg font-semibold transition-all"> | |
| <i data-feather="download" class="inline mr-2"></i> | |
| Download WAV | |
| </button> | |
| </div> | |
| </div> | |
| </div> | |
| </div> | |
| </main> | |
| <custom-footer></custom-footer> | |
| <script src="components/navbar.js"></script> | |
| <script src="components/footer.js"></script> | |
| <script src="script.js"></script> | |
| <script> | |
| feather.replace(); | |
| // Dice button for random prompts | |
| const diceBtn = document.getElementById('dice-btn'); | |
| const voiceBtn = document.getElementById('voice-btn'); | |
| const promptTextarea = document.getElementById('music-prompt'); | |
| const voiceRecognition = new VoiceRecognition(); | |
| diceBtn.addEventListener('click', async function() { | |
| // Add rotation animation | |
| diceBtn.classList.add('animate-spin'); | |
| try { | |
| const response = await fetch('https://api.deepseek.com/v1/chat/completions', { | |
| method: 'POST', | |
| headers: { | |
| 'Content-Type': 'application/json', | |
| 'Authorization': 'Bearer YOUR_DEEPSEEK_API_KEY' // Replace with actual API key | |
| }, | |
| body: JSON.stringify({ | |
| model: 'deepseek-chat', | |
| messages: [ | |
| { | |
| role: 'user', | |
| content: 'Generate 5 creative and diverse music track descriptions for AI music generation. Include different genres, moods, and styles. Format as a JSON array of strings.' | |
| } | |
| ], | |
| max_tokens: 500, | |
| temperature: 0.8 | |
| }) | |
| }); | |
| if (!response.ok) { | |
| throw new Error('Failed to fetch random prompts'); | |
| } | |
| const data = await response.json(); | |
| const prompts = JSON.parse(data.choices[0].message.content); | |
| // Pick a random prompt from the generated ones | |
| const randomPrompt = prompts[Math.floor(Math.random() * prompts.length)]; | |
| promptTextarea.value = randomPrompt; | |
| // Remove animation after a delay | |
| setTimeout(() => { | |
| diceBtn.classList.remove('animate-spin'); | |
| }, 1000); | |
| } catch (error) { | |
| console.error('Error fetching random prompt:', error); | |
| // Fallback to predefined prompts if API fails | |
| const fallbackPrompts = [ | |
| "Melodic deep house track with ethereal female vocals, perfect for sunset drives and chill vibes", | |
| "Aggressive dubstep with heavy bass drops and glitch effects, optimized for festival crowds", | |
| "Lo-fi hip hop beat with vinyl crackle and smooth jazz samples, ideal for study sessions", | |
| "Upbeat pop anthem with catchy hooks and electronic elements, radio-ready production", | |
| "Cinematic orchestral piece with epic brass and string sections, suitable for film trailers" | |
| ]; | |
| const randomPrompt = fallbackPrompts[Math.floor(Math.random() * fallbackPrompts.length)]; | |
| promptTextarea.value = randomPrompt; | |
| diceBtn.classList.remove('animate-spin'); | |
| } | |
| }); | |
| voiceBtn.addEventListener('click', function() { | |
| if (voiceRecognition.isListening) { | |
| voiceRecognition.stopListening(); | |
| voiceBtn.innerHTML = '<i data-feather="mic" class="text-white"></i>'; | |
| feather.replace(); | |
| } else { | |
| voiceRecognition.startListening( | |
| (transcript) => { | |
| promptTextarea.value = transcript; | |
| voiceBtn.innerHTML = '<i data-feather="mic" class="text-white"></i>'; | |
| feather.replace(); | |
| }, | |
| (error) => { | |
| alert('Voice recognition error: ' + error); | |
| } | |
| ); | |
| voiceBtn.innerHTML = '<i data-feather="square" class="text-white"></i>'; | |
| feather.replace(); | |
| } | |
| }); | |
| // Template buttons | |
| document.querySelectorAll('.template-btn').forEach(btn => { | |
| btn.addEventListener('click', function() { | |
| const title = this.querySelector('.font-semibold').textContent; | |
| const description = this.querySelector('.text-sm').textContent; | |
| promptTextarea.value = `${title} - ${description}`; | |
| }); | |
| }); | |
| // Generate button | |
| document.getElementById('generate-btn').addEventListener('click', async function() { | |
| const prompt = promptTextarea.value.trim(); | |
| if (!prompt) { | |
| alert('Please enter a music prompt first!'); | |
| return; | |
| } | |
| // Show loading state | |
| this.innerHTML = '<i data-feather="loader" class="animate-spin inline mr-2"></i> Generating...'; | |
| feather.replace(); | |
| // Simulate generation process | |
| setTimeout(() => { | |
| document.getElementById('results-section').classList.remove('hidden'); | |
| this.innerHTML = '<i data-feather="zap" class="inline mr-2"></i> Generate Track'; | |
| feather.replace(); | |
| }, 3000); | |
| }); | |
| function toggleAdvancedSettings() { | |
| const settings = document.getElementById('advanced-settings'); | |
| const icon = settings.previousElementSibling.querySelector('i'); | |
| settings.classList.toggle('hidden'); | |
| if (settings.classList.contains('hidden')) { | |
| icon.setAttribute('data-feather', 'chevron-down'); | |
| } else { | |
| icon.setAttribute('data-feather', 'chevron-up'); | |
| } | |
| feather.replace(); | |
| } | |
| </script> | |
| </body> | |
| </html> |