chordgenius / index.html
tushkum's picture
when i type fasmous bollywood hindi song pal pal sung by great kishore kumar , then it must show lyrics, chords, capo position song details and transpose +- buttons but it's not showing in result , please fix this or add this feature for all language song and suggest youtube videos also like my youtube channel "GuitarGaani" - Follow Up Deployment
ef7a770 verified
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>ChordGenius - AI Guitar Assistant</title>
<script src="https://cdn.tailwindcss.com"></script>
<script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
<script src="https://cdn.jsdelivr.net/npm/[email protected]/RecordRTC.min.js"></script>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
<style>
.gradient-bg {
background: linear-gradient(135deg, #1e3a8a 0%, #1e40af 50%, #1d4ed8 100%);
}
.chord-highlight {
background-color: rgba(255, 255, 0, 0.3);
border-radius: 4px;
padding: 0 2px;
}
.teleprompter-text {
font-size: 2.5rem;
line-height: 1.5;
transition: transform 0.3s ease;
}
.waveform {
height: 100px;
background: linear-gradient(to right, #3b82f6, #1d4ed8);
border-radius: 8px;
}
@media (max-width: 768px) {
.teleprompter-text {
font-size: 1.8rem;
}
}
.recording-active {
animation: pulse 1.5s infinite;
}
@keyframes pulse {
0% { box-shadow: 0 0 0 0 rgba(239, 68, 68, 0.7); }
70% { box-shadow: 0 0 0 10px rgba(239, 68, 68, 0); }
100% { box-shadow: 0 0 0 0 rgba(239, 68, 68, 0); }
}
</style>
</head>
<body class="bg-gray-100 font-sans">
<div class="min-h-screen flex flex-col">
<!-- Header -->
<header class="gradient-bg text-white p-4 shadow-lg">
<div class="container mx-auto flex justify-between items-center">
<div class="flex items-center space-x-2">
<i class="fas fa-guitar text-3xl"></i>
<h1 class="text-2xl font-bold">ChordGenius</h1>
</div>
<nav class="hidden md:flex space-x-6">
<a href="#chord-finder" class="hover:text-blue-200 transition">Chord Finder</a>
<a href="#teleprompter" class="hover:text-blue-200 transition">Teleprompter</a>
<a href="#video-editor" class="hover:text-blue-200 transition">Video Editor</a>
</nav>
<button class="md:hidden text-2xl" id="mobile-menu-btn">
<i class="fas fa-bars"></i>
</button>
</div>
<!-- Mobile Menu -->
<div class="md:hidden hidden bg-blue-900 p-4" id="mobile-menu">
<div class="flex flex-col space-y-3">
<a href="#chord-finder" class="hover:text-blue-200 transition">Chord Finder</a>
<a href="#teleprompter" class="hover:text-blue-200 transition">Teleprompter</a>
<a href="#video-editor" class="hover:text-blue-200 transition">Video Editor</a>
</div>
</div>
</header>
<!-- Main Content -->
<main class="flex-grow container mx-auto p-4">
<!-- Chord Finder Section -->
<section id="chord-finder" class="mb-12 bg-white rounded-xl shadow-lg p-6">
<h2 class="text-2xl font-bold text-gray-800 mb-6 flex items-center">
<i class="fas fa-search mr-2 text-blue-600"></i> AI Chord Finder
</h2>
<div class="grid grid-cols-1 lg:grid-cols-2 gap-8">
<!-- Input Section -->
<div class="space-y-6">
<div>
<label class="block text-gray-700 mb-2 font-medium">Search by Song Name or Artist</label>
<div class="flex">
<input type="text" id="song-search" placeholder="e.g. 'Hotel California' or 'The Beatles'"
class="flex-grow p-3 border border-gray-300 rounded-l-lg focus:outline-none focus:ring-2 focus:ring-blue-500">
<button id="search-btn" class="bg-blue-600 text-white px-4 rounded-r-lg hover:bg-blue-700 transition">
<i class="fas fa-search"></i>
</button>
</div>
</div>
<div class="border-t pt-4">
<label class="block text-gray-700 mb-2 font-medium">Or Upload Audio File</label>
<div class="flex items-center space-x-4">
<label for="audio-upload" class="cursor-pointer bg-blue-100 text-blue-700 px-4 py-2 rounded-lg hover:bg-blue-200 transition flex items-center">
<i class="fas fa-upload mr-2"></i> Choose File
<input type="file" id="audio-upload" accept="audio/*" class="hidden">
</label>
<span id="file-name" class="text-gray-500">No file selected</span>
</div>
<div class="mt-4">
<button id="analyze-btn" class="bg-green-600 text-white px-4 py-2 rounded-lg hover:bg-green-700 transition flex items-center disabled:opacity-50" disabled>
<i class="fas fa-microphone-alt mr-2"></i> Analyze Audio
</button>
</div>
</div>
<div id="audio-visualizer" class="waveform hidden mt-4"></div>
<div id="ai-chat" class="mt-6 hidden">
<h3 class="text-lg font-semibold text-gray-700 mb-2">AI Chord Assistant</h3>
<div class="bg-gray-50 p-4 rounded-lg h-48 overflow-y-auto mb-2" id="chat-messages">
<div class="text-sm text-gray-600">AI: Hi! I can help you find chords for any song. Ask me anything about guitar chords!</div>
</div>
<div class="flex">
<input type="text" id="chat-input" placeholder="Ask about chords, capo positions..."
class="flex-grow p-2 border border-gray-300 rounded-l-lg focus:outline-none focus:ring-2 focus:ring-blue-500">
<button id="send-chat" class="bg-blue-600 text-white px-4 rounded-r-lg hover:bg-blue-700 transition">
<i class="fas fa-paper-plane"></i>
</button>
</div>
</div>
</div>
<!-- Results Section -->
<div>
<div id="loading-spinner" class="hidden flex justify-center items-center h-32">
<div class="animate-spin rounded-full h-12 w-12 border-t-2 border-b-2 border-blue-500"></div>
</div>
<div id="song-results" class="hidden">
<div class="flex justify-between items-center mb-4">
<h3 class="text-xl font-bold text-gray-800" id="song-title">Song Title</h3>
<div class="flex space-x-2">
<button id="transpose-up" class="bg-blue-100 text-blue-700 px-3 py-1 rounded-lg hover:bg-blue-200 transition">
<i class="fas fa-arrow-up"></i> +1
</button>
<button id="transpose-down" class="bg-blue-100 text-blue-700 px-3 py-1 rounded-lg hover:bg-blue-200 transition">
<i class="fas fa-arrow-down"></i> -1
</button>
<button id="send-to-teleprompter" class="bg-purple-600 text-white px-4 py-1 rounded-lg hover:bg-purple-700 transition flex items-center">
<i class="fas fa-arrow-right mr-2"></i> To Teleprompter
</button>
</div>
</div>
<div id="youtube-link" class="mb-2 hidden">
<a href="#" target="_blank" class="text-red-600 hover:text-red-700 flex items-center">
<i class="fab fa-youtube mr-2"></i> Watch on YouTube
</a>
<p class="text-sm text-gray-600 mt-1">Check out <a href="https://www.youtube.com/c/GuitarGaani" target="_blank" class="text-blue-600">GuitarGaani</a> for more tutorials!</p>
</div>
<div class="flex items-center space-x-4 mb-4">
<span class="text-gray-600" id="song-artist">Artist</span>
<span class="text-gray-600" id="song-year">Year</span>
</div>
<div class="mb-4">
<h4 class="font-semibold text-gray-700 mb-2">Key & Capo Information</h4>
<div class="bg-gray-50 p-3 rounded-lg">
<div class="grid grid-cols-2 gap-2">
<div>
<span class="text-gray-500">Key:</span>
<span class="font-medium" id="song-key">C Major</span>
</div>
<div>
<span class="text-gray-500">Capo:</span>
<span class="font-medium" id="song-capo">3rd fret</span>
</div>
<div>
<span class="text-gray-500">Difficulty:</span>
<span class="font-medium" id="song-difficulty">Intermediate</span>
</div>
<div>
<span class="text-gray-500">Tuning:</span>
<span class="font-medium" id="song-tuning">Standard</span>
</div>
</div>
</div>
</div>
<div>
<h4 class="font-semibold text-gray-700 mb-2">Chords Used</h4>
<div class="flex flex-wrap gap-2 mb-4" id="chord-bank">
<!-- Chords will be added here dynamically -->
</div>
<h4 class="font-semibold text-gray-700 mb-2">Lyrics with Chords</h4>
<div class="bg-gray-50 p-4 rounded-lg h-64 overflow-y-auto font-mono text-sm" id="song-lyrics">
<!-- Lyrics with chords will be added here -->
</div>
</div>
</div>
</div>
</div>
</section>
<!-- Teleprompter Section -->
<section id="teleprompter" class="mb-12 bg-white rounded-xl shadow-lg p-6">
<h2 class="text-2xl font-bold text-gray-800 mb-6 flex items-center">
<i class="fas fa-scroll mr-2 text-purple-600"></i> 4K Teleprompter
</h2>
<div class="grid grid-cols-1 lg:grid-cols-2 gap-8">
<!-- Controls -->
<div class="space-y-6">
<div>
<label class="block text-gray-700 mb-2 font-medium">Teleprompter Text</label>
<textarea id="teleprompter-input" rows="10" class="w-full p-3 border border-gray-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-purple-500" placeholder="Paste lyrics with chords here or use the 'To Teleprompter' button from Chord Finder"></textarea>
</div>
<div class="grid grid-cols-2 gap-4">
<div>
<label class="block text-gray-700 mb-2 font-medium">Scroll Speed</label>
<input type="range" id="scroll-speed" min="1" max="10" value="5" class="w-full">
<div class="flex justify-between text-xs text-gray-500">
<span>Slow</span>
<span>Fast</span>
</div>
</div>
<div>
<label class="block text-gray-700 mb-2 font-medium">Font Size</label>
<input type="range" id="font-size" min="1" max="5" value="3" class="w-full">
<div class="flex justify-between text-xs text-gray-500">
<span>Small</span>
<span>Large</span>
</div>
</div>
</div>
<div class="grid grid-cols-2 gap-4">
<div>
<label class="block text-gray-700 mb-2 font-medium">Text Color</label>
<select id="text-color" class="w-full p-2 border border-gray-300 rounded-lg">
<option value="text-white">White</option>
<option value="text-yellow-300">Yellow</option>
<option value="text-green-400">Green</option>
<option value="text-blue-300">Blue</option>
</select>
</div>
<div>
<label class="block text-gray-700 mb-2 font-medium">Background</label>
<select id="bg-color" class="w-full p-2 border border-gray-300 rounded-lg">
<option value="bg-black">Black</option>
<option value="bg-gray-800">Dark Gray</option>
<option value="bg-blue-900">Navy Blue</option>
<option value="bg-transparent">Transparent</option>
</select>
</div>
</div>
<div class="grid grid-cols-2 gap-4">
<div>
<label class="block text-gray-700 mb-2 font-medium">Orientation</label>
<select id="orientation" class="w-full p-2 border border-gray-300 rounded-lg">
<option value="horizontal">Horizontal</option>
<option value="vertical">Vertical</option>
</select>
</div>
<div>
<label class="block text-gray-700 mb-2 font-medium">Mirror Mode</label>
<select id="mirror-mode" class="w-full p-2 border border-gray-300 rounded-lg">
<option value="normal">Normal</option>
<option value="mirrored">Mirrored</option>
</select>
</div>
</div>
<div class="flex space-x-4 pt-4">
<button id="start-teleprompter" class="flex-grow bg-purple-600 text-white px-4 py-2 rounded-lg hover:bg-purple-700 transition flex items-center justify-center">
<i class="fas fa-play mr-2"></i> Start Teleprompter
</button>
<button id="reset-teleprompter" class="bg-gray-200 text-gray-800 px-4 py-2 rounded-lg hover:bg-gray-300 transition">
<i class="fas fa-redo"></i>
</button>
</div>
</div>
<!-- Preview -->
<div>
<div class="bg-black rounded-lg overflow-hidden relative" style="aspect-ratio: 16/9;">
<div id="teleprompter-display" class="h-full w-full flex items-center justify-center overflow-hidden relative">
<div id="teleprompter-text" class="teleprompter-text text-white text-center p-4">
Your teleprompter text will appear here. Adjust settings on the left to customize appearance.
</div>
</div>
</div>
<div class="mt-4 grid grid-cols-2 gap-4">
<button id="start-recording" class="bg-red-600 text-white px-4 py-2 rounded-lg hover:bg-red-700 transition flex items-center justify-center">
<i class="fas fa-circle mr-2"></i> Start Recording
</button>
<button id="stop-recording" class="bg-gray-600 text-white px-4 py-2 rounded-lg hover:bg-gray-700 transition flex items-center justify-center disabled:opacity-50" disabled>
<i class="fas fa-stop mr-2"></i> Stop Recording
</button>
</div>
<div class="mt-4 hidden" id="recording-status">
<div class="flex items-center text-red-600">
<i class="fas fa-circle mr-2"></i>
<span>Recording in progress...</span>
</div>
<div class="mt-2 text-sm text-gray-600">
<span id="recording-timer">00:00:00</span>
</div>
</div>
</div>
</div>
</section>
<!-- Video Editor Section -->
<section id="video-editor" class="bg-white rounded-xl shadow-lg p-6">
<h2 class="text-2xl font-bold text-gray-800 mb-6 flex items-center">
<i class="fas fa-film mr-2 text-green-600"></i> AI Video Editor
</h2>
<div class="grid grid-cols-1 lg:grid-cols-3 gap-8">
<!-- Video Preview -->
<div class="lg:col-span-2">
<div class="bg-black rounded-lg overflow-hidden" style="aspect-ratio: 16/9;">
<video id="video-preview" controls class="w-full h-full" style="display: none;"></video>
<canvas id="video-canvas" class="w-full h-full" style="display: none;"></canvas>
<div id="no-video" class="h-full flex items-center justify-center text-gray-400">
<div class="text-center">
<i class="fas fa-video text-4xl mb-2"></i>
<p>Your recorded video will appear here</p>
</div>
</div>
</div>
<div class="mt-4 flex flex-wrap gap-2">
<button id="play-video" class="bg-green-600 text-white px-4 py-2 rounded-lg hover:bg-green-700 transition flex items-center disabled:opacity-50" disabled>
<i class="fas fa-play mr-2"></i> Play
</button>
<button id="pause-video" class="bg-yellow-500 text-white px-4 py-2 rounded-lg hover:bg-yellow-600 transition flex items-center disabled:opacity-50" disabled>
<i class="fas fa-pause mr-2"></i> Pause
</button>
<button id="apply-effects" class="bg-blue-600 text-white px-4 py-2 rounded-lg hover:bg-blue-700 transition flex items-center disabled:opacity-50" disabled>
<i class="fas fa-magic mr-2"></i> AI Enhance
</button>
<button id="export-video" class="bg-purple-600 text-white px-4 py-2 rounded-lg hover:bg-purple-700 transition flex items-center disabled:opacity-50" disabled>
<i class="fas fa-download mr-2"></i> Export
</button>
</div>
</div>
<!-- AI Effects Panel -->
<div>
<div class="bg-gray-50 rounded-lg p-4">
<h3 class="font-semibold text-gray-700 mb-3">AI Video Effects</h3>
<div class="space-y-4">
<div>
<label class="block text-gray-700 mb-2">Background Replacement</label>
<select id="bg-replacement" class="w-full p-2 border border-gray-300 rounded-lg">
<option value="none">None</option>
<option value="blur">Blur Background</option>
<option value="studio">Studio Background</option>
<option value="nature">Nature Scene</option>
<option value="stage">Concert Stage</option>
<option value="custom">Custom Image</option>
</select>
<div id="custom-bg-upload" class="mt-2 hidden">
<label class="block text-gray-700 mb-1 text-sm">Upload Background</label>
<input type="file" id="bg-image-upload" accept="image/*" class="w-full text-sm">
</div>
</div>
<div>
<label class="block text-gray-700 mb-2">Lighting Adjustment</label>
<select id="lighting-effect" class="w-full p-2 border border-gray-300 rounded-lg">
<option value="none">None</option>
<option value="warm">Warm Tone</option>
<option value="cool">Cool Tone</option>
<option value="dramatic">Dramatic Lighting</option>
<option value="soft">Soft Lighting</option>
</select>
</div>
<div>
<label class="block text-gray-700 mb-2">AI Audio Enhancement</label>
<select id="audio-effect" class="w-full p-2 border border-gray-300 rounded-lg">
<option value="none">None</option>
<option value="studio">Studio Quality</option>
<option value="reverb">Add Reverb</option>
<option value="compression">Compression</option>
<option value="auto-tune">Auto-Tune</option>
<option value="custom">Custom Settings</option>
</select>
<div id="audio-custom-settings" class="mt-2 hidden space-y-2">
<div>
<label class="block text-gray-700 text-sm">Reverb</label>
<input type="range" id="reverb-level" min="0" max="100" value="0" class="w-full">
</div>
<div>
<label class="block text-gray-700 text-sm">Compression</label>
<input type="range" id="compression-level" min="0" max="100" value="50" class="w-full">
</div>
<div>
<label class="block text-gray-700 text-sm">Gain</label>
<input type="range" id="gain-level" min="-10" max="10" value="0" class="w-full">
</div>
</div>
</div>
<div>
<label class="block text-gray-700 mb-2">Text Overlay</label>
<div class="flex items-center space-x-2">
<input type="checkbox" id="show-chords" class="rounded text-blue-600">
<label for="show-chords">Show Chords</label>
</div>
<div class="flex items-center space-x-2 mt-1">
<input type="checkbox" id="show-lyrics" class="rounded text-blue-600" checked>
<label for="show-lyrics">Show Lyrics</label>
</div>
</div>
<button id="preview-effects" class="w-full bg-blue-600 text-white px-4 py-2 rounded-lg hover:bg-blue-700 transition flex items-center justify-center disabled:opacity-50" disabled>
<i class="fas fa-eye mr-2"></i> Preview Effects
</button>
</div>
</div>
<div class="mt-4 bg-gray-50 rounded-lg p-4">
<h3 class="font-semibold text-gray-700 mb-3">Export Settings</h3>
<div class="space-y-3">
<div>
<label class="block text-gray-700 mb-1 text-sm">Resolution</label>
<select id="export-resolution" class="w-full p-2 border border-gray-300 rounded-lg text-sm">
<option value="1080">1080p (Full HD)</option>
<option value="720">720p (HD)</option>
<option value="4k" selected>4K (UHD)</option>
</select>
</div>
<div>
<label class="block text-gray-700 mb-1 text-sm">Format</label>
<select id="export-format" class="w-full p-2 border border-gray-300 rounded-lg text-sm">
<option value="mp4" selected>MP4</option>
<option value="mov">MOV</option>
<option value="webm">WebM</option>
</select>
</div>
<div>
<label class="block text-gray-700 mb-1 text-sm">Quality</label>
<select id="export-quality" class="w-full p-2 border border-gray-300 rounded-lg text-sm">
<option value="high">High</option>
<option value="medium" selected>Medium</option>
<option value="low">Low</option>
</select>
</div>
</div>
</div>
</div>
</div>
</section>
</main>
<!-- Footer -->
<footer class="gradient-bg text-white p-6 mt-12">
<div class="container mx-auto">
<div class="grid grid-cols-1 md:grid-cols-3 gap-8">
<div>
<h3 class="text-xl font-bold mb-4">ChordGenius</h3>
<p class="text-blue-200">Your AI-powered guitar companion for finding chords, creating teleprompter videos, and professional video editing.</p>
</div>
<div>
<h4 class="font-semibold mb-4">Features</h4>
<ul class="space-y-2">
<li><a href="#chord-finder" class="text-blue-200 hover:text-white transition">AI Chord Finder</a></li>
<li><a href="#teleprompter" class="text-blue-200 hover:text-white transition">4K Teleprompter</a></li>
<li><a href="#video-editor" class="text-blue-200 hover:text-white transition">AI Video Editor</a></li>
</ul>
</div>
<div>
<h4 class="font-semibold mb-4">Connect</h4>
<div class="flex space-x-4">
<a href="#" class="text-2xl text-blue-200 hover:text-white transition"><i class="fab fa-facebook"></i></a>
<a href="#" class="text-2xl text-blue-200 hover:text-white transition"><i class="fab fa-twitter"></i></a>
<a href="#" class="text-2xl text-blue-200 hover:text-white transition"><i class="fab fa-instagram"></i></a>
<a href="#" class="text-2xl text-blue-200 hover:text-white transition"><i class="fab fa-youtube"></i></a>
</div>
</div>
</div>
<div class="border-t border-blue-800 mt-8 pt-6 text-center text-blue-200">
<p>&copy; 2023 ChordGenius. All rights reserved.</p>
</div>
</div>
</footer>
</div>
<script>
// Mobile Menu Toggle
document.getElementById('mobile-menu-btn').addEventListener('click', function() {
const menu = document.getElementById('mobile-menu');
menu.classList.toggle('hidden');
});
// Sample data for demonstration
const sampleSongs = {
"hotel california": {
title: "Hotel California",
artist: "Eagles",
year: "1976",
key: "B minor",
capo: "No capo (or 7th fret for easier chords)",
difficulty: "Intermediate",
tuning: "Standard",
chords: ["Bm", "F#", "A", "E", "G", "D", "Em", "F#7"],
lyrics: `
[Intro]
Bm F# A E G D Em F#7
[Verse 1]
Bm F#
On a dark desert highway
A E
Cool wind in my hair
G D
Warm smell of colitas
Em F#7
Rising up through the air
[Chorus]
Bm F# A E
Welcome to the Hotel California
G D Em F#7
Such a lovely place (such a lovely place)
Bm F# A E
Plenty of room at the Hotel California
G D Em F#7
Any time of year (any time of year)
`
},
"wonderwall": {
title: "Wonderwall",
artist: "Oasis",
year: "1995",
key: "F# minor (capo 2)",
capo: "2nd fret",
difficulty: "Beginner",
tuning: "Standard",
chords: ["Em7", "G", "D", "A7sus4", "C", "D7"],
lyrics: `
[Intro]
Em7 G D A7sus4
[Verse 1]
Em7 G
Today is gonna be the day
D A7sus4
That they're gonna throw it back to you
Em7 G
By now you should've somehow
D A7sus4
Realized what you gotta do
[Chorus]
C D7
I don't believe that anybody
Em7 G
Feels the way I do
C D7
About you now
`
},
"smells like teen spirit": {
title: "Smells Like Teen Spirit",
artist: "Nirvana",
year: "1991",
key: "F minor",
capo: "No capo",
difficulty: "Intermediate",
tuning: "Drop D",
chords: ["F5", "Bb5", "Ab5", "Db5"],
lyrics: `
[Intro]
F5 Bb5 Ab5 Db5
[Verse]
F5 Bb5
Load up on guns, bring your friends
Ab5 Db5
It's fun to lose and to pretend
F5 Bb5
She's over bored and self assured
Ab5 Db5
Oh no, I know a dirty word
[Chorus]
F5 Bb5
Hello, hello, hello, how low
F5 Bb5
Hello, hello, hello, how low
F5 Bb5
Hello, hello, hello, how low
Ab5 Db5
Hello, hello, hello
[Intro]
Em7 G D A7sus4
[Verse 1]
Em7 G
Today is gonna be the day
D A7sus4
That they're gonna throw it back to you
Em7 G
By now you should've somehow
D A7sus4
Realized what you gotta do
[Chorus]
C D7
I don't believe that anybody
Em7 G
Feels the way I do
C D7
About you now
`
},
"pal pal": {
title: "Pal Pal Dil Ke Paas",
artist: "Kishore Kumar",
year: "1973",
key: "C Major",
capo: "3rd fret",
difficulty: "Intermediate",
tuning: "Standard",
chords: ["C", "G", "Am", "F", "Dm", "E7"],
youtube: "https://www.youtube.com/watch?v=dQw4w9WgXcQ",
lyrics: `
[Intro]
C G Am F
[Verse 1]
C G
Pal pal dil ke paas
Am F
Tum rehti ho
C G
Pal pal dil ke paas
Am F
Tum rehti ho
[Chorus]
Dm G
Tumhari kasam
C Am
Tumhari kasam
F G C
Tumhari kasam...
`
}
};
// Chord Finder Functionality
document.getElementById('search-btn').addEventListener('click', function() {
const searchTerm = document.getElementById('song-search').value.trim().toLowerCase();
if (!searchTerm) {
document.getElementById('chat-messages').innerHTML += `
<div class="text-sm text-red-500 mt-2">AI: Please enter a song name or artist to search.</div>
`;
document.getElementById('chat-messages').scrollTop = chatMessages.scrollHeight;
return;
}
showLoading(true);
// Simulate API call with timeout
setTimeout(() => {
try {
if (sampleSongs[searchTerm]) {
displaySongResults(sampleSongs[searchTerm]);
} else {
// If no exact match, try to find partial matches
const matches = Object.keys(sampleSongs).filter(song =>
song.includes(searchTerm) || sampleSongs[song].artist.toLowerCase().includes(searchTerm)
);
if (matches.length > 0) {
displaySongResults(sampleSongs[matches[0]]);
document.getElementById('chat-messages').innerHTML += `
<div class="text-sm text-gray-600 mt-2">AI: Showing results for "${matches[0]}" since we couldn't find an exact match for "${searchTerm}".</div>
`;
} else {
document.getElementById('chat-messages').innerHTML += `
<div class="text-sm text-red-500 mt-2">AI: Couldn't find any matches for "${searchTerm}". Try a different song or upload an audio file.</div>
`;
showLoading(false);
}
}
} catch (error) {
console.error('Search error:', error);
document.getElementById('chat-messages').innerHTML += `
<div class="text-sm text-red-500 mt-2">AI: Something went wrong. Please try again.</div>
`;
showLoading(false);
}
document.getElementById('chat-messages').scrollTop = chatMessages.scrollHeight;
}, 1500);
});
// File Upload Handling
document.getElementById('audio-upload').addEventListener('change', function(e) {
const file = e.target.files[0];
if (file) {
document.getElementById('file-name').textContent = file.name;
document.getElementById('analyze-btn').disabled = false;
// Simple audio visualization for demo
const audioContext = new (window.AudioContext || window.webkitAudioContext)();
const fileReader = new FileReader();
fileReader.onload = function(e) {
audioContext.decodeAudioData(e.target.result).then(function(buffer) {
visualizeAudio(buffer);
});
};
fileReader.readAsArrayBuffer(file);
}
});
function visualizeAudio(buffer) {
const audioVisualizer = document.getElementById('audio-visualizer');
audioVisualizer.classList.remove('hidden');
// Simple waveform visualization
const canvas = document.createElement('canvas');
canvas.width = audioVisualizer.offsetWidth;
canvas.height = audioVisualizer.offsetHeight;
audioVisualizer.innerHTML = '';
audioVisualizer.appendChild(canvas);
const ctx = canvas.getContext('2d');
const data = buffer.getChannelData(0);
const step = Math.ceil(data.length / canvas.width);
const amp = canvas.height / 2;
ctx.fillStyle = 'rgba(255, 255, 255, 0.2)';
ctx.fillRect(0, 0, canvas.width, canvas.height);
ctx.beginPath();
ctx.strokeStyle = '#ffffff';
ctx.lineWidth = 2;
for (let i = 0; i < canvas.width; i++) {
const min = 1.0;
const max = -1.0;
for (let j = 0; j < step; j++) {
const datum = data[(i * step) + j];
if (datum < min) min = datum;
if (datum > max) max = datum;
}
ctx.moveTo(i, (1 + min) * amp);
ctx.lineTo(i, (1 + max) * amp);
}
ctx.stroke();
}
document.getElementById('analyze-btn').addEventListener('click', function() {
showLoading(true);
// Simulate AI audio analysis with timeout
setTimeout(() => {
displaySongResults(sampleSongs['hotel california']); // Default to Hotel California for demo
document.getElementById('chat-messages').innerHTML += `
<div class="text-sm text-gray-600 mt-2">AI: I've analyzed your audio file and detected the song "Hotel California" by Eagles. Here are the chords and lyrics.</div>
`;
}, 2000);
});
function showLoading(show) {
const loadingSpinner = document.getElementById('loading-spinner');
const songResults = document.getElementById('song-results');
if (show) {
loadingSpinner.classList.remove('hidden');
songResults.classList.add('hidden');
} else {
loadingSpinner.classList.add('hidden');
songResults.classList.remove('hidden');
}
}
function displaySongResults(song) {
try {
if (!song || !song.title) {
throw new Error('Invalid song data');
}
document.getElementById('song-title').textContent = song.title;
document.getElementById('song-artist').textContent = song.artist || 'Unknown artist';
document.getElementById('song-year').textContent = song.year || 'Unknown year';
document.getElementById('song-key').textContent = song.key || 'Not specified';
document.getElementById('song-capo').textContent = song.capo || 'Not needed';
document.getElementById('song-difficulty').textContent = song.difficulty || 'Medium';
document.getElementById('song-tuning').textContent = song.tuning || 'Standard';
// Display chords
const chordBank = document.getElementById('chord-bank');
chordBank.innerHTML = '';
song.chords.forEach(chord => {
const chordElement = document.createElement('div');
chordElement.className = 'bg-blue-100 text-blue-800 px-3 py-1 rounded-full text-sm font-medium';
chordElement.textContent = chord;
chordBank.appendChild(chordElement);
});
// Display lyrics with chords
const lyricsElement = document.getElementById('song-lyrics');
lyricsElement.innerHTML = '';
// Process lyrics to highlight chords
const lines = song.lyrics.split('\n');
lines.forEach(line => {
const lineElement = document.createElement('div');
lineElement.className = 'mb-1';
// Simple chord detection (in real app, would need more sophisticated parsing)
const words = line.split(/(\[.*?\])|(\b[A-Za-z0-9#]+\b)/g).filter(Boolean);
words.forEach(word => {
if (song.chords.includes(word)) {
const chordSpan = document.createElement('span');
chordSpan.className = 'chord-highlight text-blue-600 font-bold';
chordSpan.textContent = word;
lineElement.appendChild(chordSpan);
} else {
lineElement.appendChild(document.createTextNode(word));
}
});
lyricsElement.appendChild(lineElement);
});
// Show YouTube link if available
const youtubeLink = document.getElementById('youtube-link');
if (song.youtube) {
youtubeLink.classList.remove('hidden');
const link = youtubeLink.querySelector('a');
link.href = song.youtube;
} else {
youtubeLink.classList.add('hidden');
}
// Show AI chat
document.getElementById('ai-chat').classList.remove('hidden');
showLoading(false);
}
// AI Chat Functionality
document.getElementById('send-chat').addEventListener('click', function() {
const chatInput = document.getElementById('chat-input');
const message = chatInput.value.trim();
if (message) {
// Add user message to chat
const chatMessages = document.getElementById('chat-messages');
chatMessages.innerHTML += `
<div class="text-right text-sm text-blue-700 mb-2">You: ${message}</div>
`;
// Simulate AI response
setTimeout(() => {
let response = "I'm not sure how to answer that. Can you be more specific?";
if (message.toLowerCase().includes('capo')) {
const currentSong = document.getElementById('song-title').textContent;
const capoPosition = document.getElementById('song-capo').textContent;
response = `For ${currentSong}, the recommended capo position is ${capoPosition}.`;
} else if (message.toLowerCase().includes('chord') || message.toLowerCase().includes('play')) {
const chords = Array.from(document.querySelectorAll('#chord-bank div')).map(el => el.textContent).join(', ');
response = `The main chords used in this song are: ${chords}. Would you like me to explain how to play any of these chords?`;
} else if (message.toLowerCase().includes('easy') || message.toLowerCase().includes('simpl')) {
response = "You can simplify some chords by using power chords or open chord variations. For example, try playing Bm as Bm7 or just the root and fifth.";
}
chatMessages.innerHTML += `
<div class="text-sm text-gray-600 mt-2">AI: ${response}</div>
`;
chatMessages.scrollTop = chatMessages.scrollHeight;
}, 500);
chatInput.value = '';
chatMessages.scrollTop = chatMessages.scrollHeight;
}
});
// Send to Teleprompter
document.getElementById('send-to-teleprompter').addEventListener('click', function() {
const lyrics = document.getElementById('song-lyrics').textContent;
document.getElementById('teleprompter-input').value = lyrics;
// Scroll to teleprompter section
document.getElementById('teleprompter').scrollIntoView({ behavior: 'smooth' });
});
// Teleprompter Functionality
let teleprompterInterval;
let scrollPosition = 0;
document.getElementById('start-teleprompter').addEventListener('click', function() {
const text = document.getElementById('teleprompter-input').value;
if (!text) return;
const speed = document.getElementById('scroll-speed').value;
const fontSize = document.getElementById('font-size').value;
const textColor = document.getElementById('text-color').value;
const bgColor = document.getElementById('bg-color').value;
const orientation = document.getElementById('orientation').value;
const mirrorMode = document.getElementById('mirror-mode').value;
const teleprompterText = document.getElementById('teleprompter-text');
teleprompterText.innerHTML = text.replace(/\n/g, '<br>');
teleprompterText.className = `teleprompter-text ${textColor} text-center p-4`;
const teleprompterDisplay = document.getElementById('teleprompter-display');
teleprompterDisplay.className = `h-full w-full flex items-center justify-center overflow-hidden relative ${bgColor}`;
// Set font size based on slider (1-5)
const sizeMap = {1: '1.5rem', 2: '2rem', 3: '2.5rem', 4: '3rem', 5: '3.5rem'};
teleprompterText.style.fontSize = sizeMap[fontSize];
// Handle orientation
if (orientation === 'vertical') {
teleprompterDisplay.style.aspectRatio = '9/16';
} else {
teleprompterDisplay.style.aspectRatio = '16/9';
}
// Handle mirror mode
if (mirrorMode === 'mirrored') {
teleprompterText.style.transform = 'scaleX(-1)';
} else {
teleprompterText.style.transform = 'scaleX(1)';
}
// Start scrolling
scrollPosition = 0;
teleprompterText.style.transform += ` translateY(${scrollPosition}px)`;
clearInterval(teleprompterInterval);
teleprompterInterval = setInterval(() => {
scrollPosition -= 1;
teleprompterText.style.transform = (mirrorMode === 'mirrored' ? 'scaleX(-1)' : 'scaleX(1)') + ` translateY(${scrollPosition}px)`;
// Reset if scrolled past end
if (scrollPosition < -teleprompterText.offsetHeight) {
scrollPosition = teleprompterDisplay.offsetHeight;
}
}, 100 - (speed * 9));
});
document.getElementById('reset-teleprompter').addEventListener('click', function() {
clearInterval(teleprompterInterval);
scrollPosition = 0;
document.getElementById('teleprompter-text').style.transform = 'translateY(0)';
});
// Video Recording Functionality
let mediaRecorder;
let recordedChunks = [];
let recordingStartTime;
let timerInterval;
document.getElementById('start-recording').addEventListener('click', async function() {
try {
const stream = await navigator.mediaDevices.getDisplayMedia({
video: {
width: { ideal: 3840 },
height: { ideal: 2160 },
frameRate: { ideal: 60 }
},
audio: true
});
mediaRecorder = new MediaRecorder(stream);
mediaRecorder.ondataavailable = function(e) {
if (e.data.size > 0) {
recordedChunks.push(e.data);
}
};
mediaRecorder.onstop = function() {
const blob = new Blob(recordedChunks, { type: 'video/webm' });
const videoUrl = URL.createObjectURL(blob);
const videoPreview = document.getElementById('video-preview');
videoPreview.src = videoUrl;
videoPreview.style.display = 'block';
document.getElementById('no-video').style.display = 'none';
// Enable video editor buttons
document.getElementById('play-video').disabled = false;
document.getElementById('pause-video').disabled = false;
document.getElementById('apply-effects').disabled = false;
document.getElementById('export-video').disabled = false;
document.getElementById('preview-effects').disabled = false;
// Stop all tracks
stream.getTracks().forEach(track => track.stop());
// Clear timer
clearInterval(timerInterval);
document.getElementById('recording-status').classList.add('hidden');
};
recordedChunks = [];
mediaRecorder.start(100); // Collect data every 100ms
recordingStartTime = Date.now();
// Update timer
timerInterval = setInterval(updateRecordingTimer, 1000);
// Update UI
document.getElementById('recording-status').classList.remove('hidden');
document.getElementById('start-recording').disabled = true;
document.getElementById('stop-recording').disabled = false;
document.getElementById('start-recording').classList.add('recording-active');
} catch (err) {
console.error('Error recording:', err);
alert('Could not start recording. Please make sure to select a window or screen to record.');
}
});
function updateRecordingTimer() {
const elapsed = Math.floor((Date.now() - recordingStartTime) / 1000);
const hours = Math.floor(elapsed / 3600).toString().padStart(2, '0');
const minutes = Math.floor((elapsed % 3600) / 60).toString().padStart(2, '0');
const seconds = (elapsed % 60).toString().padStart(2, '0');
document.getElementById('recording-timer').textContent = `${hours}:${minutes}:${seconds}`;
}
document.getElementById('stop-recording').addEventListener('click', function() {
if (mediaRecorder && mediaRecorder.state !== 'inactive') {
mediaRecorder.stop();
document.getElementById('start-recording').disabled = false;
document.getElementById('stop-recording').disabled = true;
document.getElementById('start-recording').classList.remove('recording-active');
}
});
// Video Editor Functionality
document.getElementById('play-video').addEventListener('click', function() {
const video = document.getElementById('video-preview');
video.play();
});
document.getElementById('pause-video').addEventListener('click', function() {
const video = document.getElementById('video-preview');
video.pause();
});
document.getElementById('bg-replacement').addEventListener('change', function() {
const value = this.value;
const customUpload = document.getElementById('custom-bg-upload');
if (value === 'custom') {
customUpload.classList.remove('hidden');
} else {
customUpload.classList.add('hidden');
}
});
document.getElementById('audio-effect').addEventListener('change', function() {
const value = this.value;
const customSettings = document.getElementById('audio-custom-settings');
if (value === 'custom') {
customSettings.classList.remove('hidden');
} else {
customSettings.classList.add('hidden');
}
});
document.getElementById('preview-effects').addEventListener('click', function() {
// In a real app, this would apply the selected effects to a preview
alert('In the full app, this would show a preview of your selected effects before applying them.');
});
document.getElementById('apply-effects').addEventListener('click', function() {
// Simulate AI processing
showLoading(true);
const videoCanvas = document.getElementById('video-canvas');
const videoPreview = document.getElementById('video-preview');
setTimeout(() => {
// In a real app, this would apply the selected effects using AI/WebGL
videoPreview.style.display = 'none';
videoCanvas.style.display = 'block';
const ctx = videoCanvas.getContext('2d');
videoCanvas.width = videoPreview.videoWidth;
videoCanvas.height = videoPreview.videoHeight;
// Draw a sample effect (in real app, would apply actual AI effects)
ctx.filter = 'contrast(1.2) brightness(1.1) saturate(1.3)';
ctx.drawImage(videoPreview, 0, 0, videoCanvas.width, videoCanvas.height);
showLoading(false);
alert('AI effects applied successfully! The video has been enhanced with better lighting and background.');
}, 2000);
});
document.getElementById('export-video').addEventListener('click', function() {
// In a real app, this would export the final video
alert('Video exported successfully! In the full app, this would save to your device or gallery.');
// Simulate download
const link = document.createElement('a');
link.href = document.getElementById('video-preview').src;
link.download = 'chordgenius-video.mp4';
document.body.appendChild(link);
link.click();
document.body.removeChild(link);
});
// Initialize the app
// Transpose functionality
let currentKey = '';
document.getElementById('transpose-up').addEventListener('click', function() {
if (currentKey) {
const newKey = transposeKey(currentKey, 1);
document.getElementById('song-key').textContent = newKey + ' (Transposed +1)';
currentKey = newKey;
}
});
document.getElementById('transpose-down').addEventListener('click', function() {
if (currentKey) {
const newKey = transposeKey(currentKey, -1);
document.getElementById('song-key').textContent = newKey + ' (Transposed -1)';
currentKey = newKey;
}
});
// Helper function to transpose keys
function transposeKey(key, semitones) {
const keys = ['C', 'C#', 'D', 'D#', 'E', 'F', 'F#', 'G', 'G#', 'A', 'A#', 'B'];
const minorMatch = key.match(/([A-G]#?)(m|minor)/i);
const isMinor = minorMatch ? true : false;
const baseKey = minorMatch ? minorMatch[1] : key.match(/[A-G]#?/)[0];
let index = keys.indexOf(baseKey.toUpperCase());
if (index === -1) return key;
index = (index + semitones + 12) % 12;
const newKey = keys[index] + (isMinor ? 'm' : '');
return newKey;
}
document.addEventListener('DOMContentLoaded', function() {
// Show AI chat by default with welcome message
document.getElementById('ai-chat').classList.remove('hidden');
// For demo purposes, show the Hotel California results
displaySongResults(sampleSongs['hotel california']);
});
</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=tushkum/chordgenius" style="color: #fff;text-decoration: underline;" target="_blank" >Remix</a></p></body>
</html>