PageSourceSearch

https://superdjradio.hu/assets/js/radioplayer-selector.js?v=2026100104

js superdjradio.hu collected 2026-10-08 09:22:26 UTC 16,791 bytes, 351 lines download raw bytes

1// --- Kombinált, régi és új logika: minden funkció működik, csatornaváltáskor minden UI frissül ---
2
3$(document).ready(function () {
4    const audio = document.getElementById('radio-player');
5    const apiKey = '9e84032a429186dc2ccc2538a6c632b7';
6    const defaultCover = 'assets/images/logosdr.png';
7
8    // Csatorna API-k (playlist és info)
9    const channelInfo = {
10        "1": {
11            stream: "https://s03.diazol.hu:35152/stream",
12            info: "https://s03.diazol.hu:633/api/info.cgi?user=superdjradio&streamid=1&mount=%2Fstream&out=json",
13            playlist: "https://s03.diazol.hu:633/api/playlist.cgi?user=superdjradio&streamid=1&mount=%2Fstream&num=10&out=json"
14        },
15        "2": {
16            stream: "https://s03.diazol.hu:35152/stream2",
17            info: "https://s03.diazol.hu:633/api/info.cgi?user=superdjradio&streamid=5&mount=%2Fstream2&out=json",
18            playlist: "https://s03.diazol.hu:633/api/playlist.cgi?user=superdjradio&streamid=5&mount=%2Fstream2&num=10&out=json"
19        },
20        "3": {
21            stream: "https://s03.diazol.hu:35152/stream3",
22            info: "https://s03.diazol.hu:633/api/info.cgi?user=superdjradio&streamid=9&mount=%2Fstream3&out=json",
23            playlist: "https://s03.diazol.hu:633/api/playlist.cgi?user=superdjradio&streamid=9&mount=%2Fstream3&num=10&out=json"
24        },
25        "4": {
26            stream: "https://s03.diazol.hu:35152/stream4",
27            info: "https://s03.diazol.hu:633/api/info.cgi?user=superdjradio&streamid=13&mount=%2Fstream4&out=json",
28            playlist: "https://s03.diazol.hu:633/api/playlist.cgi?user=superdjradio&streamid=13&mount=%2Fstream4&num=10&out=json"
29        }
30    };
31
32    let currentChannel = "1";
33    let infoInterval = null;
34
35    // --- UI vezérlés (hangerő, play/pause, sticky) ---
36    $('#play-btn, #sticky-play-btn').click(function () {
37        if (audio.paused) {
38            audio.play();
39        } else {
40            audio.pause();
41        }
42    });
43
44    // A play/szünet ikon a hangelem tényleges állapotát követi
45    function syncPlayIcons() {
46        const playing = !audio.paused && !audio.error;
47        $('#play-btn i, #sticky-play-btn i').toggleClass('fa-pause', playing).toggleClass('fa-play', !playing);
48    }
49    $(audio).on('play pause ended error', syncPlayIcons);
50
51    // Az alsó lejátszó csak akkor látszik, ha a felső már kigördült a képből
52    let stickyCollapsed = true; // az első lejátszásig rejtve marad
53    let topPlayerVisible = true;
54
55    function updateStickyPlayer() {
56        $('#sticky-radio-player').toggleClass('d-none', stickyCollapsed || topPlayerVisible);
57        $('#toggle-sticky-player').toggleClass('d-none', topPlayerVisible)
58            .find('i').toggleClass('fa-chevron-down', !stickyCollapsed).toggleClass('fa-headphones', stickyCollapsed);
59    }
60
61    new IntersectionObserver(function (entries) {
62        topPlayerVisible = entries[0].isIntersecting;
63        updateStickyPlayer();
64    }).observe(document.querySelector('.radio-player'));
65
66    $(audio).on('play', function () {
67        stickyCollapsed = false;
68        updateStickyPlayer();
69    });
70
71    $('#toggle-sticky-player').click(function () {
72        stickyCollapsed = !stickyCollapsed;
73        updateStickyPlayer();
74    });
75
76    // A két hangerőszabályzó együtt mozog
77    $('#volume-control').hide();
78    $('#volume-btn').click(function () {
79        $('#volume-control').toggle();
80    });
81
82    $('#sticky-volume-control').hide();
83    $('#sticky-volume-btn').click(function () {
84        $('#sticky-volume-control').toggle();
85    });
86
87    $('#volume-slider, #sticky-volume-slider').on('input', function () {
88        audio.volume = $(this).val();
89    });
90    $(audio).on('volumechange', function () {
91        $('#volume-slider, #sticky-volume-slider').val(audio.volume);
92    });
93
94    // Az adatforrás az ékezetes címeket néha hibás kódolással adja („í" az „í" helyett);
95    // ezt visszaalakítjuk, a jó szöveget pedig érintetlenül hagyjuk
96    function fixEncoding(text) {
97        try {
98            return decodeURIComponent(escape(text));
99        } catch (e) {
100            return text;
101        }
102    }
103
104    // Ha a kapott borító nem tölthető be, a rádió logója marad a lejátszókban
105    $('#album-cover-img, #sticky-album-cover').on('error', function () {
106        if (!this.src.endsWith(defaultCover)) this.src = defaultCover;
107    });
108
109    // --- Dalcím, előadó, borítókép frissítése ---
110    // Playlist API-t használunk, hogy mindig a ténylegesen játszott dal jelenjen meg (és ne sweeper vagy azonosító)
111    function updatePlayerInfo(channelId) {
112        const playlistUrl = channelInfo[channelId].playlist;
113        $.ajax({
114            url: playlistUrl,
115            dataType: 'json',
116            cache: false,
117            success: function (data) {
118                // Keressük az első valódi dalt (artist és title nem üres, title nem sweeper/superdjradio)
119                let song = null;
120                if (data.mscp && Array.isArray(data.mscp.playlist)) {
121                    song = data.mscp.playlist.find(item =>
122                        item.title &&
123                        item.title.trim() !== '' &&
124                        !/^sweeper/i.test(item.title) &&
125                        !/^superdjradio/i.test(item.title)
126                    );
127                }
128                const title = song && song.title ? fixEncoding(song.title) : 'Ismeretlen szám';
129                const artist = song && song.artist ? fixEncoding(song.artist) : 'Ismeretlen előadó';
130                $('#song-title').text(title);
131                $('#artist-name').text(artist);
132                $('#sticky-song-title').text(title);
133                $('#sticky-artist-name').text(artist);
134
135                // Borítókép Last.fm-ről
136                $.getJSON(`https://ws.audioscrobbler.com/2.0/?method=track.getInfo&api_key=${apiKey}&artist=${encodeURIComponent(artist)}&track=${encodeURIComponent(title)}&format=json`, function (trackData) {
137                    let albumCover = defaultCover;
138                    if (trackData.track && trackData.track.album && trackData.track.album.image) {
139                        const coverImage = trackData.track.album.image.find(img => img.size === 'large');
140                        if (coverImage && coverImage['#text']) {
141                            albumCover = coverImage['#text'];
142                        }
143                    }
144                    $('#album-cover-img').attr('src', albumCover);
145                    $('#sticky-album-cover').attr('src', albumCover);
146                }).fail(function () {
147                    $('#album-cover-img').attr('src', defaultCover);
148                    $('#sticky-album-cover').attr('src', defaultCover);
149                });
150            },
151            error: function () {
152                $('#song-title').text('Ismeretlen szám');
153                $('#artist-name').text('Ismeretlen előadó');
154                $('#album-cover-img').attr('src', defaultCover);
155                $('#sticky-album-cover').attr('src', defaultCover);
156            }
157        });
158    }
159
160    function startInfoPolling(channelId) {
161        if (infoInterval) clearInterval(infoInterval);
162        updatePlayerInfo(channelId);
163        infoInterval = setInterval(function () {
164            updatePlayerInfo(channelId);
165        }, 10000);
166    }
167
168    // --- Nem rég szólt nálunk dinamikus frissítése borítóképpel ---
169    let playlistInterval = null;
170    let lastRecentSongs = [];
171
172    function updateRecentSongs(channelId) {
173        const playlistUrl = channelInfo[channelId].playlist;
174        fetch(playlistUrl)
175            .then(response => response.json())
176            .then(data => {
177                // Csak az utolsó 3 zene kell, a most szólót kihagyva
178                const playlist = (data.mscp && Array.isArray(data.mscp.playlist)) ? data.mscp.playlist.slice(1, 4) : [];
179                const currentSongs = playlist.map(song => ({
180                    title: song.title || 'Ismeretlen szám',
181                    artist: song.artist || 'Ismeretlen előadó',
182                    time: song.time || '',
183                }));
184
185                const recentSongsContainer = document.getElementById('recent-songs');
186                if (!recentSongsContainer) return;
187
188                // Ellenőrizzük, hogy változott-e a tartalom (visszanavigálás után a konténer üres)
189                if (JSON.stringify(currentSongs) === JSON.stringify(lastRecentSongs) && recentSongsContainer.children.length) {
190                    // Nem változott, ne frissítsük a DOM-ot
191                    return;
192                }
193                lastRecentSongs = currentSongs;
194
195                recentSongsContainer.innerHTML = '';
196
197                playlist.forEach(song => {
198                    const title = fixEncoding(song.title || 'Ismeretlen szám');
199                    const artist = fixEncoding(song.artist || 'Ismeretlen előadó');
200                    // Az időből elég az óra és a perc (17:41:35 -> 17:41)
201                    const time = (song.time || '').replace(/^(\d{1,2}:\d{2}):\d{2}$/, '$1');
202                    const defaultCover = 'assets/images/logosdr.png';
203
204                    // Kártya létrehozása alapértelmezett borítóval
205                    const card = document.createElement('div');
206                    card.className = 'col-md-4';
207                    card.innerHTML = `
208                        <div class="card bg-dark text-white h-100 shadow recent-song-card">
209                            <img src="${defaultCover}" alt="Borítókép" class="card-img-top recent-cover-img" style="max-height:200px;object-fit:cover;">
210                            <div class="card-body">
211                                <h5 class="card-title">${title}</h5>
212                                <p class="card-text">${artist}</p>
213                                <small class="text-muted">${time}</small>
214                            </div>
215                        </div>
216                    `;
217                    recentSongsContainer.appendChild(card);
218
219                    // Borítókép aszinkron betöltése Last.fm-ről
220                    $.getJSON(`https://ws.audioscrobbler.com/2.0/?method=track.getInfo&api_key=${apiKey}&artist=${encodeURIComponent(artist)}&track=${encodeURIComponent(title)}&format=json`, function (trackData) {
221                        let albumCover = defaultCover;
222                        if (trackData.track && trackData.track.album && trackData.track.album.image) {
223                            const coverImage = trackData.track.album.image.find(img => img.size === 'large');
224                            if (coverImage && coverImage['#text']) {
225                                albumCover = coverImage['#text'];
226                            }
227                        }
228                        const img = card.querySelector('.recent-cover-img');
229                        if (img) img.src = albumCover;
230                    }).fail(function () {
231                        // Ha nincs borító, marad az alapértelmezett
232                    });
233                });
234            })
235            .catch(error => {
236                console.error('Error fetching recent songs:', error);
237            });
238    }
239
240    function startPlaylistPolling(channelId) {
241        if (playlistInterval) clearInterval(playlistInterval);
242        updateRecentSongs(channelId);
243        playlistInterval = setInterval(function () {
244            updateRecentSongs(channelId);
245        }, 10000);
246    }
247
248    // --- Csatornaváltás ---
249    function switchChannel(streamId) {
250        audio.src = channelInfo[streamId].stream;
251        audio.play();
252        currentChannel = streamId;
253        startInfoPolling(currentChannel);
254
255        // Az alsó lejátszó gombján a kiválasztott csatorna neve
256        const menuItem = $('.dropdown-item[data-streamid="' + streamId + '"]').first();
257        $('#sticky-channel-name').text(menuItem.text().replace('🎧', '').trim());
258
259        // Nem rég szólt nálunk frissítése
260        startPlaylistPolling(currentChannel);
261        updateChannelCards();
262    }
263
264    $('.dropdown-item[data-streamid]').click(function (e) {
265        e.preventDefault();
266        switchChannel($(this).attr('data-streamid') || "1");
267    });
268
269    // --- Kezdőlapi csatornakártyák ---
270    // A kártyák a tartalommal együtt cserélődnek, ezért delegált eseménykezelés kell
271    $(document).on('click', '.channel-play', function () {
272        const streamId = String($(this).data('streamid'));
273        if (streamId !== currentChannel) {
274            switchChannel(streamId);
275        } else if (audio.paused) {
276            audio.play();
277        } else {
278            audio.pause();
279        }
280    });
281
282    // Az éppen szóló csatorna kártyája kiemelve, a gombja szünetre vált
283    function updateChannelCards() {
284        const playing = !audio.paused && !audio.error;
285        $('.channel-card').each(function () {
286            const active = playing && String($(this).data('streamid')) === currentChannel;
287            $(this).toggleClass('is-playing', active);
288            $(this).find('.channel-play i').toggleClass('fa-pause', active).toggleClass('fa-play', !active);
289            $(this).find('.channel-play span').text(active ? 'Szünet' : 'Hallgatom');
290        });
291    }
292    $(audio).on('play pause ended error', updateChannelCards);
293
294    // Mindegyik kártyán az adott csatornán éppen szóló dal
295    function updateChannelSongs() {
296        $('.channel-card').each(function () {
297            const card = $(this);
298            fetch(channelInfo[String(card.data('streamid'))].playlist)
299                .then(response => response.json())
300                .then(data => {
301                    const playlist = (data.mscp && Array.isArray(data.mscp.playlist)) ? data.mscp.playlist : [];
302                    const song = playlist.find(item =>
303                        item.title &&
304                        item.title.trim() !== '' &&
305                        !/^sweeper/i.test(item.title) &&
306                        !/^superdjradio/i.test(item.title)
307                    );
308                    const title = song ? fixEncoding(song.title) : 'Ismeretlen szám';
309                    const artist = song && song.artist ? fixEncoding(song.artist) : '';
310                    card.find('.channel-song-title').text(title);
311                    card.find('.channel-song-artist').text(artist);
312
313                    // Borítót csak akkor kérünk újra, ha a dal megváltozott
314                    const songKey = title + '|' + artist;
315                    if (card.data('song') === songKey) return;
316                    card.data('song', songKey);
317
318                    const cover = card.find('.channel-cover');
319                    // Ha a kapott kép nem tölthető be, marad a rádió logója
320                    cover.off('error').on('error', function () {
321                        if (!this.src.endsWith(defaultCover)) this.src = defaultCover;
322                    });
323                    $.getJSON(`https://ws.audioscrobbler.com/2.0/?method=track.getInfo&api_key=${apiKey}&artist=${encodeURIComponent(artist)}&track=${encodeURIComponent(title)}&format=json`, function (trackData) {
324                        let albumCover = defaultCover;
325                        if (trackData.track && trackData.track.album && trackData.track.album.image) {
326                            const coverImage = trackData.track.album.image.find(img => img.size === 'large');
327                            if (coverImage && coverImage['#text']) {
328                                albumCover = coverImage['#text'];
329                            }
330                        }
331                        cover.attr('src', albumCover);
332                    }).fail(function () {
333                        cover.attr('src', defaultCover);
334                    });
335                })
336                .catch(error => console.error('Error fetching channel song:', error));
337        });
338    }
339    setInterval(updateChannelSongs, 10000);
340
341    // A main.js hívja meg, amikor a kezdőlap tartalma újra betöltődik
342    window.refreshChannelCards = function () {
343        updateChannelCards();
344        updateChannelSongs();
345    };
346
347    // --- Induláskor az alapértelmezett csatorna info és playlist polling ---
348    startInfoPolling(currentChannel);
349    startPlaylistPolling(currentChannel);
350    window.refreshChannelCards();
351});

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.