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 - **🎧 Live Streaming**: Supports multiple streaming protocols (Icecast, Zeno, Shoutcast, Radiojar)
// RADIO NAME - **🎨 Modern UI**: Spotify-inspired interface with smooth animations
const RADIO_NAME = 'Game! Radio 1'; - **📱 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 ## 🚀 Quick Start
var API_SERVICE = 'DEEZER';
// Change Stream URL Here, Supports, ICECAST, ZENO, SHOUTCAST, RADIOJAR and any other stream service. ### Prerequisites
const URL_STREAMING = 'https://stream-51.zeno.fm/cfhkm5fs1uhvv?zs=HOu6hxV1SG-7iGi9WGVTqQ';
//API URL GET API On Joeycast Website - A modern web browser (Chrome, Firefox, Safari, Edge)
const API_URL = 'https://api-v2.streamafrica.net/icyv2?url=' + URL_STREAMING; - 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) # Using Node.js
[![Deploy to Netlify](https://www.netlify.com/img/deploy/button.svg)](https://app.netlify.com/start/deploy?repository=https://github.com/joeyboli/RadioPlayer/) 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 // API endpoint for metadata
* Icecast / Shoutcast const API_URL = "https://your-api-endpoint.com/metadata"
* Zeno Radio
* RadioJar
* Azuracast
* Centova Cast
* Everest Cast
* MediaCP
* Sonic Panel
## Supported API/Data Sources // Vagalume API key for lyrics (optional)
* Apple Music / Itunes const API_KEY = "your-vagalume-api-key"
* Deezer ```
* Spotify
### 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 ### API Configuration
[![](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)
[![](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 | Key | Action |
1. Display Now Playing Song Info (Artwork, Artist, Year, Genre) |-----|--------|
2. Free Control Panel to manage everything. | `Space` or `P` | Play/Pause |
3. Supports Fetching Song Info From Itunes, Deezer, Spotify, Tidal, Youtube Music, Azuracast API, Live 365 API, RadioKing API & Many More | `` | Volume Up |
4. Supports HLS & Any Shoutcast/Icecast Compatible Stream. | `` | Volume Down |
5. Displays Last 5 Played Songs | `M` | Mute/Unmute |
6. Listeners Can Stream The Currently Playing Track On More Than 20 Streaming Services. | `0-9` | Set volume to 0-90% |
7. Supports Single Or Multi Radio Stations.
#### Price ## 🎨 Customization
199$ One Time Price.
#### Demo. ### Styling
- [JC Player Pro Demo](http://341cf564-b130-4db6-bd67-ede75af533c2.player.joeycast.com "JC Player Pro Demo")
#### Purchase URL. The player uses CSS custom properties for easy theming. Edit `css/style.css` to customize:
[Buy JCPlayer Pro](https://spp.joeycast.com/store/jcplayer/jcplayer-pro/4)
```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 ## 🔧 Development
* [gsavio/player-shoutcast-html5](https://github.com/gsavio/player-shoutcast-html5)
* [Streamafrica's RadioAPI](https://api.streamafrica.net/)
### 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> <title>RadioPlayer</title>
<link rel="icon" type="image/png" href="img/cover.png" /> <link rel="icon" type="image/png" href="img/cover.png" />
<link rel="stylesheet" href="css/font-awesome.min.css"> <link rel="stylesheet" href="css/font-awesome.min.css">
<link rel="stylesheet" type="text/css" href="css/animate.css"> <link rel="stylesheet" type="text/css" href="css/animate.css">
<link rel="stylesheet" href="css/style.css?v2322"> <link rel="stylesheet" href="css/style.css?v2322">
</head> </head>
<body> <body>
<div class="cover-site"> <div class="cover-site">
<div id="bgCover"></div> <div id="bgCover"></div>
<div class="bg-mask"></div> <div class="bg-mask"></div>
</div> </div>
<main> <main>
<section id="player"> <section id="player">
<div class="container"> <div class="container">
<div class="row web-player"> <!-- Spotify-style Player Interface -->
<div class="col-12 col-lg-10"> <div class="player-interface">
<div class="row"> <!-- Left Side: Artwork -->
<div class="col-12 col-md-5"> <div class="player-left">
<div class="cover-album"> <div class="main-artwork">
<div id="currentCoverArt"></div> <div id="currentCoverArt" class="loading-artwork-main">
<div class="artwork-loading-spinner"></div>
</div>
<div class="watermark"></div> <div class="watermark"></div>
</div> </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"> <!-- Right Side: Song Info and Controls -->
<div class="play-pause col-12 col-md-6 text-center"> <div class="player-right">
<button class="btn-play" onclick="togglePlay()"><i id="playerButton" class="fa fa-play"></i> <span id="buttonPlay">PLAY</span></button> <!-- Song Information -->
<div class="song-info">
</div> <h2 id="currentSong" class="current-song">
</div> <span class="song-skeleton">Loading...</span>
<div class="row"> </h2>
<div class="col-12 col-md-6 text-center"> <h3 id="currentArtist" class="current-artist">
<div class="row volume-control"> <span class="artist-skeleton">Loading artist...</span>
<div class="volume-icon col-1"><i class="fa fa-volume-up"></i></div> </h3>
<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>
</div> </div>
</article> <!-- Player Controls -->
<article class="col-12 col-md-6"> <div class="player-controls">
<div class="cover-historic"></div> <button class="btn-play" onclick="togglePlay()">
<div class="music-info"> <i id="playerButton" class="fa fa-play"></i>
<div class="song">No Title</div> <span id="buttonPlay">PLAY</span>
<div class="artist">No Artist</div> <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> </div>
<div class="action-buttons">
</article> <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>
</div> </div>
</div> </div>
</section> </section>
</main> </main>
<!-- Lyrics Modal -->
<div class="modal fade" id="modalLyrics" tabindex="-1" role="dialog" aria-labelledby="lyricsSong" aria-hidden="true"> <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-dialog" role="document">
<div class="modal-content"> <div class="modal-content">
<div class="modal-header"> <div class="modal-header">
<h5 class="modal-title" id="lyricsSong">Lyrics</h5> <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> <span aria-hidden="true">&times;</span>
</button> </button>
</div> </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> <!-- History Modal -->
<div class="modal-footer"> <div class="modal fade" id="modalHistory" tabindex="-1" role="dialog" aria-labelledby="historyTitle" aria-hidden="true">
<button type="button" class="btn btn-success" data-dismiss="modal">Close</button> <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> </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://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="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/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> </body>
</html> </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:
.: {}