Overview
SoundWave provides a powerful search system that helps you find music quickly across multiple sources including YouTube and Spotify. The search feature includes real-time suggestions, smart filtering, and multi-page result aggregation.
SoundWave implements debouncing to optimize search performance and reduce unnecessary API calls while you type.
How Debouncing Works
User Types Query
As you type in the search field, the input event is captured.
Debounce Timer Activates
The system waits 300ms before triggering the search to avoid excessive API calls.
Suggestions Display
After the delay, if you’re still typing, previous requests are cancelled and only the latest query is sent.
Implementation
The debounce function prevents API overload:
function debounce ( func , wait ) {
let timeout ;
return function ( ... args ) {
clearTimeout ( timeout );
timeout = setTimeout (() => func . apply ( this , args ), wait );
};
}
// Applied to search input with 300ms delay
document . getElementById ( 'song-name' ). addEventListener ( 'input' , debounce ( function () {
const songName = this . value ;
suggestionsContainer . innerHTML = '' ;
if ( songName ) {
originalSearchTerm = songName . toLowerCase ();
fetchSuggestions ( songName );
} else {
clearSuggestionsAndResults ();
}
}, 300 ));
The 300ms delay strikes a balance between responsiveness and performance. You can adjust this value based on your needs.
Real-Time Search Suggestions
As you type, SoundWave fetches suggestions from YouTube to help you find what you’re looking for faster.
Suggestion Sources
The system uses fallback URLs to ensure reliability:
function fetchSuggestions ( songName ) {
const url1 = 'https://inv.nadeko.net/search?q=' + encodeURIComponent ( songName );
const url2 = 'https://yewtu.be/search?q=' + encodeURIComponent ( songName );
fetch ( 'https://api.allorigins.win/raw?url=' + encodeURIComponent ( url1 ))
. then ( response => {
if ( response . ok ) return response . text ();
throw new Error ( 'Network response was not ok.' );
})
. then ( data => {
processSuggestionsData ( data );
})
. catch (() => {
// Fallback to second URL if first fails
fetch ( 'https://api.allorigins.win/raw?url=' + encodeURIComponent ( url2 ))
. then ( response => response . text ())
. then ( data => processSuggestionsData ( data ))
. catch ( error => {
console . error ( 'Error al obtener sugerencias:' , error );
});
});
}
Suggestions are limited to 5 items to keep the interface clean and focused.
Multi-Page Search
When you click the search button, SoundWave performs a comprehensive search across multiple pages to give you the best results.
Search Process
async function fetchSearchResults ( songName ) {
const maxPages = 6 ; // Search across 6 pages
let allResults = [];
for ( let page = 1 ; page <= maxPages ; page ++ ) {
const url = `https://yewtu.be/search?q= ${ encodeURIComponent ( songName ) } &page= ${ page } ` ;
try {
const response = await fetch ( 'https://api.allorigins.win/raw?url=' + encodeURIComponent ( url ));
if ( ! response . ok ) throw new Error ( 'Network response was not ok.' );
const data = await response . text ();
const parser = new DOMParser ();
const doc = parser . parseFromString ( data , 'text/html' );
const divs = doc . querySelectorAll ( 'div.video-card-row' );
// Extract and filter results
const searchResults = Array . from ( divs )
. map ( div => {
const link = div . querySelector ( 'a' );
const titleElement = link ? link . querySelector ( 'p' ) : null ;
const title = titleElement ? titleElement . innerText : 'Sin título' ;
const videoId = link ? link . getAttribute ( 'href' ). split ( 'v=' )[ 1 ] : null ;
return { title , videoId };
})
. filter ( result => {
// Apply filtering logic
const searchTerm = originalSearchTerm . toLowerCase ();
const songTitle = result . title . toLowerCase ();
const includesSearchTerm = (
songTitle . includes ( searchTerm ) ||
searchTerm . split ( ' ' ). every ( term => songTitle . includes ( term ))
);
const excludesOfficial = ! songTitle . includes ( 'oficial' ) &&
! songTitle . includes ( 'official' );
return includesSearchTerm && excludesOfficial ;
});
allResults = allResults . concat ( searchResults );
} catch ( error ) {
console . error ( 'There was a problem with the fetch operation:' , error );
}
}
// Group results for pagination
groupedResults = [];
for ( let i = 0 ; i < allResults . length ; i += 5 ) {
groupedResults . push ( allResults . slice ( i , i + 5 ));
}
currentGroupIndex = 0 ;
showGroupedResults ();
}
Result Grouping
Results are grouped in sets of 5 for easier navigation:
Group 1 : Results 1-5
Group 2 : Results 6-10
Group 3 : Results 11-15
And so on…
Navigation Controls Use the < and > buttons to navigate between result groups. The current group number is displayed at the bottom of the results.
Spotify Search
SoundWave also supports Spotify search for direct access to Spotify’s catalog:
async function searchSongs () {
const query = document . getElementById ( 'search-query' ). value . trim ();
if ( ! query ) {
alert ( 'Por favor, ingresa un término de búsqueda.' );
return ;
}
const response = await fetch (
`https://jsnode-ab0e.onrender.com/search?query= ${ encodeURIComponent ( query ) } &type=track&accessToken= ${ accessToken } `
);
const data = await response . json ();
const songList = document . getElementById ( 'song-list' );
songList . innerHTML = '' ;
data . tracks . items . forEach ( track => {
const li = document . createElement ( 'li' );
li . textContent = ` ${ track . name } - ${ track . artists . map ( artist => artist . name ). join ( ', ' ) } ` ;
li . dataset . embedUrl = `https://open.spotify.com/embed/track/ ${ track . id } ?utm_source=generator&theme=0` ;
li . addEventListener ( 'click' , () => playTrack ( li . dataset . embedUrl ));
songList . appendChild ( li );
});
}
Search Modes
YouTube Search Searches across multiple YouTube instances with intelligent filtering
Spotify Search Direct access to Spotify’s official catalog with instant playback
Best Practices
Always provide specific search terms. Generic queries like “music” will return too many irrelevant results.
Search Tips
Include Artist Name : Search “Song Name Artist” for better results
Use Exact Titles : Exact song titles yield more accurate matches
Avoid Special Characters : Keep searches simple without special symbols
Be Patient : Multi-page searches may take a few seconds
Clearing Search Results
You can clear all search results and suggestions:
function clearSuggestionsAndResults () {
suggestionsContainer . innerHTML = '' ;
filteredContent . innerHTML = '' ;
sourceLinksContainer . innerHTML = '' ;
stopAudioPlayer ();
}
This function is automatically called when you clear the search input field.
Next Steps
Filtering Results Learn how SoundWave filters search results
Playback Controls Discover how to control music playback