Este commit está contenido en:
Joey 😎
2025-08-01 00:46:14 +00:00
padre b2e7bb8756
commit 4883b0eb83
Se han modificado 12 ficheros con 1810 adiciones y 1003 borrados

BIN
.DS_Store vendido Archivo normal

Archivo binario no mostrado.

270
README.md
Ver fichero

@@ -1,102 +1,250 @@
# 🎵 Game! Radio Player
# HTML5 Icecast/Shoutcast/Zeno Full Page Radio Player
A modern, responsive web-based radio player with a beautiful Spotify-inspired interface. Stream your favorite radio station with real-time song information, lyrics, and playback history.
# Documentation.
![Radio Player Preview](img/cover.png)
Open The [Script.js](https://github.com/joeyboli/html5-shoutcast-icecast-zeno-player/blob/main/js/script.js) file and edit the lines Below.
## ✨ Features
```javascript
// RADIO NAME
const RADIO_NAME = 'Game! Radio 1';
- **🎧 Live Streaming**: Supports multiple streaming protocols (Icecast, Zeno, Shoutcast, Radiojar)
- **🎨 Modern UI**: Spotify-inspired interface with smooth animations
- **📱 Responsive Design**: Works perfectly on desktop, tablet, and mobile devices
- **🎵 Real-time Metadata**: Displays current song, artist, and album artwork
- **📜 Lyrics Integration**: Automatic lyrics lookup using Vagalume API
- **📚 Playback History**: Shows up to 5 recently played songs
- **🎛️ Volume Control**: Precise volume control with keyboard shortcuts
- **⌨️ Keyboard Shortcuts**: Full keyboard navigation support
- **🎨 Dynamic Artwork**: Album covers with loading animations
- **🔊 Media Session**: Integration with browser media controls
// SELECT ARTWORK PROVIDER, ITUNES, DEEZER & SPOTIFY. eg : spotify
var API_SERVICE = 'DEEZER';
## 🚀 Quick Start
// Change Stream URL Here, Supports, ICECAST, ZENO, SHOUTCAST, RADIOJAR and any other stream service.
const URL_STREAMING = 'https://stream-51.zeno.fm/cfhkm5fs1uhvv?zs=HOu6hxV1SG-7iGi9WGVTqQ';
### Prerequisites
//API URL GET API On Joeycast Website
const API_URL = 'https://api-v2.streamafrica.net/icyv2?url=' + URL_STREAMING;
- A modern web browser (Chrome, Firefox, Safari, Edge)
- A radio stream URL
- (Optional) Vagalume API key for lyrics
### Installation
1. **Clone the repository**
```bash
git clone https://github.com/yourusername/radio-player.git
cd radio-player
```
## StreamAfrica's RadioAPI
2. **Install dependencies** (if using npm/pnpm)
```bash
pnpm install
```
[https://radioapi.me](https://radioapi.me/)
3. **Configure your radio stream**
- Open `js/script.js`
- Update the `URL_STREAMING` constant with your stream URL
- Update the `API_URL` with your metadata API endpoint
## Free Hosting
4. **Serve the files**
```bash
# Using Python
python -m http.server 8000
[![Deploy with Vercel](https://vercel.com/button)](https://vercel.com/new/clone?repository-url=https%3A%2F%2Fgithub.com%2Fjoeyboli%2FRadioPlayer)
[![Deploy to Netlify](https://www.netlify.com/img/deploy/button.svg)](https://app.netlify.com/start/deploy?repository=https://github.com/joeyboli/RadioPlayer/)
# Using Node.js
npx serve .
## Change Logo.
# Using PHP
php -S localhost:8000
```
Open The img folder and add your logo named "cover.png"
5. **Open in browser**
```
http://localhost:8000
```
## ⚙️ Configuration
## Demo Screenshots
### Stream Configuration
![Demo Screenshot](https://i.ibb.co/xfXG7fb/Screenshot-2023-06-18-21-40-11.png)
Edit `js/script.js` to configure your radio stream:
```javascript
// Change Stream URL Here
const URL_STREAMING = "https://your-stream-url.com/stream"
## Supported Hosting Types
* Icecast / Shoutcast
* Zeno Radio
* RadioJar
* Azuracast
* Centova Cast
* Everest Cast
* MediaCP
* Sonic Panel
// API endpoint for metadata
const API_URL = "https://your-api-endpoint.com/metadata"
## Supported API/Data Sources
* Apple Music / Itunes
* Deezer
* Spotify
// Vagalume API key for lyrics (optional)
const API_KEY = "your-vagalume-api-key"
```
### Supported Stream Types
# JCPlayer Pro
- **Icecast**: `http://icecast.server.com:8000/stream`
- **Shoutcast**: `http://shoutcast.server.com:8000/stream`
- **Radiojar**: `https://stream.radiojar.com/stream`
- **Zeno**: `https://zeno.fm/stream`
#### ScreenShot
[![](https://i.ibb.co/41fgDTR/Screenshot-2024-10-16-at-1-00-39-PM.png
)](https://i.ibb.co/41fgDTR/Screenshot-2024-10-16-at-1-00-39-PM.png)
### API Configuration
[![](https://i.ibb.co/4RG2VWW/Screenshot-2024-10-16-at-1-01-00-PM.png)](https://i.ibb.co/4RG2VWW/Screenshot-2024-10-16-at-1-01-00-PM.png)
The player expects a JSON API response with the following structure:
[![](https://i.ibb.co/h7nFnL6/Screenshot-2024-10-16-at-1-01-08-PM.png)](https://i.ibb.co/h7nFnL6/Screenshot-2024-10-16-at-1-01-08-PM.png)
```json
{
"title": "Song Title",
"artist": "Artist Name",
"art": "https://album-art-url.com/cover.jpg",
"history": [
{
"song": "Previous Song",
"artist": "Previous Artist",
"artwork": "https://previous-artwork-url.com/cover.jpg"
}
]
}
```
## 🎮 Keyboard Shortcuts
## Features
1. Display Now Playing Song Info (Artwork, Artist, Year, Genre)
2. Free Control Panel to manage everything.
3. Supports Fetching Song Info From Itunes, Deezer, Spotify, Tidal, Youtube Music, Azuracast API, Live 365 API, RadioKing API & Many More
4. Supports HLS & Any Shoutcast/Icecast Compatible Stream.
5. Displays Last 5 Played Songs
6. Listeners Can Stream The Currently Playing Track On More Than 20 Streaming Services.
7. Supports Single Or Multi Radio Stations.
| Key | Action |
|-----|--------|
| `Space` or `P` | Play/Pause |
| `` | Volume Up |
| `` | Volume Down |
| `M` | Mute/Unmute |
| `0-9` | Set volume to 0-90% |
#### Price
199$ One Time Price.
## 🎨 Customization
#### Demo.
- [JC Player Pro Demo](http://341cf564-b130-4db6-bd67-ede75af533c2.player.joeycast.com "JC Player Pro Demo")
### Styling
#### Purchase URL.
[Buy JCPlayer Pro](https://spp.joeycast.com/store/jcplayer/jcplayer-pro/4)
The player uses CSS custom properties for easy theming. Edit `css/style.css` to customize:
```css
:root {
--primary-color: #1db954;
--secondary-color: #191414;
--text-color: #ffffff;
--background-color: #121212;
}
```
### History Items
## Feedback
To change the number of history items displayed:
If you have any feedback, please reach out to me at bankuboy@proton.me
1. Edit `js/script.js`
2. Modify the `HISTORY_ITEMS_COUNT` constant in `initializeHistoryItems()`
```javascript
const HISTORY_ITEMS_COUNT = 10 // Change from 5 to desired number
```
## License
## 📱 Browser Support
[MIT](https://github.com/gsavio/player-shoutcast-html5/blob/master/LICENSE)
- ✅ Chrome 60+
- ✅ Firefox 55+
- ✅ Safari 12+
- ✅ Edge 79+
## Credits
* [gsavio/player-shoutcast-html5](https://github.com/gsavio/player-shoutcast-html5)
* [Streamafrica's RadioAPI](https://api.streamafrica.net/)
## 🔧 Development
### Project Structure
```
radio-player/
├── css/
│ ├── animate.css # Animation library
│ ├── bootstrap.min.css # Bootstrap framework
│ ├── font-awesome.min.css # Icon library
│ └── style.css # Custom styles
├── fonts/ # Font Awesome fonts
├── img/ # Images and artwork
├── js/
│ ├── bootstrap.min.js # Bootstrap JavaScript
│ └── script.js # Main application logic
├── index.html # Main HTML file
├── package.json # Dependencies
└── README.md # This file
```
### Key Functions
- `Page()` - Handles UI updates and DOM manipulation
- `Player()` - Manages audio playback and controls
- `getStreamingData()` - Fetches metadata from API
- `initializeHistoryItems()` - Dynamically generates history items
## 🌐 API Integration
### Vagalume Lyrics API
To enable lyrics functionality:
1. Visit [Vagalume API](https://api.vagalume.com.br/docs/)
2. Get your API key
3. Update the `API_KEY` constant in `js/script.js`
### Custom Metadata API
The player expects a REST API endpoint that returns JSON metadata. Implement your own API or use services like:
- RadioAPI.me
- Radio Browser API
- Custom Icecast metadata parser
## 🐛 Troubleshooting
### Common Issues
**Stream not playing:**
- Check if the stream URL is accessible
- Verify CORS settings on your server
- Ensure the stream format is supported
**Metadata not updating:**
- Verify API endpoint is working
- Check browser console for errors
- Ensure API response format matches expected structure
**Lyrics not showing:**
- Verify Vagalume API key is valid
- Check if song/artist exists in Vagalume database
- Ensure API requests are not blocked by CORS
### Debug Mode
Enable debug logging by opening browser console and looking for:
- API response data
- Stream connection status
- Error messages
## 📄 License
This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.
## 🤝 Contributing
1. Fork the repository
2. Create a feature branch (`git checkout -b feature/amazing-feature`)
3. Commit your changes (`git commit -m 'Add amazing feature'`)
4. Push to the branch (`git push origin feature/amazing-feature`)
5. Open a Pull Request
## 🙏 Acknowledgments
- [Bootstrap](https://getbootstrap.com/) - CSS framework
- [Font Awesome](https://fontawesome.com/) - Icons
- [Animate.css](https://animate.style/) - Animations
- [Vagalume](https://www.vagalume.com.br/) - Lyrics API
## 📞 Support
If you need help or have questions:
- Create an [issue](https://github.com/yourusername/radio-player/issues)
- Check the [documentation](https://github.com/yourusername/radio-player/wiki)
- Join our [Discord community](https://discord.gg/your-community)
---
Made with ❤️ for radio lovers everywhere

La diferencia del archivo ha sido suprimido porque es demasiado grande Cargar Diff

Archivo binario no mostrado.

Ver fichero

@@ -7,137 +7,130 @@
<title>RadioPlayer</title>
<link rel="icon" type="image/png" href="img/cover.png" />
<link rel="stylesheet" href="css/font-awesome.min.css">
<link rel="stylesheet" type="text/css" href="css/animate.css">
<link rel="stylesheet" href="css/style.css?v2322">
</head>
<body>
<div class="cover-site">
<div id="bgCover"></div>
<div class="bg-mask"></div>
</div>
<main>
<section id="player">
<div class="container">
<div class="row web-player">
<div class="col-12 col-lg-10">
<div class="row">
<div class="col-12 col-md-5">
<div class="cover-album">
<div id="currentCoverArt"></div>
<!-- Spotify-style Player Interface -->
<div class="player-interface">
<!-- Left Side: Artwork -->
<div class="player-left">
<div class="main-artwork">
<div id="currentCoverArt" class="loading-artwork-main">
<div class="artwork-loading-spinner"></div>
</div>
<div class="watermark"></div>
</div>
</div>
<div class="col-12 ml-md-auto col-md-6">
<div class="row">
<div class="col-12">
<div class="info-current-song">
<h2 id="currentSong" class="current-song text-uppercase">Song</h2>
<h3 id="currentArtist" class="current-artist text-captalize">Artist</h3>
</div>
</div>
<div class="col-12">
<!--
<div class="row">
<div class="play-pause col-12 col-md-2 text-center">
<i id="playerButton" class="fa fa-play-circle" onclick="togglePlay()"></i>
</div>
<div class="col-12 col-md-10 text-center">
<div class="row volume-control">
<div class="volume-icon col-1"><i class="fa fa-volume-up"></i></div>
<div class="volume-slide col-10 text-center"><input type="range" id="volume"
step="1" min="0" max="100" value="80"></div>
<div class="percentual-volume col-12">Volume <span id="volIndicator">...</span>%</div>
</div>
</div>
<div class="col-12 text-center call-lyrics">
<a href="#" class="lyrics" style="" data-target="#modalLyrics">VER LETRA</a>
</div>
</div>-->
<div class="row">
<div class="play-pause col-12 col-md-6 text-center">
<button class="btn-play" onclick="togglePlay()"><i id="playerButton" class="fa fa-play"></i> <span id="buttonPlay">PLAY</span></button>
</div>
</div>
<div class="row">
<div class="col-12 col-md-6 text-center">
<div class="row volume-control">
<div class="volume-icon col-1"><i class="fa fa-volume-up"></i></div>
<div class="volume-slide col-10 text-center"><input type="range" id="volume"
step="1" min="0" max="100" value="80"></div>
<div class="percentual-volume col-12">Volume <span id="volIndicator">...</span>%</div>
</div>
</div>
</div>
<div class="row">
<div class="col-12 col-md-6 text-center call-lyrics">
<a href="#" class="lyrics" style="" data-target="#modalLyrics">LYRICS</a>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="row historic">
<div class="col-12">
<h2>RECENTLY PLAYED</h2>
<div class="row" id="historicSong">
<article class="col-12 col-md-6">
<div class="cover-historic"></div>
<div class="music-info">
<div class="song">No Song</div>
<div class="artist">No Artist</div>
<!-- Right Side: Song Info and Controls -->
<div class="player-right">
<!-- Song Information -->
<div class="song-info">
<h2 id="currentSong" class="current-song">
<span class="song-skeleton">Loading...</span>
</h2>
<h3 id="currentArtist" class="current-artist">
<span class="artist-skeleton">Loading artist...</span>
</h3>
</div>
</article>
<article class="col-12 col-md-6">
<div class="cover-historic"></div>
<div class="music-info">
<div class="song">No Title</div>
<div class="artist">No Artist</div>
<!-- Player Controls -->
<div class="player-controls">
<button class="btn-play" onclick="togglePlay()">
<i id="playerButton" class="fa fa-play"></i>
<span id="buttonPlay">PLAY</span>
<div class="btn-loading-spinner"></div>
</button>
<div class="volume-control">
<div class="volume-icon">
<i class="fa fa-volume-up"></i>
</div>
<div class="volume-slide">
<input type="range" id="volume" step="1" min="0" max="100" value="80">
</div>
<div class="volume-indicator">
<span id="volIndicator">80</span>%
</div>
</div>
</article>
<div class="action-buttons">
<button class="btn-secondary" data-toggle="modal" data-target="#modalHistory">
<i class="fa fa-history"></i>
HISTORY
</button>
<a href="#" class="btn-secondary lyrics" data-target="#modalLyrics">
<i class="fa fa-file-text-o"></i>
LYRICS
<div class="lyrics-loading-dot"></div>
</a>
</div>
</div>
</div>
</div>
</div>
</section>
</main>
<!-- Lyrics Modal -->
<div class="modal fade" id="modalLyrics" tabindex="-1" role="dialog" aria-labelledby="lyricsSong" aria-hidden="true">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="lyricsSong">Lyrics</h5>
<button type="button" style="color: #fff" class="close" data-dismiss="modal" aria-label="Fechar">
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">&times;</span>
</button>
</div>
<div class="modal-body" id="lyric">
<div class="lyrics-loading">
<div class="lyrics-skeleton-line"></div>
<div class="lyrics-skeleton-line"></div>
<div class="lyrics-skeleton-line short"></div>
<div class="lyrics-skeleton-line"></div>
<div class="lyrics-skeleton-line short"></div>
</div>
</div>
</div>
</div>
</div>
<div class="modal-body" id="lyric"></div>
<div class="modal-footer">
<button type="button" class="btn btn-success" data-dismiss="modal">Close</button>
<!-- History Modal -->
<div class="modal fade" id="modalHistory" tabindex="-1" role="dialog" aria-labelledby="historyTitle" aria-hidden="true">
<div class="modal-dialog modal-lg" role="document">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="historyTitle">Recently Played</h5>
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">&times;</span>
</button>
</div>
<div class="modal-body">
<div class="history-list" id="historicSong">
<!-- History items will be generated dynamically -->
</div>
</div>
</div>
</div>
</div>
<script type="text/javascript" src="https://code.jquery.com/jquery-3.2.1.min.js"></script>
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.12.3/umd/popper.min.js"></script>
<script type="text/javascript" src="js/bootstrap.min.js"></script>
<script type="text/javascript" src="js/script.js?3892920001992"></script>
<script type="text/javascript" src="js/script.js?3892920001992"></script>
</body>
</html>

La diferencia del archivo ha sido suprimido porque es demasiado grande Cargar Diff

8
package.json Archivo normal
Ver fichero

@@ -0,0 +1,8 @@
{
"name": "my-v0-project",
"version": "0.1.0",
"private": true,
"scripts": {
"build": "echo 'no build script'"
}
}

9
pnpm-lock.yaml generado Archivo normal
Ver fichero

@@ -0,0 +1,9 @@
lockfileVersion: '9.0'
settings:
autoInstallPeers: true
excludeLinksFromLockfile: false
importers:
.: {}