PageSourceSearch

https://www.radiogrenouille.com/wp-content/themes/astra-child/components/audio-player/assets/script.js

js radiogrenouille.com collected 2026-09-24 09:10:36 UTC 18,324 bytes, 689 lines download raw bytes

1(function ($) {
2
3    window.RGPlayer = {
4
5        liveUrl: 'https://live.radiogrenouille.com:8443/live',
6
7        mode: 'live',
8
9        audio: null,
10
11        mobilePlayerOpen: true,
12
13        init() {
14
15            this.audio = document.getElementById('rg-audio');
16
17            if (!this.audio) {
18                console.error('RGPlayer : audio introuvable');
19                return;
20            }
21
22            this.bindEvents();
23
24            this.initMarquee();
25
26            this.updateLiveTitle();
27
28            setInterval(() => {
29                this.updateLiveTitle();
30            }, 30000);
31
32            console.log('RGPlayer initialisé');
33
34        },
35
36        bindEvents() {
37
38            const self = this;
39
40            this.updateProgressLayout();
41
42            $(window).on('resize', function () {
43                self.updateProgressLayout();
44            });
45
46
47            // Bouton LIVE
48            $('.rg-live-button, .mobile-live').on('click', function () {
49
50                console.log('click');
51
52                self.playLive();
53
54            });
55
56            // Lecture
57            this.audio.addEventListener('play', function () {
58
59                $('#rg-player').addClass('is-playing');
60
61                self.showPlayer();
62
63                if (self.mode === 'live') {
64                    $('.rg-live-status').addClass('is-live');
65                    $('.rg-live-button').html('<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="20.64" height="25" x="0px" y="0px" viewBox="0 0 17.5 21.2" xml:space="preserve" fill="#272727"><rect width="6" height="21.2"></rect><rect x="11.5" width="6" height="21.2"></rect></svg> Pause');
66                    $('.mobile-live')
67                        .html('<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="20.64" height="25" x="0px" y="0px" viewBox="0 0 17.5 21.2" xml:space="preserve" fill="#272727"><rect width="6" height="21.2"></rect><rect x="11.5" width="6" height="21.2"></rect></svg> Pause')
68                        .addClass('is-playing');
69                }
70
71                $('.rg-play').html('<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="20.64" height="25" x="0px" y="0px" viewBox="0 0 17.5 21.2" xml:space="preserve" fill="#bbbcbf"><rect width="6" height="21.2"></rect><rect x="11.5" width="6" height="21.2"></rect></svg>');
72
73                self.updateCardsState();
74
75                if (self.mode === "podcast" && self.currentPodcast) {
76
77                    document.dispatchEvent(
78                        new CustomEvent("podcastPlay", {
79                            detail: self.currentPodcast
80                        })
81                    );
82
83                }
84
85
86            });
87
88
89            // Pause
90            this.audio.addEventListener('pause', function () {
91
92                $('#rg-player').removeClass('is-playing');
93
94                $('.rg-live-status').removeClass('is-live');
95
96                $('.rg-live-button').html('<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 640 640"><path fill="#272727" d="M187.2 100.9C174.8 94.1 159.8 94.4 147.6 101.6C135.4 108.8 128 121.9 128 136L128 504C128 518.1 135.5 531.2 147.6 538.4C159.7 545.6 174.8 545.9 187.2 539.1L523.2 355.1C536 348.1 544 334.6 544 320C544 305.4 536 291.9 523.2 284.9L187.2 100.9z"></path></svg> Écouter')
97                $('.rg-play').html('<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="20.64" height="25" x="0px" y="0px" viewBox="0 0 17.5 21.2" xml:space="preserve" fill="#bbbcbf"><path d="M0,0l17.5,10.9L0,21.2V0z"></path></svg>');
98                $('.mobile-live')
99                    .html('<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 640 640"><path fill="#272727" d="M187.2 100.9C174.8 94.1 159.8 94.4 147.6 101.6C135.4 108.8 128 121.9 128 136L128 504C128 518.1 135.5 531.2 147.6 538.4C159.7 545.6 174.8 545.9 187.2 539.1L523.2 355.1C536 348.1 544 334.6 544 320C544 305.4 536 291.9 523.2 284.9L187.2 100.9z"></path></svg> Écouter')
100                    .removeClass('is-playing');
101
102                $('.play-button-mask').addClass('pause');
103
104                $('.audio').removeClass('pause');
105
106                if (self.mode === "podcast" && self.currentPodcast) {
107
108                    document.dispatchEvent(
109                        new CustomEvent("podcastPause", {
110                            detail: self.currentPodcast
111                        })
112                    );
113
114                }
115
116
117            });
118
119            $('.rg-progress-hitbox').on('click', function (e) {
120
121                if (!self.audio.duration) {
122                    return;
123                }
124
125                const rect = this.getBoundingClientRect();
126
127                const x = e.clientX - rect.left;
128
129                const percent = Math.max(
130                    0,
131                    Math.min(1, x / rect.width)
132                );
133
134                self.audio.currentTime = percent * self.audio.duration;
135
136                self.updateProgress();
137
138            });
139
140            $('.rg-volume-hitbox').on('click', function (e) {
141
142                const rect = this.getBoundingClientRect();
143
144                const y = rect.bottom - e.clientY;
145
146                const volume = Math.max(
147                    0,
148                    Math.min(1, y / rect.height)
149                );
150
151                RGPlayer.audio.volume = volume;
152
153                RGPlayer.updateVolume();
154
155            });
156
157
158
159
160
161
162            // Fin
163            this.audio.addEventListener('ended', function () {
164
165                $('#rg-player').removeClass('is-playing');
166
167                $('.rg-live-status').removeClass('is-live');
168
169                $('.rg-play').text('▶');
170
171            });
172
173            $('.rg-play').on('click', function () {
174
175                self.toggle();
176
177            });
178
179
180            $('.rg-back15').on('click', function () {
181
182                self.audio.currentTime -= 15;
183
184            });
185
186
187            $('.rg-forward15').on('click', function () {
188
189                self.audio.currentTime += 15;
190
191            });
192
193            this.audio.addEventListener('timeupdate', function () {
194
195                $('.rg-current').text(
196                    self.formatTime(self.audio.currentTime)
197                );
198
199                self.updateProgress();
200
201                if (self.mode === "podcast" && self.currentPodcast) {
202
203                    document.dispatchEvent(
204                        new CustomEvent("podcastProgress", {
205                            detail: {
206                                source: self.currentPodcast.source,
207                                percent:
208                                    (self.audio.currentTime / self.audio.duration) * 100
209                            }
210                        })
211                    );
212
213                }
214
215
216            });
217
218
219
220            this.audio.addEventListener('loadedmetadata', function () {
221
222                if (self.audio.duration != 'Infinity') {
223                    $('.rg-duration').text(
224                        self.formatTime(self.audio.duration)
225                    );
226                }
227
228            });
229
230            let draggingProgress = false;
231
232            $('.rg-progress-hitbox, .rg-progress-dot').on('pointerdown', function (e) {
233
234                if (!self.audio.duration) return;
235
236                draggingProgress = true;
237
238                updateProgressFromPointer(e);
239
240            });
241
242            $(document).on('pointermove', function (e) {
243
244                if (!draggingProgress) return;
245
246                updateProgressFromPointer(e);
247
248            });
249
250            $(document).on('pointerup pointercancel', function () {
251
252                draggingProgress = false;
253
254            });
255
256            function updateProgressFromPointer(e) {
257
258                const rect = $('.rg-progress-hitbox')[0].getBoundingClientRect();
259
260                const x = e.clientX - rect.left;
261
262                const percent = Math.max(
263                    0,
264                    Math.min(1, x / rect.width)
265                );
266
267                self.audio.currentTime = percent * self.audio.duration;
268
269                self.updateProgress();
270
271            }
272
273            let draggingVolume = false;
274
275            $('.rg-volume-hitbox, .rg-volume-thumb').on('pointerdown', function (e) {
276
277                draggingVolume = true;
278
279                updateVolumeFromPointer(e);
280
281            });
282
283            $(document).on('pointermove', function (e) {
284
285                if (!draggingVolume) return;
286
287                updateVolumeFromPointer(e);
288
289            });
290
291            $(document).on('pointerup pointercancel', function () {
292
293                draggingVolume = false;
294
295            });
296
297            function updateVolumeFromPointer(e) {
298
299                const rect = $('.rg-volume-hitbox')[0].getBoundingClientRect();
300
301                const y = rect.bottom - e.clientY;
302
303                const volume = Math.max(
304                    0,
305                    Math.min(1, y / rect.height)
306                );
307
308                self.audio.volume = volume;
309
310                self.updateVolume();
311
312            }
313
314            $('.rg-progress-dot, .rg-volume-thumb').on('pointerdown', function (e) {
315                this.setPointerCapture(e.pointerId);
316            });
317
318            $('.toggle-mobile').on('click', function () {
319
320                if ($('#header-player').hasClass('mobile-open')) {
321                    self.hidePlayer();
322                } else {
323                    self.showPlayer();
324                }
325
326            });
327
328            document.addEventListener("openPodcastPlayer", (e) => {
329
330                const data = e.detail;
331
332                RGPlayer.playPodcast(data);
333
334            });
335
336
337
338
339
340        },
341
342        playLive() {
343
344            this.mode = 'live';
345
346            // Si le live est déjà chargé
347            if (this.audio.src === this.liveUrl) {
348
349                this.toggle();
350
351                return;
352
353            }
354
355            this.audio.src = this.liveUrl;
356
357            this.audio.load();
358
359            this.audio.play();
360
361            $('#rg-player')
362                .removeClass('mode-podcast')
363                .addClass('mode-live');
364
365        },
366
367        playPodcast(data) {
368
369            this.mode = 'podcast';
370
371            // Même podcast déjà chargé
372            if (
373                this.currentPodcast &&
374                this.currentPodcast.source === data.source &&
375                this.audio.src === data.audio
376            ) {
377
378                this.audio.play();
379
380                return;
381
382            }
383
384
385            // Nouveau podcast
386            this.currentPodcast = data;
387
388            this.audio.src = data.audio;
389            this.audio.load();
390
391            this.audio.play();
392
393            console.log('avant mode');
394
395            $('.mobile-live').removeClass('is-playing');
396
397            $('#rg-player')
398                .removeClass('mode-live')
399                .addClass('mode-podcast');
400
401            console.log('apres mode');
402
403            $('.rg-title').text(data.title);
404            $('.rg-category').text(data.category);
405            $('.rg-duration').text(data.duration);
406
407            this.initMarquee();
408
409            $('.rg-live-status')
410                .removeClass('is-live');
411
412
413            document.dispatchEvent(
414                new CustomEvent("podcastPlay", {
415                    detail: data
416                })
417            );
418
419        },
420
421
422
423
424
425        toggle() {
426
427            if (this.audio.paused) {
428
429                this.audio.play();
430
431            } else {
432
433                this.audio.pause();
434
435            }
436
437        },
438
439        initMarquee() {
440
441            $('.rg-title, .rg-live-title').each(function () {
442
443                const $el = $(this);
444
445                $el.off('.marquee');
446
447                $el.on('mouseenter.marquee', function () {
448
449                    // déjà en cours
450                    if ($el.hasClass('is-marquee')) {
451                        return;
452                    }
453
454                    // overflow ?
455                    if (this.scrollWidth <= this.clientWidth) {
456                        return;
457                    }
458
459                    $el.addClass('is-marquee');
460
461                    const text = $el.text();
462
463                    $el.html(`
464                        <div class="rg-title-marquee animate">
465                            <span>${text}</span>
466                            <span>${text}</span>
467                        </div>
468                    `);
469
470                    $el.find('.rg-title-marquee')
471                        .one('animationend', function () {
472
473                            $el.removeClass('is-marquee');
474                            $el.text(text);
475
476                        });
477
478                });
479
480            });
481
482        },
483
484
485        formatTime(seconds) {
486
487            if (!seconds || isNaN(seconds)) {
488                return '00:00';
489            }
490
491            let minutes = Math.floor(seconds / 60);
492            let secs = Math.floor(seconds % 60);
493
494            return (
495                String(minutes).padStart(2, '0') +
496                ':' +
497                String(secs).padStart(2, '0')
498            );
499
500        },
501
502        updateLiveTitle() {
503
504            const self = this;
505
506            $.ajax({
507                url: 'https://radiogrenouille.com/log/onAir.xml',
508                dataType: 'xml',
509                cache: false,
510                success(xml) {
511
512                    const artiste = $(xml).find('artiste').text().trim();
513                    const titre = $(xml).find('titre').text().trim();
514
515                    let text = titre;
516
517                    if (artiste) {
518                        text = artiste + ' — ' + titre;
519                    }
520
521                    if (text === self.liveTitle) {
522                        return;
523                    }
524
525                    self.liveTitle = text;
526
527                    $('.rg-live-title').text(text);
528
529                    self.initMarquee();
530
531                }
532            });
533
534        },
535
536
537
538        updateProgressLayout() {
539
540            const $header = $('#header-player');
541
542            if (!$header.length) {
543                return;
544            }
545
546            const left = $header.offset().left;
547            const width = window.innerWidth - left;
548
549            $('.rg-progress').css({
550                width: width + 'px'
551            });
552
553        },
554
555        updateVolume() {
556
557            const volume = this.audio.volume;
558            const percent = volume * 100;
559
560            $('.rg-volume-fill').css('height', percent + '%');
561            $('.rg-volume-thumb').css('bottom', percent + '%');
562
563        },
564
565
566
567        updateProgress() {
568
569            if (!this.audio.duration) {
570                return;
571            }
572
573            const percent = (this.audio.currentTime / this.audio.duration) * 100;
574
575            $('.rg-progress-bar').css('width', percent + '%');
576            $('.rg-progress-dot').css('left', percent + '%');
577
578        },
579
580
581
582        updateCardsState() {
583
584            let currentAudio = this.audio.currentSrc;
585
586
587            // Reset slider
588            $('.play-button-mask').addClass('pause');
589
590
591            // Reset cartes podcasts
592            $('.audio').removeClass('pause');
593
594
595            $('.carousel-item, .audio').each(function () {
596
597                let audio = $(this).data('audio');
598
599
600                if (audio && currentAudio.includes(audio)) {
601
602
603                    // Slider
604                    $(this)
605                        .closest('.carousel-item')
606                        .find('.play-button-mask')
607                        .removeClass('pause');
608
609
610                    // Grilles podcasts
611                    $(this)
612                        .addClass('pause');
613
614
615                }
616
617            });
618
619        },
620
621        showPlayer() {
622
623            if (window.innerWidth > 768) {
624                return;
625            }
626
627            $('#header-player')
628                .css({
629                    top: 'calc(100dvh - ' + $('#header-player').outerHeight() + 'px',
630                })
631                .addClass('mobile-open');
632
633            $('.toggle-mobile').html(`
634                    <svg width="16" height="16" viewBox="0 0 16 16">
635                        <polyline
636                            points="2,5 8,11 14,5"
637                            fill="none"
638                            stroke="#000"
639                            stroke-width="2"
640                        />
641                    </svg>
642                `);
643
644        },
645
646        hidePlayer() {
647
648            if (window.innerWidth > 768) {
649                return;
650            }
651
652            $('#header-player')
653                .css({
654                    top: '100dvh',
655                })
656                .removeClass('mobile-open');
657
658            $('.toggle-mobile').html(`
659                    <svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="16" height="16" x="0px" y="0px" viewBox="0 0 17 17" enable-background="new 0 0 17 17" xml:space="preserve" class="audioBar">
660                            <rect x="0" width="2" height="16" transform="translate(0)">
661                                <animate attributeName="height" attributeType="XML" dur="1s" values="2;16;
6612" repeatCount="indefinite"></animate>
662                            </rect>
663                            <rect x="5" width="2" height="16" transform="translate(0)">
664                                <animate attributeName="height" attributeType="XML" dur="1s" values="2;16;2" repeatCount="indefinite" begin="0.3s"></animate>
665                            </rect>
666                            <rect x="10" width="2" height="16" transform="translate(0)">
667                                <animate attributeName="height" attributeType="XML" dur="1s" values="2;16;2" repeatCount="indefinite" begin="0.5s"></animate>
668                            </rect>
669                            <rect x="15" width="2" height="16" transform="translate(0)">
670                                <animate attributeName="height" attributeType="XML" dur="1s" values="2;16;2" repeatCount="indefinite" begin="0.3s"></animate>
671                            </rect>
672                        </svg>
673                `);
674
675        },
676
677
678
679
680    };
681
682
683    $(function () {
684
685        RGPlayer.init();
686
687    });
688
689})(jQuery);

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.