soundeffect-player
Version:
Lightweight JavaScript library for playing sound effects with SoundEffect.app integration
592 lines (506 loc) âĸ 20.9 kB
HTML
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>SoundEffect Player Demo - Powered by SoundEffect.app</title>
<style>
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
color: #333;
min-height: 100vh;
padding: 20px;
}
.container {
max-width: 1200px;
margin: 0 auto;
background: white;
border-radius: 20px;
box-shadow: 0 20px 40px rgba(0,0,0,0.1);
overflow: hidden;
}
.header {
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
color: white;
padding: 40px;
text-align: center;
}
.header h1 {
font-size: 2.5rem;
margin-bottom: 10px;
}
.header p {
font-size: 1.2rem;
opacity: 0.9;
}
.header a {
color: #fff;
text-decoration: none;
font-weight: bold;
border-bottom: 2px solid rgba(255,255,255,0.3);
transition: border-color 0.3s;
}
.header a:hover {
border-color: #fff;
}
.content {
padding: 40px;
}
.section {
margin-bottom: 40px;
}
.section h2 {
color: #667eea;
margin-bottom: 20px;
font-size: 1.8rem;
}
.demo-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
gap: 30px;
margin-bottom: 40px;
}
.demo-card {
background: #f8f9ff;
border-radius: 15px;
padding: 25px;
border: 2px solid #e1e5ff;
transition: all 0.3s ease;
}
.demo-card:hover {
border-color: #667eea;
box-shadow: 0 10px 30px rgba(102, 126, 234, 0.1);
}
.demo-card h3 {
color: #667eea;
margin-bottom: 15px;
font-size: 1.3rem;
}
.demo-card p {
color: #666;
margin-bottom: 20px;
line-height: 1.6;
}
.button-group {
display: flex;
flex-wrap: wrap;
gap: 10px;
margin-bottom: 20px;
}
.btn {
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
color: white;
border: none;
padding: 12px 20px;
border-radius: 8px;
cursor: pointer;
font-size: 14px;
font-weight: 500;
transition: all 0.3s ease;
min-width: 120px;
}
.btn:hover {
transform: translateY(-2px);
box-shadow: 0 5px 15px rgba(102, 126, 234, 0.3);
}
.btn:active {
transform: translateY(0);
}
.btn:disabled {
opacity: 0.6;
cursor: not-allowed;
transform: none;
}
.search-container {
margin-bottom: 20px;
}
.search-input {
width: 100%;
padding: 15px;
border: 2px solid #e1e5ff;
border-radius: 10px;
font-size: 16px;
margin-bottom: 15px;
transition: border-color 0.3s;
}
.search-input:focus {
outline: none;
border-color: #667eea;
}
.results {
background: white;
border-radius: 10px;
border: 1px solid #e1e5ff;
max-height: 200px;
overflow-y: auto;
}
.result-item {
padding: 15px;
border-bottom: 1px solid #f0f0f0;
cursor: pointer;
transition: background-color 0.3s;
}
.result-item:hover {
background-color: #f8f9ff;
}
.result-item:last-child {
border-bottom: none;
}
.result-title {
font-weight: 500;
color: #333;
margin-bottom: 5px;
}
.result-category {
color: #667eea;
font-size: 12px;
text-transform: uppercase;
font-weight: 500;
}
.controls {
background: #f8f9ff;
padding: 20px;
border-radius: 10px;
margin-bottom: 20px;
}
.control-row {
display: flex;
align-items: center;
gap: 15px;
margin-bottom: 10px;
}
.control-row:last-child {
margin-bottom: 0;
}
.control-label {
font-weight: 500;
min-width: 80px;
color: #333;
}
.volume-slider {
flex: 1;
height: 6px;
background: #e1e5ff;
border-radius: 3px;
outline: none;
-webkit-appearance: none;
}
.volume-slider::-webkit-slider-thumb {
-webkit-appearance: none;
width: 20px;
height: 20px;
background: #667eea;
border-radius: 50%;
cursor: pointer;
}
.status {
padding: 15px;
background: #e8f2ff;
border-radius: 10px;
color: #2c5aa0;
font-family: monospace;
font-size: 14px;
white-space: pre-wrap;
max-height: 150px;
overflow-y: auto;
}
.footer {
background: #f8f9ff;
padding: 30px;
text-align: center;
color: #666;
}
.footer a {
color: #667eea;
text-decoration: none;
font-weight: 500;
}
.footer a:hover {
text-decoration: underline;
}
.loading {
opacity: 0.6;
pointer-events: none;
}
@media (max-width: 768px) {
.demo-grid {
grid-template-columns: 1fr;
}
.header h1 {
font-size: 2rem;
}
.content {
padding: 20px;
}
}
</style>
</head>
<body>
<div class="container">
<div class="header">
<h1>đĩ SoundEffect Player Demo</h1>
<p>Experience 300,000+ sounds from <a href="https://soundeffect.app" target="_blank">SoundEffect.app</a> with AI-powered search</p>
</div>
<div class="content">
<!-- Basic Playback Demo -->
<div class="section">
<h2>đ Quick Start Demo</h2>
<div class="demo-grid">
<div class="demo-card">
<h3>đŽ Game Sounds</h3>
<p>Perfect sound effects for web games and interactive applications</p>
<div class="button-group">
<button class="btn" onclick="playSound('epic-win')">đ Victory</button>
<button class="btn" onclick="playSound('explosion')">đĨ Explosion</button>
<button class="btn" onclick="playSound('power-up')">⥠Power Up</button>
<button class="btn" onclick="playSound('coin-collect')">đĒ Coin</button>
</div>
</div>
<div class="demo-card">
<h3>đ Meme Sounds</h3>
<p>Viral internet sounds and popular memes from social media</p>
<div class="button-group">
<button class="btn" onclick="playSound('bruh')">đ Bruh</button>
<button class="btn" onclick="playSound('vine boom')">đĸ Vine Boom</button>
<button class="btn" onclick="playSound('among us')">đ´ Among Us</button>
<button class="btn" onclick="playSound('fail')">đ
Epic Fail</button>
</div>
</div>
<div class="demo-card">
<h3>đ UI Sounds</h3>
<p>Clean interface sounds for apps and web applications</p>
<div class="button-group">
<button class="btn" onclick="playSound('notification')">đ Notification</button>
<button class="btn" onclick="playSound('button click')">đ Click</button>
<button class="btn" onclick="playSound('success')">â
Success</button>
<button class="btn" onclick="playSound('error')">â Error</button>
</div>
</div>
<div class="demo-card">
<h3>đĒ Streaming Effects</h3>
<p>Popular sounds for streamers and content creators</p>
<div class="button-group">
<button class="btn" onclick="playSound('applause')">đ Applause</button>
<button class="btn" onclick="playSound('drum roll')">đĨ Drum Roll</button>
<button class="btn" onclick="playSound('air horn')">đ¯ Air Horn</button>
<button class="btn" onclick="playSound('wow')">đ˛ Wow</button>
</div>
</div>
</div>
</div>
<!-- AI Search Demo -->
<div class="section">
<h2>đ AI-Powered Search</h2>
<div class="demo-card">
<h3>Smart Sound Discovery</h3>
<p>Describe what you need and let AI find the perfect sound from SoundEffect.app</p>
<div class="search-container">
<input type="text" class="search-input" id="searchInput" placeholder="Try: 'epic battle music', 'funny cartoon sound', 'notification bell'...">
<button class="btn" onclick="searchSounds()" id="searchBtn">đ Search SoundEffect.app</button>
</div>
<div id="searchResults" class="results" style="display: none;"></div>
</div>
</div>
<!-- Trending Sounds -->
<div class="section">
<h2>đĨ Trending Now</h2>
<div class="demo-card">
<h3>What's Popular on SoundEffect.app</h3>
<p>Discover what sounds are trending right now</p>
<button class="btn" onclick="loadTrending()" id="trendingBtn">đĨ Load Trending Sounds</button>
<div id="trendingResults" class="results" style="display: none; margin-top: 15px;"></div>
</div>
</div>
<!-- Player Controls -->
<div class="section">
<h2>đī¸ Player Controls</h2>
<div class="demo-card">
<div class="controls">
<div class="control-row">
<span class="control-label">Volume:</span>
<input type="range" class="volume-slider" min="0" max="100" value="80" onchange="setVolume(this.value)">
<span id="volumeDisplay">80%</span>
</div>
<div class="control-row">
<button class="btn" onclick="pauseSound()">â¸ī¸ Pause</button>
<button class="btn" onclick="resumeSound()">âļī¸ Resume</button>
<button class="btn" onclick="stopSound()">âšī¸ Stop</button>
<button class="btn" onclick="getPlayerState()">đ Get State</button>
</div>
</div>
<div class="status" id="status">đĩ SoundEffect Player ready! Powered by SoundEffect.app
Try clicking any sound button above to test the integration.</div>
</div>
</div>
</div>
<div class="footer">
<p>
Built with <strong>SoundEffect Player</strong> âĸ
Powered by <a href="https://soundeffect.app" target="_blank">SoundEffect.app</a> âĸ
<a href="https://github.com/soundeffect/soundeffect-player" target="_blank">GitHub</a> âĸ
<a href="https://soundeffect.app/api" target="_blank">API Docs</a>
</p>
<p style="margin-top: 10px; font-size: 14px; opacity: 0.8;">
300,000+ royalty-free sound effects âĸ AI-powered search âĸ Perfect for games, apps & content creation
</p>
</div>
</div>
<!-- Include the SoundEffect Player library -->
<script src="../src/soundeffect-player.js"></script>
<script>
// Initialize the SoundEffect Player
const player = new SoundEffectPlayer({
debug: true, // Enable console logging for demo
volume: 0.8
});
let searchTimeout;
// Update status display
function updateStatus(message) {
const status = document.getElementById('status');
const timestamp = new Date().toLocaleTimeString();
status.textContent += `\n[${timestamp}] ${message}`;
status.scrollTop = status.scrollHeight;
}
// Play sound by search query
async function playSound(query) {
try {
updateStatus(`đ Searching for "${query}" on SoundEffect.app...`);
// Search for the sound
const results = await player.search(query, 1);
if (results.length > 0) {
const sound = results[0];
updateStatus(`đĩ Playing: ${sound.title}`);
await player.play(sound.id);
updateStatus(`â
Successfully playing sound from SoundEffect.app`);
} else {
updateStatus(`â No sounds found for "${query}"`);
}
} catch (error) {
updateStatus(`â Error: ${error.message}`);
}
}
// Search sounds with AI
async function searchSounds() {
const input = document.getElementById('searchInput');
const query = input.value.trim();
const btn = document.getElementById('searchBtn');
const results = document.getElementById('searchResults');
if (!query) return;
try {
btn.disabled = true;
btn.textContent = 'đ Searching...';
results.style.display = 'none';
updateStatus(`đ AI searching SoundEffect.app for: "${query}"`);
const sounds = await player.search(query, 10);
if (sounds.length > 0) {
results.innerHTML = sounds.map(sound => `
<div class="result-item" onclick="playSearchResult('${sound.id}', '${sound.title}')">
<div class="result-title">${sound.title}</div>
<div class="result-category">${sound.category}</div>
</div>
`).join('');
results.style.display = 'block';
updateStatus(`â
Found ${sounds.length} sounds on SoundEffect.app`);
} else {
updateStatus(`â No sounds found for "${query}"`);
}
} catch (error) {
updateStatus(`â Search error: ${error.message}`);
} finally {
btn.disabled = false;
btn.textContent = 'đ Search SoundEffect.app';
}
}
// Play a sound from search results
async function playSearchResult(soundId, title) {
try {
updateStatus(`đĩ Playing: ${title}`);
await player.play(soundId);
updateStatus(`â
Successfully playing sound from SoundEffect.app`);
} catch (error) {
updateStatus(`â Playback error: ${error.message}`);
}
}
// Load trending sounds
async function loadTrending() {
const btn = document.getElementById('trendingBtn');
const results = document.getElementById('trendingResults');
try {
btn.disabled = true;
btn.textContent = 'đĨ Loading...';
results.style.display = 'none';
updateStatus(`đĨ Loading trending sounds from SoundEffect.app...`);
const trending = await player.getTrending(8);
if (trending.length > 0) {
results.innerHTML = trending.map(sound => `
<div class="result-item" onclick="playSearchResult('${sound.id}', '${sound.title}')">
<div class="result-title">đĨ ${sound.title}</div>
<div class="result-category">${sound.category} âĸ Trending</div>
</div>
`).join('');
results.style.display = 'block';
updateStatus(`â
Loaded ${trending.length} trending sounds`);
} else {
updateStatus(`â No trending sounds available`);
}
} catch (error) {
updateStatus(`â Trending error: ${error.message}`);
} finally {
btn.disabled = false;
btn.textContent = 'đĨ Load Trending Sounds';
}
}
// Player controls
function setVolume(value) {
const volume = value / 100;
player.setVolume(volume);
document.getElementById('volumeDisplay').textContent = `${value}%`;
updateStatus(`đ Volume set to ${value}%`);
}
function pauseSound() {
player.pause();
updateStatus(`â¸ī¸ Playback paused`);
}
function resumeSound() {
player.resume();
updateStatus(`âļī¸ Playback resumed`);
}
function stopSound() {
player.stop();
updateStatus(`âšī¸ Playback stopped`);
}
function getPlayerState() {
const state = player.getState();
updateStatus(`đ Player State: ${JSON.stringify(state, null, 2)}`);
}
// Enable search on Enter key
document.getElementById('searchInput').addEventListener('keypress', function(e) {
if (e.key === 'Enter') {
searchSounds();
}
});
// Auto-search with debounce
document.getElementById('searchInput').addEventListener('input', function(e) {
const query = e.target.value.trim();
if (searchTimeout) {
clearTimeout(searchTimeout);
}
if (query.length > 2) {
searchTimeout = setTimeout(() => {
searchSounds();
}, 1000);
}
});
// Initialize demo
updateStatus(`đĩ SoundEffect Player Demo loaded!`);
updateStatus(`đ Connected to SoundEffect.app with 300K+ sounds`);
updateStatus(`đ¤ AI-powered search ready - try any description!`);
</script>
</body>
</html>