diff --git a/ui.ts b/ui.ts index cd201f8..b80e63e 100644 --- a/ui.ts +++ b/ui.ts @@ -1,5 +1,5 @@ /** - * Virome API - UI HTML Template + * Virome API - Premium UI Template */ export const html = ` @@ -9,73 +9,107 @@ export const html = ` Virome API + +
- Virome APIUNOFFICIAL + Virome APIUnofficial
-
- Get Started -

Explore the Docs

-

Check out the documentation to learn how to use the Virome API for music search and streaming.

-
-
- Open Source -

Open Source

-

Virome API is open-source. Built with Deno for fast, secure music data access.

-
-
- Features -

What You Can Do

-

Search songs, albums, artists. Get streaming URLs, related tracks, and more.

-
-
- Try It -

Test the Player

-

Use the built-in player to search and play music directly from the API.

-
+
📚

Explore the Docs

Comprehensive documentation to integrate Virome API into your music applications.

+

Open Source

Built with Deno for blazing fast, secure, and modern music data access.

+
🎵

Full Featured

Search songs, albums, artists. Stream music, get lyrics, and discover new tracks.

+

Live Player

Test the API with our built-in player. Search and play music instantly.

@@ -85,8 +119,8 @@ export const html = `
Search Endpoints
-
GET/api/search
Search YouTube Music. Params: q, filter (songs/albums/artists)
-
GET/api/yt_search
Search YouTube. Params: q, filter (videos/channels/playlists)
+
GET/api/search
Search YouTube Music. Params: q, filter, region, language
+
GET/api/yt_search
Search YouTube. Params: q, filter
GET/api/search/suggestions
Get search suggestions. Params: q
Content Endpoints
@@ -98,74 +132,20 @@ export const html = `
Discovery Endpoints
-
GET/api/related/:videoId
Get related songs for a video
-
GET/api/similar
Find similar tracks. Params: title, artist
-
GET/api/trending
Most played songs in a country
-
GET/api/radio
Generate radio mix. Params: videoId
-
GET/api/top/artists
Most listened artists in a country
-
GET/api/top/tracks
Most listened tracks in a country
-
-
Info Endpoints
-
-
GET/api/lyrics
Get lyrics. Params: title, artist
-
GET/api/artist/info
Artist bio and stats. Params: artist
-
GET/api/track/info
Track details. Params: title, artist
+
GET/api/related/:videoId
Get related songs
+
GET/api/similar
Find similar tracks
+
GET/api/trending
Trending music by country
+
GET/api/radio
Generate radio mix
Streaming Endpoints
GET/api/stream
Get stream URLs. Params: id
-
GET/api/watch_playlist
Get watch playlist. Params: videoId or playlistId
-
GET/health
Health check endpoint
+
GET/api/lyrics
Get lyrics. Params: title, artist
-
-
- @@ -205,16 +185,13 @@ export const html = `
Click "Test Endpoint" to see the response...
-
Virome API
+
Built with Deno
-
-
-
-
-
-
+
-
-
@@ -223,9 +200,7 @@ export const html = `
0:00 -
-
-
+
0:00
@@ -246,7 +221,7 @@ export const html = ` function fmt(s){var m=Math.floor(s/60),sec=Math.floor(s%60);return m+':'+(sec<10?'0':'')+sec} function seek(e){if(!player||!playerReady)return;var bar=document.getElementById('progressBar'),rect=bar.getBoundingClientRect(),pct=(e.clientX-rect.left)/rect.width;player.seekTo(pct*(player.getDuration()||0),true)} async function doSearch(){var q=document.getElementById('searchInput').value.trim();if(!q)return;var filter=document.getElementById('searchType').value;document.getElementById('searchBtn').disabled=true;document.getElementById('loading').style.display='block';document.getElementById('resultsList').innerHTML='';try{var url='/api/search?q='+encodeURIComponent(q);if(filter)url+='&filter='+filter;var res=await fetch(url);var data=await res.json();songs=data.results||[];renderResults(filter)}catch(e){songs=[];renderResults(filter)}document.getElementById('searchBtn').disabled=false;document.getElementById('loading').style.display='none'} - function renderResults(filter){var list=document.getElementById('resultsList');if(!songs.length){list.innerHTML='
No results found
';return}if(filter==='artists'){list.innerHTML=songs.map((s,i)=>'
'+esc(s.title||'Unknown')+'
Artist
').join('')}else if(filter==='albums'){list.innerHTML=songs.map((s,i)=>'
'+esc(s.title||'Unknown')+'
'+esc(s.artists?.map(a=>a.name).join(', ')||'Album')+'
').join('')}else{list.innerHTML=songs.map((s,i)=>{var isPlayable=s.videoId&&(s.resultType==='song'||s.resultType==='video'||!s.resultType);var onclick=isPlayable?'playSong('+i+')':s.resultType==='artist'?'openArtist(\\''+s.browseId+'\\')':s.resultType==='album'?'openAlbum(\\''+s.browseId+'\\')':'';var typeLabel=s.isTopResult?'TOP':s.resultType&&s.resultType!=='song'?''+s.resultType.toUpperCase()+'':'';return '
'+esc(s.title||'Unknown')+typeLabel+'
'+esc(s.artists?.map(a=>a.name).join(', ')||(s.subtitle||'Unknown'))+'
'+(s.duration||'')+'
'}).join('')}} + function renderResults(filter){var list=document.getElementById('resultsList');if(!songs.length){list.innerHTML='
No results found
';return}if(filter==='artists'){list.innerHTML=songs.map((s,i)=>'
'+esc(s.title||'Unknown')+'
Artist
').join('')}else if(filter==='albums'){list.innerHTML=songs.map((s,i)=>'
'+esc(s.title||'Unknown')+'
'+esc(s.artists?.map(a=>a.name).join(', ')||'Album')+'
').join('')}else{list.innerHTML=songs.map((s,i)=>{var isPlayable=s.videoId&&(s.resultType==='song'||s.resultType==='video'||!s.resultType);var onclick=isPlayable?'playSong('+i+')':s.resultType==='artist'?'openArtist(\\''+s.browseId+'\\')':s.resultType==='album'?'openAlbum(\\''+s.browseId+'\\')':'';var typeLabel=s.isTopResult?'TOP':s.resultType&&s.resultType!=='song'?''+s.resultType+'':'';return '
'+esc(s.title||'Unknown')+typeLabel+'
'+esc(s.artists?.map(a=>a.name).join(', ')||(s.subtitle||'Unknown'))+'
'+(s.duration||'')+'
'}).join('')}} function openArtist(id){switchTab('api');document.getElementById('apiEndpoint').value='artist';updateApiInputs();document.getElementById('api_browseId').value=id;updateApiUrl();testApi()} function openAlbum(id){switchTab('api');document.getElementById('apiEndpoint').value='album';updateApiInputs();document.getElementById('api_browseId').value=id;updateApiUrl();testApi()} function playSong(i){if(!songs[i])return;if(!playerReady){setTimeout(()=>playSong(i),300);return}currentIndex=i;var s=songs[i];document.getElementById('playerTitle').textContent=s.title||'Unknown';document.getElementById('playerArtist').textContent=s.artists?.map(a=>a.name).join(', ')||'Unknown';document.getElementById('playerThumb').src=s.thumbnails?.[0]?.url||'https://img.youtube.com/vi/'+s.videoId+'/mqdefault.jpg';document.getElementById('player').className='player visible';document.querySelectorAll('.result-item').forEach((el,idx)=>el.className=idx===i?'result-item active':'result-item');player.loadVideoById(s.videoId);isPlaying=true;document.getElementById('playBtn').textContent='⏸'} @@ -263,7 +238,7 @@ export const html = ` document.addEventListener('click',function(e){if(!e.target.classList.contains('country-search')){document.querySelectorAll('.country-list').forEach(l=>l.style.display='none')}}); function updateApiUrl(){var ep=document.getElementById('apiEndpoint').value,cfg=apiCfg[ep],url=cfg.url,params=new URLSearchParams();cfg.inputs.forEach(i=>{var val=document.getElementById('api_'+i.n)?.value?.trim()||i.v||'';if(val){if(url.includes('{'+i.n+'}'))url=url.replace('{'+i.n+'}',encodeURIComponent(val));else params.append(i.n,val)}});var qs=params.toString();if(qs)url+='?'+qs;document.getElementById('apiUrl').textContent='GET '+url} document.getElementById('apiInputs').oninput=updateApiUrl; - async function testApi(){var ep=document.getElementById('apiEndpoint').value,cfg=apiCfg[ep],url=cfg.url,params=new URLSearchParams();cfg.inputs.forEach(i=>{var val=document.getElementById('api_'+i.n)?.value?.trim();if(val){if(url.includes('{'+i.n+'}'))url=url.replace('{'+i.n+'}',encodeURIComponent(val));else params.append(i.n,val)}});var qs=params.toString();if(qs)url+='?'+qs;document.getElementById('apiResponse').innerHTML='
Loading...
';try{var res=await fetch(url);var data=await res.json();document.getElementById('apiResponse').innerHTML='
'+JSON.stringify(data,null,2)+'
'}catch(e){document.getElementById('apiResponse').innerHTML='
Error: '+e.message+'
'}} + async function testApi(){var ep=document.getElementById('apiEndpoint').value,cfg=apiCfg[ep],url=cfg.url,params=new URLSearchParams();cfg.inputs.forEach(i=>{var val=document.getElementById('api_'+i.n)?.value?.trim();if(val){if(url.includes('{'+i.n+'}'))url=url.replace('{'+i.n+'}',encodeURIComponent(val));else params.append(i.n,val)}});var qs=params.toString();if(qs)url+='?'+qs;document.getElementById('apiResponse').innerHTML='
Loading...
';try{var res=await fetch(url);var data=await res.json();document.getElementById('apiResponse').innerHTML='
'+JSON.stringify(data,null,2)+'
'}catch(e){document.getElementById('apiResponse').innerHTML='
Error: '+e.message+'
'}} updateApiInputs();