PageSourceSearch

https://monticello.media/wp-content/angie-snippets/prod/snippet-23608/script.js?m=1785289999

js monticello.media collected 2026-10-10 01:01:55 UTC 5,471 bytes, 149 lines download raw bytes

1class AudioStreamHandler_bf1e7435 extends elementorModules.frontend.handlers.Base {
2    getDefaultSettings() {
3        return {
4            selectors: {
5                playBtn: '.as-bf1e7435-play-btn',
6                playIcon: '.as-bf1e7435-play-icon',
7                pauseIcon: '.as-bf1e7435-pause-icon',
8                volumeInput: '.as-bf1e7435-volume-input',
9                trackTitle: '.as-bf1e7435-track-title',
10                artistName: '.as-bf1e7435-artist-name',
11                albumName: '.as-bf1e7435-album-name',
12                albumArt: '.as-bf1e7435-album-art'
13            }
14        };
15    }
16
17    getDefaultElements() {
18        const selectors = this.getSettings('selectors');
19        return {
20            $playBtn: this.$element.find(selectors.playBtn),
21            $playIcon: this.$element.find(selectors.playIcon),
22            $pauseIcon: this.$element.find(selectors.pauseIcon),
23            $volumeInput: this.$element.find(selectors.volumeInput),
24            $trackTitle: this.$element.find(selectors.trackTitle),
25            $artistName: this.$element.find(selectors.artistName),
26            $albumName: this.$element.find(selectors.albumName),
27            $albumArt: this.$element.find(selectors.albumArt)
28        };
29    }
30
31    bindEvents() {
32        this.streamUrl = this.$element.find('.as-bf1e7435-player').data('stream-url');
33        this.xmlUrl = this.$element.find('.as-bf1e7435-player').data('xml-url');
34        this.interval = parseInt(this.$element.find('.as-bf1e7435-player').data('interval'), 10) * 1000 || 15000;
35        this.ajaxUrl = this.$element.find('.as-bf1e7435-player').data('ajax-url');
36        this.nonce = this.$element.find('.as-bf1e7435-player').data('nonce');
37
38        this.audio = null;
39        this.isPlaying = false;
40        this.metaTimer = null;
41
42        this.elements.$playBtn.on('click', this.togglePlayback.bind(this));
43        this.elements.$volumeInput.on('input', this.handleVolumeChange.bind(this));
44
45        // Start pulling metadata immediately if an XML URL is defined
46        if (this.xmlUrl) {
47            this.fetchMetadata();
48            this.metaTimer = setInterval(this.fetchMetadata.bind(this), this.interval);
49        } else {
50            this.elements.$trackTitle.text('Live Broadcast');
51            this.elements.$artistName.text('Ready to Play');
52        }
53    }
54
55    initAudio() {
56        if (!this.audio) {
57            this.audio = new Audio(this.streamUrl);
58            this.audio.volume = parseFloat(this.elements.$volumeInput.val());
59        }
60    }
61
62    togglePlayback() {
63        this.initAudio();
64
65        if (this.isPlaying) {
66            this.audio.pause();
67            // Force stream reload upon re-play to stay live and free up browser memory
68            this.audio.src = '';
69            this.audio.load();
70            this.audio = null;
71            
72            this.elements.$playIcon.show();
73            this.elements.$pauseIcon.hide();
74            this.isPlaying = false;
75        } else {
76            this.initAudio();
77            this.audio.src = this.streamUrl;
78            this.audio.play().catch(err => console.error("Audio stream playback failed:", err));
79            
80            this.elements.$playIcon.hide();
81            this.elements.$pauseIcon.show();
82            this.isPlaying = true;
83        }
84    }
85
86    handleVolumeChange(e) {
87        const vol = parseFloat(e.target.value);
88        if (this.audio) {
89            this.audio.volume = vol;
90        }
91    }
92
93    fetchMetadata() {
94        if (!this.xmlUrl || !this.ajaxUrl) return;
95
96        jQuery.ajax({
97            url: this.ajaxUrl,
98            type: 'GET',
99            data: {
100                action: 'audio_stream_get_meta_bf1e7435',
101                xml_url: this.xmlUrl,
102                nonce: this.nonce
103            },
104            success: (response) => {
105                if (response.success && response.data) {
106                    const data = response.data;
107                    this.elements.$trackTitle.text(data.title || 'Live Stream');
108                    this.elements.$artistName.text(data.artist || 'Radio Broadcast');
109                    
110                    if (data.album) {
111                        this.elements.$albumName.text(data.album).show();
112                    } else {
113                        this.elements.$albumName.hide();
114                    }
115
116                    // Dynamically update Cover Art / Fallback
117                    if (data.cover) {
118                        this.elements.$albumArt.attr('src', data.cover);
119                    } else {
120                        const fallback = this.elements.$albumArt.data('fallback-logo');
121                        if (fallback) {
122                            this.elements.$albumArt.attr('src', fallback);
123                        }
124                    }
125                }
126            },
127            error: () => {
128                console.log('Failed to pull custom stream metadata');
129            }
130        });
131    }
132
133    onDestroy() {
134        if (this.audio) {
135            this.audio.pause();
136            this.audio = null;
137        }
138        if (this.metaTimer) {
139            clearInterval(this.metaTimer);
140        }
141    }
142}
143
144jQuery(window).on('elementor/frontend/init', () => {
145    const addHandler = ($element) => {
146        elementorFrontend.elementsHandler.addHandler(AudioStreamHandler_bf1e7435, { $element });
147    };
148    elementorFrontend.hooks.addAction('frontend/element_ready/audio_stream_bf1e7435.default', addHandler);
149});

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.